diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..8228ba34a --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Text Editor TMP Files +*.swp +*.blend1 +*.blend2 +*.blend3 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..8086a2f44 --- /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 +eliasfleckenstein@web.de. +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 1b5098a4f..5cbd6bcfc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,105 +1,410 @@ -# Contributing to MineClone 2 -So you want to contribute 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 Nicu and Fleckenstein. If you have any +problems or questions, contact us (See Links section below). -MineClone 2's development target is to make a free software clone of Minecraft, -***version 1.12***, ***PC edition***, *** + Optifine features supported by the Minetest Engine ***. +You can help with MineClone2's development in many different ways, +whether you're a programmer or not. -MineClone 2 is maintained by three persons. Namely, kay27, EliasFleckenstein and jordan4ibanez. You can find us -in the Minetest forums (forums.minetest.net), in IRC in the #mineclone2 -channel on irc.freenode.net. And finally, you can send e-mails to - or . +## MineClone2's development target is to... +- Crucially, create a stable, moddable, free/libre clone of Minecraft +based on the Minetest engine with polished features, usable in both +singleplayer and multiplayer. Currently, most of **Minecraft Java +Edition 1.12.2** features are already implemented and polishing existing +features are prioritized over new feature requests. +- With lessened priority yet strictly, implement features targetting +**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported +by the Minetest Engine). This means features in parity with the listed +Minecraft experiences are prioritized over those that don't fulfill this +scope. +- Optionally, create a performant experience that will run relatively +well on really low spec computers. Unfortunately, due to Minecraft's +mechanisms and Minetest engine's limitations along with a very small +playerbase on low spec computers, optimizations are hard to investigate. -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. +## 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) -## 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: +## 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. -For small and medium changes: +## How you can help as a non-programmer -* Fork the repository +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. + +### 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" +). +* Please write in plain, understandable English. It will be easier to +communicate. +* Please start the issue title with a capital letter. +* Always check the currently opened issues before creating a new one. +Don't report bugs that have already been reported or request features +that already have been requested. +* 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. + +### 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. +* 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 might +not work, so it's not very useful to try them out yet. + +### Contributing assets +Due to license problems, MineClone2 unfortunately 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 use the Pixel Perfection texture pack. This is mostly +enough; however in some cases - e.g. for newer Minecraft features, it's +useful to have texture artists around. 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. + +#### 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 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 +Minetest 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 * Create a pull request to get your changes merged into master +* Keep your pull request up to date by regularly merging upstream. It is +imperative that conflicts are resolved prior to merging the pull +request. +* After the pull request got merged, you can delete the branch -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. -If your code causes bugs and crashes, it is your responsibility to fix them as soon as possible. +### Changing Gameplay +Pull Requests that change gameplay have to be properly researched and +need to state their sources. These PRs also need Fleckenstein's approval +before they are merged. +You can use these sources: -We mostly use plain merging rather than rebasing or squash merging. +* 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) -Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue. +### Stick to our guidelines -Contributors will be credited in `CREDITS.md`. +#### Git Guidelines +* We use merge rather than rebase or squash merge +* We don't use git submodules. +* Your commit names should be relatively descriptive, e.g. when saying +"Fix #issueid", the commit message should also contain the title of the +issue. +* Try to keep your commits as atomic as possible (advise, but completely +optional) -## Code Style +#### 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. -Each mod must provide `mod.conf`. -Each mod which add API functions should store functions inside a global table named like the mod. -Public functions should not use self references but rather just access the table directly. -Functions should be defined in this way: -``` -function mcl_xyz.stuff(param) end -``` -Insteed of this way: -``` -mcl_xyz.stuff = function(param) end -``` -Indentation must be unified, more likely with tabs. +```lua +mcl_example = {} + +function mcl_example.do_something() + -- ... +end -Time sensitive mods should make a local copy of most used API functions to improve performances. -``` -local vector = vector -local get_node = minetest.get_node ``` +* Public functions should not use self references but rather just access +the table directly, e.g. -## Features > 1.12 +```lua +-- bad +function mcl_example:do_something() +end -If you want to make a feature that was added in a Minecraft version later than 1.12, you should fork MineClone5 (mineclone5 branch in the repository) and add your changes to this. +-- good +function mcl_example.do_something() +end +``` -## What we accept +* Use modern Minetest API, e.g. no usage of `minetest.env` +* Tabs should be used for indent, spaces for alignment, e.g. -* Every MC features up to version 1.12 JE. -* Every already finished and working good features from versions above (only when making a MineClone5 PR / Contribution). -* Except features which couldn't be done easily and bugfree because of Minetest engine limitations. Eg. we CAN extend world boundaries by playing with map chunks, just teleporting player onto next layer after 31000 , but it would cost too much (time, code, bugs, performance, stability, etc). -* Some features, approved by the rest of the community, I mean maybe some voting and really missing any negative feedback. +```lua -## What we reject +-- use tabs for indent -* Any features which cause critical bugs, sending them to rework/fix or trying to fix immediately. -* Some small portions of big entirely missing features which just definitely break gamplay balance give nothing useful -* Controversial features, which some people support while others do not should be discussed well, with publishing forum announcements, at least during the week. In case if there are still doubts - send them into the mod. +for i = 1, 10 do + if i % 3 == 0 then + print(i) + end +end -## Reporting bugs -Report all bugs and missing Minecraft features here: +-- use tabs for indent and spaces to align things - +some_table = { + {"a string", 5}, + {"a very much longer string", 10}, +} +``` -## Direct discussion -We have an IRC channel! Join us on #mineclone2 in freenode.net. +* 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 -## Creating releases +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. + +#### Developer responsibilities +- You should not push things directly to +MineClone2 master - rather, do your work on a branch on your private +repository, then create a pull request. This way other people can review +your changes and make sure they work before they get merged. +- Merge PRs only when they have recieved the necessary feedback and have +been tested by at least two different people (including the author of +the pull request), to avoid crashes or the introduction of new bugs. +- You may also be assigned to issues or pull +requests as a developer. In this case it is your responsibility to fix +the issue / review and merge the pull request when it is ready. You can +also unassign yourself from the issue / PR if you have no time or don't +want to take care of it for some other reason. After all, everyone is a +volunteer and we can't expect you to do work that you are not interested +in. **The important thing is that you make sure to inform us if you +won't take care of something that has been assigned to you.** +- Please assign yourself to something that you want to work on to avoid +duplicate work. +- As a developer, it should be easy to reach you about your work. You +should be in at least one of the public MineClone2 discussion rooms - +preferrably Discord, but if you really don't like Discord, Matrix +or IRC are fine too. + +### Maintainer status +Maintainers carry the main responsibility for the project. + +#### Maintainer responsibilities +- Making sure issues are addressed and pull requests are reviewed and +merged, by assigning either themselves or Developers to issues / PRs +- Making releases +- Making sure guidelines are kept +- 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 +* Fleckenstein - responsible for gameplay review, publishing releases, +technical guidelines and issue/PR delegation +* 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 index 296e7c23b..c1174e797 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -6,9 +6,13 @@ ## Creator of MineClone2 * Wuzzy + ## Maintainers +* Nicu +* cora + +## Previous Maintainers * Fleckenstein -* kay27 * jordan4ibanez ## Developers @@ -19,10 +23,10 @@ * iliekprogrammar * MysticTempest * Rootyjr -* Nicu * aligator * Code-Sploit * NO11 +* kabou ## Contributors * Laurent Rocher @@ -48,8 +52,25 @@ * dBeans * nickolas360 * yutyo -* ztianyang +* Tianyang Zhang * j45 +* Marcin Serwin +* erlehmann +* E +* Benjamin Schötz +* Doloment +* Sydney Gems +* talamh +* Emily2255 +* Emojigit +* FinishedFragment +* sfan5 +* Blue Blancmange +* Jared Moody +* SmallJoker +* Sven792 +* aldum +* Dieter44 ## MineClone5 * kay27 @@ -57,6 +78,16 @@ * epCode * NO11 * j45 +* 3raven +* PrarieWind +* Gustavo1 +* CableGuy67 + +## Mineclonia +* erlehmann +* Li0n +* E +* n_to ## Original Mod Authors * Wuzzy @@ -74,7 +105,6 @@ * Rochambeau * rubenwardy * stu -* jordan4ibanez * 4aiman * Kahrl * Krock @@ -103,6 +133,7 @@ * xMrVizzy * yutyo * NO11 +* kay27 ## Translations * Wuzzy @@ -110,6 +141,11 @@ * wuniversales * kay27 * pitchum +* todoporlalibertad +* Marcin Serwin + +## Funders +* 40W ## Special thanks * celeron55 for creating Minetest diff --git a/GROUPS.md b/GROUPS.md index 8c0c3563e..b2c009b47 100644 --- a/GROUPS.md +++ b/GROUPS.md @@ -56,6 +56,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 +72,7 @@ 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 #### Footnotes @@ -149,7 +151,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 diff --git a/README.md b/README.md index ca4d01959..555a2f490 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ -# (Currently in feature freeze) - -# 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.72.0 (in development) +Version: 0.74 (in development) ### Gameplay You start in a randomly-generated world made entirely of cubes. You can explore @@ -68,39 +66,43 @@ Use the `/giveme` chat command to obtain them. See the in-game help for an explanation. ## Installation -This game requires [Minetest](http://minetest.net) to run (version 5.3.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. -## Reporting bugs -Please report all bugs and missing Minecraft features here: +## Useful links +The MineClone2 repository is hosted at Mesehub. To contribute or report issues, head there. - +* Mesehub: +* Discord: +* YouTube +* IRC: +* Matrix: +* Reddit: +* Minetest forums: +* ContentDB: +* OpenCollective: -## Chating with the community -Join our discord server at: - - - -## Project description -The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software. - -* **Target of development: Minecraft, PC Edition, version 1.12** (later known as “Java Edition”) -* MineClone2 also includes Optifine features supported by the Minetest -* In general, Minecraft is aimed to be cloned as good as possible -* Cloning the gameplay has highest priority -* MineClone 2 will use different assets, but with a similar style -* Limitations found in Minetest will be documented in the course of development -* Features of later Minecraft versions are collected in the mineclone5 branch - -## Using features from newer versions of Minecraft -For > 1.12 features, checkout MineClone5. It includes features from newer Minecraft versions. -Download it here: https://git.minetest.land/MineClone2/MineClone2/src/branch/mineclone5 +## Target +- Crucially, create a stable, moddable, free/libre clone of Minecraft +based on the Minetest engine with polished features, usable in both +singleplayer and multiplayer. Currently, most of **Minecraft Java +Edition 1.12.2** features are already implemented and polishing existing +features are prioritized over new feature requests. +- With lessened priority yet strictly, implement features targetting +**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported +by the Minetest Engine). This means features in parity with the listed +Minecraft experiences are prioritized over those that don't fulfill this +scope. +- Optionally, create a performant experience that will run relatively +well on really low spec computers. Unfortunately, due to Minecraft's +mechanisms and Minetest engine's limitations along with a very small +playerbase on low spec computers, optimizations are hard to investigate. ## Completion status This game is currently in **beta** stage. @@ -187,7 +189,7 @@ Technical differences from Minecraft: * Different engine (Minetest) * Different easter eggs -… and finally, MineClone 2 is free software (“free” as in “freedom”)! +… and finally, MineClone2 is free software (“free” as in “freedom”)! ## Other readme files 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/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/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/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 76c68122b..e04fb2eac 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -83,7 +83,7 @@ local function get_hardness_values_for_groups() for _, ndef in pairs(minetest.registered_nodes) do for g, _ in pairs(mcl_autogroup.registered_diggroups) do - if ndef.groups[g] ~= nil then + if ndef.groups[g] then maps[g][ndef._mcl_hardness or 0] = true end end @@ -207,6 +207,10 @@ end function mcl_autogroup.can_harvest(nodename, toolname) 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 diff --git a/mods/CORE/controls/init.lua b/mods/CORE/controls/init.lua index 2ceb7e902..ef57281a4 100644 --- a/mods/CORE/controls/init.lua +++ b/mods/CORE/controls/init.lua @@ -1,6 +1,8 @@ local get_connected_players = minetest.get_connected_players local clock = os.clock +local pairs = pairs + controls = {} controls.players = {} @@ -20,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) @@ -49,27 +51,27 @@ minetest.register_globalstep(function(dtime) 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, 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 - end - end end end) diff --git a/mods/CORE/mcl_attached/init.lua b/mods/CORE/mcl_attached/init.lua index 4f538e104..c4a7a3337 100644 --- a/mods/CORE/mcl_attached/init.lua +++ b/mods/CORE/mcl_attached/init.lua @@ -1,29 +1,93 @@ +-- 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 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. +-- +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.new(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 + core.sound_play(def.sounds.fall, {pos = p}, true) + end + remove_node(p) + for _, item in pairs(drops) do + local pos = { + x = p.x + math.random()/2 - 0.25, + y = p.y + math.random()/2 - 0.25, + z = p.z + 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 function minetest.check_single_for_falling(pos) - local ret_o = original_function(pos) - local ret = false - local node = minetest.get_node(pos) + if original_function(pos) then + return true + end + + 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 if get_item_group(get_node(vector.add(pos, dir)).name, "solid") == 0 then - 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 + drop_attached_node(pos) + return true end end end - return ret_o or ret + + 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_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_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index 3a60f2f37..0132d1669 100644 --- a/mods/CORE/mcl_explosions/init.lua +++ b/mods/CORE/mcl_explosions/init.lua @@ -12,9 +12,13 @@ under the LGPLv2.1 license. mcl_explosions = {} -local mod_fire = minetest.get_modpath("mcl_fire") ~= nil +local mod_fire = minetest.get_modpath("mcl_fire") --local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire") +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 @@ -24,6 +28,7 @@ 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 = {} @@ -240,7 +245,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc local ent = obj:get_luaentity() -- Ignore items to lower lag - if (obj:is_player() or (ent and ent.name ~= '__builtin.item')) and obj:get_hp() > 0 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 @@ -356,9 +361,9 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc local on_blast = node_on_blast[data[idx]] local remove = true - if do_drop or on_blast ~= nil then + if do_drop or on_blast then local npos = get_position_from_hash(hash) - if on_blast ~= nil then + if on_blast then on_blast(npos, 1.0, do_drop) remove = false else @@ -400,8 +405,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc 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. 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.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_init/init.lua b/mods/CORE/mcl_init/init.lua index 066e555df..fec9c7ba9 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -32,9 +32,9 @@ 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) 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 diff --git a/mods/CORE/mcl_loot/init.lua b/mods/CORE/mcl_loot/init.lua index 1b2c50807..b90cd4428 100644 --- a/mods/CORE/mcl_loot/init.lua +++ b/mods/CORE/mcl_loot/init.lua @@ -58,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 diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_bonemeal.png b/mods/CORE/mcl_particles/textures/mcl_particles_bonemeal.png new file mode 100644 index 000000000..684df9865 Binary files /dev/null and b/mods/CORE/mcl_particles/textures/mcl_particles_bonemeal.png differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_totem1.png b/mods/CORE/mcl_particles/textures/mcl_particles_totem1.png new file mode 100644 index 000000000..15fe082e1 Binary files /dev/null and b/mods/CORE/mcl_particles/textures/mcl_particles_totem1.png differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_totem2.png b/mods/CORE/mcl_particles/textures/mcl_particles_totem2.png new file mode 100644 index 000000000..2ab88983d Binary files /dev/null and b/mods/CORE/mcl_particles/textures/mcl_particles_totem2.png differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_totem3.png b/mods/CORE/mcl_particles/textures/mcl_particles_totem3.png new file mode 100644 index 000000000..55d6f49d3 Binary files /dev/null and b/mods/CORE/mcl_particles/textures/mcl_particles_totem3.png differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_totem4.png b/mods/CORE/mcl_particles/textures/mcl_particles_totem4.png new file mode 100644 index 000000000..d6e6502b7 Binary files /dev/null and b/mods/CORE/mcl_particles/textures/mcl_particles_totem4.png differ diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index a7504af08..0d1cb45dc 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -1,5 +1,27 @@ 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 + -- Based on minetest.rotate_and_place --[[ @@ -335,6 +357,32 @@ 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) @@ -456,7 +504,9 @@ function mcl_util.calculate_durability(itemstack) end end end - uses = uses or (next(itemstack:get_tool_capabilities().groupcaps) or {}).uses + + local _, groupcap = next(itemstack:get_tool_capabilities().groupcaps) + uses = uses or (groupcap or {}).uses end return uses or 0 @@ -538,3 +588,25 @@ function mcl_util.get_object_name(object) return luaentity.nametag and luaentity.nametag ~= "" and luaentity.nametag or luaentity.description or luaentity.name end end + +function mcl_util.replace_mob(obj, mob) + local rot = obj:get_yaw() + local pos = obj:get_pos() + obj:remove() + obj = minetest.add_entity(pos, mob) + 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 diff --git a/mods/CORE/mcl_worlds/API.md b/mods/CORE/mcl_worlds/API.md index dd96b01b5..69508e924 100644 --- a/mods/CORE/mcl_worlds/API.md +++ b/mods/CORE/mcl_worlds/API.md @@ -12,7 +12,7 @@ Params: * pos: position -## mcl_worlds.y_to_layer(y) +## 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: @@ -78,4 +78,4 @@ Table containing all function registered with mcl_worlds.register_on_dimension_c Notify this mod of a dimension change of to * player: player, player who changed the dimension -* dimension: string, new dimension ("overworld", "nether", "end", "void") \ No newline at end of file +* dimension: string, new dimension ("overworld", "nether", "end", "void") diff --git a/mods/CORE/mcl_worlds/init.lua b/mods/CORE/mcl_worlds/init.lua index ec8144794..4f8914506 100644 --- a/mods/CORE/mcl_worlds/init.lua +++ b/mods/CORE/mcl_worlds/init.lua @@ -1,5 +1,7 @@ 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 @@ -44,12 +46,16 @@ function mcl_worlds.y_to_layer(y) 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. @@ -119,6 +125,8 @@ function mcl_worlds.dimension_change(player, dimension) last_dimension[playername] = dimension end +local dimension_change = mcl_worlds.dimension_change + ----------------------- INTERNAL STUFF ---------------------- -- Update the dimension callbacks every DIM_UPDATE seconds @@ -126,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/tga_encoder/init.lua b/mods/CORE/tga_encoder/init.lua index 96afda5e1..24ec502e1 100644 --- a/mods/CORE/tga_encoder/init.lua +++ b/mods/CORE/tga_encoder/init.lua @@ -38,18 +38,32 @@ function image:encode_header() self.data = self.data .. string.char(0) -- image id .. string.char(0) -- color map type - .. string.char(2) -- image type (uncompressed true-color image = 2) + .. 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 - self.data = self.data - .. string.char(pixel[3], pixel[2], pixel[1]) + 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() @@ -70,7 +84,7 @@ function image:encode() end function image:save(filename) - local f = assert(io.open(filename, "w")) + local f = assert(io.open(filename, "wb")) f:write(self.data) f:close() end diff --git a/mods/CORE/walkover/init.lua b/mods/CORE/walkover/init.lua index 6260b43e0..eb9de4218 100644 --- a/mods/CORE/walkover/init.lua +++ b/mods/CORE/walkover/init.lua @@ -2,46 +2,45 @@ local get_connected_players = minetest.get_connected_players local get_node = minetest.get_node -local vector_add = vector.add +local vector = vector local ceil = math.ceil +local pairs = pairs walkover = {} -walkover.registered_globals = {} - -function walkover.register_global(func) - table.insert(walkover.registered_globals, func) -end local on_walk = {} local registered_globals = {} +walkover.registered_globals = registered_globals + +function walkover.register_global(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 - for _,func in ipairs(walkover.registered_globals) do --cache registered globals - table.insert(registered_globals, func) - end end) local timer = 0 minetest.register_globalstep(function(dtime) - timer = timer + dtime; + timer = timer + dtime if timer >= 0.3 then - for _,player in pairs(get_connected_players()) do - local pp = player:get_pos() - pp.y = ceil(pp.y) - local loc = vector_add(pp, {x=0,y=-1,z=0}) - if loc ~= nil then - local nodeiamon = get_node(loc) - if nodeiamon ~= nil then - if on_walk[nodeiamon.name] then - on_walk[nodeiamon.name](loc, nodeiamon, player) + for _, player in pairs(get_connected_players()) do + local ppos = player:get_pos() + ppos.y = ceil(ppos.y) + local npos = vector.add(ppos, vector.new(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](loc, nodeiamon, player) + registered_globals[i](npos, node, player) end end end diff --git a/mods/ENTITIES/drippingwater/init.lua b/mods/ENTITIES/drippingwater/init.lua deleted file mode 100644 index e17bdda40..000000000 --- a/mods/ENTITIES/drippingwater/init.lua +++ /dev/null @@ -1,114 +0,0 @@ ---Dripping Water Mod ---by kddekadenz - -local math = math - --- 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, -}) \ No newline at end of file diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index 8c187617c..72664b1df 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_boats") +local S = minetest.get_translator(minetest.get_current_modname()) local boat_visual_size = {x = 1, y = 1, z = 1} local paddling_speed = 22 @@ -84,7 +84,7 @@ local function attach_object(self, obj) end end, name) obj:set_look_horizontal(yaw) - mcl_tmp_message.message(obj, S("Sneak to dismount")) + mcl_title.set(obj, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60}) else obj:get_luaentity()._old_visual_size = visual_size end @@ -115,7 +115,7 @@ local boat = { 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"}, + textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"}, visual_size = boat_visual_size, hp_max = boat_max_hp, damage_texture_modifier = "^[colorize:white:0", @@ -148,6 +148,11 @@ function boat.on_activate(self, staticdata, dtime_s) self._v = data.v self._last_v = self._v self._itemstring = data.itemstring + + while #data.textures < 5 do + table.insert(data.textures, data.textures[1]) + end + self.object:set_properties({textures = data.textures}) end end @@ -262,7 +267,7 @@ function boat.on_step(self, dtime, moveresult) 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 @@ -271,7 +276,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 @@ -337,7 +342,8 @@ function boat.on_step(self, dtime, moveresult) 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_water(p) or is_obsidian_boat then -- Inside water: Slowly sink local y = self.object:get_velocity().y y = y - 0.01 @@ -377,13 +383,13 @@ 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 boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "boat_obsidian" } +local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat"), S("Obsidian 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" } + craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood", "mcl_core:obsidian" } end -local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak" } +local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak", "obsidian" } for b=1, #boat_ids do local itemstring = "mcl_boats:"..boat_ids[b] @@ -434,8 +440,9 @@ for b=1, #boat_ids do pos = vector.add(pos, vector.multiply(dir, boat_y_offset_ground)) end local boat = minetest.add_entity(pos, "mcl_boats:boat") + local texture = "mcl_boats_texture_"..images[b].."_boat.png" boat:get_luaentity()._itemstring = itemstring - boat:set_properties({textures = { "mcl_boats_texture_"..images[b].."_boat.png" }}) + boat:set_properties({textures = { texture, texture, texture, texture, texture }}) boat:set_yaw(placer:get_look_horizontal()) if not minetest.is_creative_enabled(placer:get_player_name()) then itemstack:take_item() @@ -470,6 +477,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.fr.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr index 04d6d9da9..785d50146 100644 --- a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr @@ -6,6 +6,7 @@ Boats are used to travel on the surface of water.=Les bateaux sont utilisés pou 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. +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 \ No newline at end of file +Water vehicle=Véhicule aquatique +Sneak to dismount= \ 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/mod.conf b/mods/ENTITIES/mcl_boats/mod.conf index a5d6cc8cb..61463b6ec 100644 --- a/mods/ENTITIES/mcl_boats/mod.conf +++ b/mods/ENTITIES/mcl_boats/mod.conf @@ -1,7 +1,7 @@ name = mcl_boats author = PilzAdam description = Adds drivable boats. -depends = mcl_player, flowlib +depends = mcl_player, flowlib, mcl_title optional_depends = mcl_core, doc_identifier diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_obsidian_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_obsidian_boat.png new file mode 100644 index 000000000..6ae10c0c4 Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_obsidian_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_obsidian_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_obsidian_boat.png new file mode 100644 index 000000000..af3c24b30 Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_obsidian_boat.png differ diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 4cb19cca1..885875aca 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -26,20 +26,64 @@ function mcl_burning.get_collisionbox(obj, smaller, storage) 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 = minetest.find_nodes_in_area(vector.add(pos, minp), vector.add(pos, maxp), nodenames) + 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 a creative player, this function does nothing. +-- function mcl_burning.set_on_fire(obj, burn_time) if obj:get_hp() < 0 then return end - local storage = mcl_burning.get_storage(obj) - local luaentity = obj:get_luaentity() if luaentity and luaentity.fire_resistant then return @@ -60,50 +104,32 @@ function mcl_burning.set_on_fire(obj, burn_time) 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 - if not storage.burn_time or burn_time >= storage.burn_time then - if obj:is_player() and not storage.fire_hud_id then - storage.fire_hud_id = obj:hud_add({ - hud_elem_type = "image", - position = {x = 0.5, y = 0.5}, - scale = {x = -100, y = -100}, - text = "mcl_burning_entity_flame_animated.png^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. 1, - z_index = 1000, - }) + 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 - storage.burn_time = burn_time - storage.fire_damage_timer = 0 + return + end + storage.burn_time = burn_time + storage.fire_damage_timer = 0 - local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") - local minp, maxp = mcl_burning.get_collisionbox(obj, false, storage) - local obj_size = obj:get_properties().visual_size + 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 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 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)) - 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}) - local fire_luaentity = fire_entity:get_luaentity() - fire_luaentity:update_frame(obj, storage) - - for _, other in pairs(minetest.get_objects_inside_radius(fire_entity:get_pos(), 0)) do - local other_luaentity = other:get_luaentity() - if other_luaentity and other_luaentity.name == "mcl_burning:fire" and other_luaentity ~= fire_luaentity then - other:remove() - break - end - end + if obj:is_player() then + mcl_burning.update_hud(obj) end end @@ -143,4 +169,4 @@ function mcl_burning.tick(obj, dtime, storage) end end end -end \ No newline at end of file +end diff --git a/mods/ENTITIES/mcl_burning/init.lua b/mods/ENTITIES/mcl_burning/init.lua index 5cf0d85fe..039d295b7 100644 --- a/mods/ENTITIES/mcl_burning/init.lua +++ b/mods/ENTITIES/mcl_burning/init.lua @@ -1,14 +1,29 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) mcl_burning = { - storage = {}, - 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 .. "/api.lua") +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 pairs(minetest.get_connected_players()) do + 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) @@ -16,12 +31,12 @@ minetest.register_globalstep(function(dtime) for _, pos in pairs(nodes) do local node = minetest.get_node(pos) - if minetest.get_item_group(node.name, "puts_out_fire") > 0 then + if get_item_group(node.name, "puts_out_fire") > 0 then burn_time = 0 break end - local value = minetest.get_item_group(node.name, "set_on_fire") + local value = get_item_group(node.name, "set_on_fire") if value > burn_time then burn_time = value end @@ -39,75 +54,78 @@ minetest.register_on_respawnplayer(function(player) end) minetest.register_on_joinplayer(function(player) - local storage - + local storage = {} local burn_data = player:get_meta():get_string("mcl_burning:data") - if burn_data == "" then - storage = {} - else - storage = minetest.deserialize(burn_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) -minetest.register_on_leaveplayer(function(player) +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) + 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 = "cube", + 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, }, - animation_frame = 0, - animation_timer = 0, + _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, storage = self:sanity_check() - - if parent then - self.animation_timer = self.animation_timer + dtime - if self.animation_timer >= 0.1 then - self.animation_timer = 0 - self.animation_frame = self.animation_frame + 1 - if self.animation_frame > mcl_burning.animation_frames - 1 then - self.animation_frame = 0 - end - self:update_frame(parent, storage) - end - else - self.object:remove() - end - end, - sanity_check = function(self) 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 - - return parent, storage - end, - update_frame = function(self, parent, storage) - local frame_overlay = "^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. self.animation_frame - local fire_texture = "mcl_burning_entity_flame_animated.png" .. frame_overlay - self.object:set_properties({textures = {"blank.png", "blank.png", fire_texture, fire_texture, fire_texture, fire_texture}}) if parent:is_player() then - parent:hud_change(storage.fire_hud_id, "text", "mcl_burning_hud_flame_animated.png" .. frame_overlay) + 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_dripping/init.lua b/mods/ENTITIES/mcl_dripping/init.lua new file mode 100644 index 000000000..57ba7ecfe --- /dev/null +++ b/mods/ENTITIES/mcl_dripping/init.lua @@ -0,0 +1,66 @@ +-- Dripping Water Mod +-- by kddekadenz + +local math = math + +-- License of code, textures & sounds: CC0 + +local function register_drop(liquid, glow, sound, nodes) + minetest.register_entity("mcl_dripping:drop_" .. liquid, { + hp_max = 1, + physical = true, + collide_with_objects = false, + collisionbox = {-0.01, 0.01, -0.01, 0.01, 0.01, 0.01}, + glow = glow, + pointable = false, + visual = "sprite", + visual_size = {x = 0.1, y = 0.1}, + textures = {""}, + spritediv = {x = 1, y = 1}, + initial_sprite_basepos = {x = 0, y = 0}, + static_save = false, + _dropped = false, + on_activate = function(self) + self.object:set_properties({ + textures = {"[combine:2x2:" .. -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=default_" .. liquid .. "_source_animated.png"} + }) + 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(vector.new(0, -5, 0)) + end + if minetest.get_node(vector.offset(ownpos, 0, 0.5, 0)).name == "air" then + self.object:set_acceleration(vector.new(0, -5, 0)) + end + if minetest.get_node(vector.offset(ownpos, 0, -0.1, 0)).name ~= "air" then + local ent = self.object:get_luaentity() + if not ent._dropped then + ent._dropped = true + minetest.sound_play({name = "drippingwater_" .. sound .. "drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) + end + if k < 3 then + self.object:remove() + end + end + end, + }) + minetest.register_abm({ + label = "Create drops", + nodenames = nodes, + neighbors = {"group:" .. liquid}, + interval = 2, + chance = 22, + action = function(pos) + if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1, 0)).name, liquid) ~= 0 + and minetest.get_node(vector.offset(pos, 0, -1, 0)).name == "air" then + local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100 + minetest.add_entity(vector.offset(pos, x, -0.520, z), "mcl_dripping:drop_" .. liquid) + end + end, + }) +end + +register_drop("water", 1, "", {"group:opaque", "group:leaves"}) +register_drop("lava", math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), "lava", {"group:opaque"}) \ No newline at end of file diff --git a/mods/ENTITIES/drippingwater/mod.conf b/mods/ENTITIES/mcl_dripping/mod.conf similarity index 82% rename from mods/ENTITIES/drippingwater/mod.conf rename to mods/ENTITIES/mcl_dripping/mod.conf index 1de118f4c..921d5e59f 100644 --- a/mods/ENTITIES/drippingwater/mod.conf +++ b/mods/ENTITIES/mcl_dripping/mod.conf @@ -1,4 +1,4 @@ -name = drippingwater +name = mcl_dripping author = kddekadenz description = Drops are generated rarely under solid nodes depends = mcl_core diff --git a/mods/ENTITIES/drippingwater/readme.txt b/mods/ENTITIES/mcl_dripping/readme.txt similarity index 75% rename from mods/ENTITIES/drippingwater/readme.txt rename to mods/ENTITIES/mcl_dripping/readme.txt index f609163ed..afe35608e 100644 --- a/mods/ENTITIES/drippingwater/readme.txt +++ b/mods/ENTITIES/mcl_dripping/readme.txt @@ -1,12 +1,12 @@ -Dripping Water Mod +Dripping Mod by kddekadenz -modified for MineClone 2 by Wuzzy +modified for MineClone 2 by Wuzzy and NO11 Installing instructions: - 1. Copy the drippingwater mod folder into games/gamemode/mods + 1. Copy the mcl_dripping mod folder into games/gamemode/mods 2. Start game and enjoy :) 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_falling_nodes/init.lua b/mods/ENTITIES/mcl_falling_nodes/init.lua index 01681a159..d527603de 100644 --- a/mods/ENTITIES/mcl_falling_nodes/init.lua +++ b/mods/ENTITIES/mcl_falling_nodes/init.lua @@ -19,7 +19,10 @@ local function deal_falling_damage(self, dtime) end self._hit = self._hit or {} for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do - if mcl_util.get_hp(obj) > 0 and not self._hit[obj] then + 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 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.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_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index a73f586e9..e39e21bfb 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -1,5 +1,5 @@ --these are lua locals, used for higher performance -local minetest, math, vector, ipairs = minetest, math, vector, ipairs +local minetest, math, vector, ipairs, pairs = minetest, math, vector, ipairs, pairs --this is used for the player pool in the sound buffer local pool = {} @@ -110,7 +110,7 @@ minetest.register_globalstep(function(dtime) if tick == true and pool[name] > 0 then minetest.sound_play("item_drop_pickup", { pos = pos, - gain = 0.7, + gain = 0.3, max_hear_distance = 16, pitch = math.random(70,110)/100 }) @@ -233,7 +233,7 @@ function minetest.handle_node_drops(pos, drops, digger) local dug_node = minetest.get_node(pos) local tooldef local tool - if digger ~= nil then + if digger then tool = digger:get_wielded_item() tooldef = minetest.registered_tools[tool:get_name()] @@ -256,6 +256,8 @@ function minetest.handle_node_drops(pos, drops, digger) local silk_touch_drop = false local nodedef = minetest.registered_nodes[dug_node.name] + 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 } @@ -290,10 +292,10 @@ function minetest.handle_node_drops(pos, drops, digger) end end - if digger and mcl_experience.throw_experience and not silk_touch_drop then + 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 @@ -314,7 +316,7 @@ 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 + if obj then local x = math.random(1, 5) if math.random(1,2) == 1 then x = -x @@ -363,6 +365,17 @@ 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 + minetest.register_entity(":__builtin:item", { initial_properties = { hp_max = 1, @@ -383,7 +396,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, @@ -469,7 +482,7 @@ minetest.register_entity(":__builtin:item", { end, get_staticdata = function(self) - return minetest.serialize({ + local data = minetest.serialize({ itemstring = self.itemstring, always_collect = self.always_collect, age = self.age, @@ -477,6 +490,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) @@ -564,7 +610,7 @@ 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 @@ -574,7 +620,7 @@ minetest.register_entity(":__builtin:item", { 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 @@ -631,6 +677,18 @@ minetest.register_entity(":__builtin:item", { 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 + self._removed = true + self.object:remove() + return + end + end + 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 @@ -642,16 +700,6 @@ minetest.register_entity(":__builtin:item", { -- 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") diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 6fd98f550..d894f9722 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -1,9 +1,10 @@ -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 @@ -197,14 +198,27 @@ 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 + -- 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 + if g ~= self._railtype and self._railtype then -- Detach driver if player then if self._old_pos then @@ -418,7 +432,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 @@ -523,7 +538,7 @@ function mcl_minecarts.place_minecart(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) @@ -606,7 +621,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 @@ -645,7 +660,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_tmp_message.message(clicker, S("Sneak to dismount")) + mcl_title.set(clicker, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60}) end end, name) end @@ -846,4 +861,4 @@ if has_mcl_wip then mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart") mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart") mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart") -end \ No newline at end of file +end diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr index 39cdfd013..67ed5eb1b 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr @@ -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= \ No newline at end of file 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/mod.conf b/mods/ENTITIES/mcl_minecarts/mod.conf index 9fff9175d..3b8ae5551 100644 --- a/mods/ENTITIES/mcl_minecarts/mod.conf +++ b/mods/ENTITIES/mcl_minecarts/mod.conf @@ -1,6 +1,6 @@ name = mcl_minecarts author = Krock description = Minecarts are vehicles to move players quickly on rails. -depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons +depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons optional_depends = doc_identifier, mcl_wip diff --git a/mods/ENTITIES/mcl_minecarts/rails.lua b/mods/ENTITIES/mcl_minecarts/rails.lua index 53ec86d94..91282f253 100644 --- a/mods/ENTITIES/mcl_minecarts/rails.lua +++ b/mods/ENTITIES/mcl_minecarts/rails.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_minecarts") +local S = minetest.get_translator(minetest.get_current_modname()) -- Template rail function local function register_rail(itemstring, tiles, def_extras, creative) @@ -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_mobs/api/mob_functions/backup_code_api.txt b/mods/ENTITIES/mcl_mobs/api.lua similarity index 55% rename from mods/ENTITIES/mcl_mobs/api/mob_functions/backup_code_api.txt rename to mods/ENTITIES/mcl_mobs/api.lua index 48233d0b4..ea9235391 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/backup_code_api.txt +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -1,7 +1,119 @@ -local math = math -local vector = vector -local function disable_physics(object, luaentity, ignore_check, reset_movement) +-- 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 + +-- Localize +local S = minetest.get_translator("mcl_mobs") + +-- CMI support check +local use_cmi = minetest.global_exists("cmi") + + +-- Invisibility mod check +mobs.invis = {} +if minetest.global_exists("invisibility") then + mobs.invis = invisibility +end + + +-- 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 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) + +-- Peaceful mode message so players will know there are no monsters +if minetest.settings:get_bool("only_peaceful_mobs", false) then + minetest.register_on_joinplayer(function(player) + minetest.chat_send_player(player:get_player_name(), + S("Peaceful mode active! No monsters will spawn.")) + end) +end + +-- 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({ @@ -14,912 +126,630 @@ local function disable_physics(object, luaentity, ignore_check, reset_movement) end end -----For Water Flowing: -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=-9.81,z=0}) + +-- 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 ---[[ -local timer = 0 -minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer < 1 then return end - for _, player in pairs(minetest.get_connected_players()) do - local pos = player:get_pos() - for _, obj in pairs(minetest_get_objects_inside_radius(pos, 47)) do - local lua = obj:get_luaentity() - if lua and lua._cmi_is_mob then - lua.lifetimer = math.max(20, lua.lifetimer) - lua.despawn_immediately = false - 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 + 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 - timer = 0 -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 - }) + local p1, p2 = self.object:get_pos(), object:get_pos() + return p1 and p2 and (vector.distance(p1, p2) <= dist) end --- Spawn a child -function mobs:spawn_child(pos, mob_type) - local child = minetest_add_entity(pos, mob_type) - if not child then +-- attack player/mob +local do_attack = function(self, player) + + if self.state == "attack" or self.state == "die" then return end - local ent = child:get_luaentity() - effect(pos, 15, "mcl_particles_smoke.png", 1, 2, 2, 15, 5) + self.attack = player + self.state = "attack" - ent.child = true + -- TODO: Implement war_cry sound without being annoying + --if random(0, 100) < 90 then + --mob_sound(self, "war_cry", true) + --end +end - local textures - -- using specific child texture (if found) - if ent.child_texture then - textures = ent.child_texture[1] + +-- 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 pairs(minetest.get_objects_inside_radius(pos, width)) do + + local ent = object:get_luaentity() + if object:is_player() or (ent and ent._cmi_is_mob 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 - -- 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({x,z}) +end - return child +-- 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 --- feeding, taming and breeding (thanks blert2112) -function mobs:feed_tame(self, clicker, feed_count, breed, tame) - if not self.follow then - return false +-- 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 - -- can eat/tame with item in hand - if follow_holding(self, clicker) then + return 0 +end - -- if not in creative then take item - if not mobs.is_creative(clicker:get_player_name()) then +local function update_roll(self) + local is_Fleckenstein = self.nametag == "Fleckenstein" + local was_Fleckenstein = false - local item = clicker:get_wielded_item() + local rot = self.object:get_rotation() + rot.z = is_Fleckenstein and pi or 0 + self.object:set_rotation(rot) - item:take_item() + local cbox = table.copy(self.collisionbox) + local acbox = self.object:get_properties().collisionbox - clicker:set_wielded_item(item) + 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] + end + + self.object:set_properties({collisionbox = cbox}) +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) + update_roll(self) + return yaw + end - mob_sound(self, "eat", nil, true) + self.target_yaw = yaw + self.delay = delay - -- increase health - self.health = self.health + 4 + return self.target_yaw +end - if self.health >= self.hp_max then +-- global function to set mob yaw +function mobs:yaw(self, yaw, delay, dtime) + set_yaw(self, yaw, delay, dtime) +end - self.health = self.hp_max - - if self.htimer < 1 then - self.htimer = 5 - 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 - self.object:set_hp(self.health) +-- 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 - update_tag(self) + self.animation.current = self.animation.current or "" - -- make children grow quicker - if self.child == true then + if (anim == self.animation.current + or not self.animation[anim .. "_start"] + or not self.animation[anim .. "_end"]) and self.state ~= "die" then + return + end - -- deduct 10% of the time to adulthood - self.hornytimer = self.hornytimer + ((CHILD_GROW_TIME - self.hornytimer) * 0.1) + 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] and minetest.registered_nodes[nn].damage_per_second and minetest.registered_nodes[nn].damage_per_second > 0 then + return true + end + return false +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 +-- 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 - if tame then - self.tamed = true +-- check line of sight (BrunoMine) +local line_of_sight = function(self, pos1, pos2, stepsize) - if not self.owner or self.owner == "" then - self.owner = clicker:get_player_name() - end - end + stepsize = stepsize or 1 - -- make sound when fed so many times - mob_sound(self, "random", true) + 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 - return true + -- 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 --- no damage to nodes explosion -function mobs:safe_boom(self, pos, strength) - minetest_sound_play(self.sounds and self.sounds.explode or "tnt_explode", { + +-- 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 = self.sounds and self.sounds.distance or 32 + max_hear_distance = 8, }, 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) - self.object:remove() - 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) - end +local update_tag = function(self) + local tag + if mobs_debug then + tag = "nametag = '"..tostring(self.nametag).."'\n".. + "state = '"..tostring(self.state).."'\n".. + "order = '"..tostring(self.order).."'\n".. + "attack = "..tostring(self.attack).."\n".. + "health = "..tostring(self.health).."\n".. + "breath = "..tostring(self.breath).."\n".. + "gotten = "..tostring(self.gotten).."\n".. + "tamed = "..tostring(self.tamed).."\n".. + "horny = "..tostring(self.horny).."\n".. + "hornytimer = "..tostring(self.hornytimer).."\n".. + "runaway_timer = "..tostring(self.runaway_timer).."\n".. + "following = "..tostring(self.following) else - mobs:safe_boom(self, pos, strength) + tag = self.nametag end + self.object:set_properties({ + nametag = tag, + }) + + update_roll(self) end --- falling and fall damage --- returns true if mob died -local falling = function(self, pos) +-- drop items +local item_drop = function(self, cooked, looting_level) - if self.fly and self.state ~= "die" then + -- 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 - 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 + local obj, item, num + local pos = self.object:get_pos() - -- floating in water (or falling) - local v = self.object:get_velocity() + self.drops = self.drops or {} -- nil check - if v.y > 0 then + for n = 1, #self.drops do + local dropdef = self.drops[n] + local chance = 1 / dropdef.chance + local looting_type = dropdef.looting - -- 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 - - if minetest_registered_nodes[node_ok(pos).name].groups.lava then - - if self.floats_on_lava == 1 then - - self.object:set_acceleration({ - x = 0, - y = -self.fall_speed / (max(1, v.y) ^ 2), - z = 0 - }) - end - 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 / (math.max(1, v.y) ^ 2), - z = 0 - }) - end - else - - end -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 "" + 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 - -- 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 * math_pi / 2) - self.rotate - - if lp.x > s.x then - yaw = yaw + math_pi + 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 - yaw = set_yaw(self, yaw, 4) - self.state = "runaway" - self.runaway_timer = 3 - self.following = nil - 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 - - --- 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 + if do_common_looting then + num = num + math.floor(math.random(0, looting_level) + 0.5) end - end + if num > 0 then + item = dropdef.name - -- follow that thing - if self.following then + -- cook items when true + if cooked then - local s = self.object:get_pos() - local p + local output = minetest.get_craft_result({ + method = "cooking", width = 1, items = {item}}) - 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) + math_pi / 2) - self.rotate - - if p.x > s.x then yaw = yaw + math_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") + if output and output.item and not output.item:is_empty() then + item = output.item:get_name() 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 + -- add item if it exists + for x = 1, num do + obj = minetest.add_item(pos, ItemStack(item .. " " .. 1)) + end - self.state = "flop" - self.object:set_acceleration({x = 0, y = DEFAULT_FALL_SPEED, z = 0}) + if obj and obj:get_luaentity() then - 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), + 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 - - 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 + + self.drops = {} 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 - - --- 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 - - --- 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 - - --- dogfight 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 - --- 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 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 = "" - 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() + 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 - 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 - - - - - - -- check if mob is dead or only hurt local check_for_death = function(self, cause, cmi_cause) @@ -946,7 +776,7 @@ local check_for_death = function(self, cause, cmi_cause) -- play damage sound if health was reduced and make mob flash red. if damaged then add_texture_mod(self, "^[colorize:red:130") - minetest_after(.2, function(self) + minetest.after(.2, function(self) if self and self.object then remove_texture_mod(self, "^[colorize:red:130") end @@ -989,8 +819,8 @@ local check_for_death = function(self, cause, cmi_cause) 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)) + if mod_experience and ((not self.child) or self.type ~= "animal") and (minetest.get_us_time() - self.xp_timestamp <= 5000000) then + mcl_experience.throw_xp(self.object:get_pos(), math.random(self.xp_min, self.xp_max)) end end end @@ -1055,7 +885,7 @@ local check_for_death = function(self, cause, cmi_cause) set_animation(self, "die") else local rot = self.object:get_rotation() - rot.z = math_pi/2 + rot.z = pi/2 self.object:set_rotation(rot) length = 1 + DEATH_DELAY set_animation(self, "stand", true) @@ -1082,366 +912,34 @@ local check_for_death = function(self, cause, cmi_cause) if length <= 0 then kill(self) else - minetest_after(length, kill, self) + minetest.after(length, kill, self) end return true 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 - - --- 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 - - --- 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 - - --- 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 - --- 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 +-- 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 false + 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 --- 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] and minetest_registered_nodes[nn].damage_per_second and minetest_registered_nodes[nn].damage_per_second > 0 then - return true - end - return false -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 - - --- 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 not object then - return false - end - local factor - -- Apply view range reduction for special player armor - if object:is_player() and mod_armor 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 - --- 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 math.random(0, 100) < 90 then - --mob_sound(self, "war_cry", true) - --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 - - -local function update_roll(self) - local is_Fleckenstein = self.nametag == "Fleckenstein" - local was_Fleckenstein = false - - local rot = self.object:get_rotation() - rot.z = is_Fleckenstein and math_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] - end - - self.object:set_properties({collisionbox = cbox}) -end - - - -- is mob facing a cliff or danger local is_at_cliff_or_danger = function(self) @@ -1453,23 +951,23 @@ local is_at_cliff_or_danger = function(self) 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 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( + 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 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] + local def = minetest.registered_nodes[bnode.name] if def and def.walkable then return false end @@ -1488,18 +986,18 @@ local is_at_water_danger = function(self) 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 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( + 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 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 @@ -1507,7 +1005,7 @@ local is_at_water_danger = function(self) 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] + local def = minetest.registered_nodes[bnode.name] if def and def.walkable then return false end @@ -1517,10 +1015,25 @@ local is_at_water_danger = function(self) 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 + local function get_light(pos, tod) - local ok, light = pcall(minetest.get_natural_light or minetest.get_node_light, pos, tod) - if ok then - return light + if minetest.get_node_or_nil(pos) then + local lightfunc = minetest.get_natural_light or minetest.get_node_light + return lightfunc(pos, tod) else return 0 end @@ -1608,7 +1121,7 @@ local do_env_damage = function(self) self.object:set_velocity({x = 0, y = 0, z = 0}) end - local nodef = minetest_registered_nodes[self.standing_in] + local nodef = minetest.registered_nodes[self.standing_in] -- rain if self.rain_damage > 0 and mod_weather then @@ -1649,8 +1162,6 @@ local do_env_damage = function(self) self.health = self.health - self.lava_damage - mcl_burning.set_on_fire(self.object, 15) - effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) if check_for_death(self, "lava", {type = "environment", @@ -1667,8 +1178,6 @@ local do_env_damage = function(self) self.health = self.health - self.fire_damage - mcl_burning.set_on_fire(self.object, 8) - effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) if check_for_death(self, "fire", {type = "environment", @@ -1694,7 +1203,7 @@ local do_env_damage = function(self) 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 + if minetest.get_item_group(self.standing_in, "water") == 0 then drowning = true end elseif nodef.drowning > 0 then @@ -1720,7 +1229,7 @@ local do_env_damage = function(self) return true end else - self.breath = math_min(self.breath_max, self.breath + 1) + self.breath = math.min(self.breath_max, self.breath + 1) end end @@ -1786,13 +1295,13 @@ local do_jump = function(self) local nod = node_ok(pos) - if minetest_registered_nodes[nod.name].walkable == false then + if minetest.registered_nodes[nod.name].walkable == false then return false end -- where is front - local dir_x = -math_sin(yaw) * (self.collisionbox[4] + 0.5) - local dir_z = math_cos(yaw) * (self.collisionbox[4] + 0.5) + 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({ @@ -1810,7 +1319,7 @@ local do_jump = function(self) }, "air") -- we don't attempt to jump if there's a stack of blocks blocking - if minetest_registered_nodes[nodTop.name].walkable == true then + if minetest.registered_nodes[nodTop.name].walkable == true then return false end @@ -1819,12 +1328,12 @@ local do_jump = function(self) return false end - if self.walk_chance == 0 - or minetest_registered_items[nod.name].walkable then + local ndef = minetest.registered_nodes[nod.name] + if self.walk_chance == 0 or ndef and ndef.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 + 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() @@ -1835,7 +1344,7 @@ local do_jump = function(self) self.object:set_velocity(v) -- when in air move forward - minetest_after(0.3, function(self, v) + minetest.after(0.3, function(self, v) if (not self.object) or (not self.object:get_luaentity()) or (self.state == "die") then return end @@ -1882,7 +1391,7 @@ local entity_physics = function(pos, radius) radius = radius * 2 - local objs = minetest_get_objects_inside_radius(pos, radius) + local objs = minetest.get_objects_inside_radius(pos, radius) local obj_pos, dist for n = 1, #objs do @@ -1892,7 +1401,7 @@ local entity_physics = function(pos, radius) dist = vector.distance(pos, obj_pos) if dist < 1 then dist = 1 end - local damage = math_floor((4 / dist) * radius) + local damage = floor((4 / dist) * radius) local ent = objs[n]:get_luaentity() -- punches work on entities AND players @@ -1972,14 +1481,14 @@ local breed = function(self) return end - -- horny animal can mate for BREED_TIME seconds, - -- afterwards horny animal cannot mate again for BREED_TIME_AGAIN seconds + -- 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 < BREED_TIME + BREED_TIME_AGAIN then + and self.hornytimer < HORNY_TIME + HORNY_AGAIN_TIME then self.hornytimer = self.hornytimer + 1 - if self.hornytimer >= BREED_TIME + BREED_TIME_AGAIN then + if self.hornytimer >= HORNY_TIME + HORNY_AGAIN_TIME then self.hornytimer = 0 self.horny = false end @@ -1987,13 +1496,13 @@ local breed = function(self) -- find another same animal who is also horny and mate if nearby if self.horny == true - and self.hornytimer <= BREED_TIME then + 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 objs = minetest.get_objects_inside_radius(pos, 3) local num = 0 local ent = nil @@ -2026,18 +1535,18 @@ local breed = function(self) if ent and canmate == true and ent.horny == true - and ent.hornytimer <= BREED_TIME then + and ent.hornytimer <= HORNY_TIME then num = num + 1 end -- found your mate? then have a baby if num > 1 then - self.hornytimer = BREED_TIME + 1 - ent.hornytimer = BREED_TIME + 1 + self.hornytimer = HORNY_TIME + 1 + ent.hornytimer = HORNY_TIME + 1 -- spawn baby - minetest_after(5, function(parent1, parent2, pos) + minetest.after(5, function(parent1, parent2, pos) if not parent1.object:get_luaentity() then return end @@ -2047,7 +1556,7 @@ local breed = function(self) -- Give XP if mod_experience then - mcl_experience.throw_experience(pos, math.random(1, 7)) + mcl_experience.throw_xp(pos, math.random(1, 7)) end -- custom breed function @@ -2087,6 +1596,7 @@ local breed = function(self) end end + -- find and replace what mob is looking for (grass, wheat etc.) local replace = function(self, pos) @@ -2094,7 +1604,7 @@ local replace = function(self, pos) 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 + or random(1, self.replace_rate) > 1 then return end @@ -2102,7 +1612,7 @@ local replace = function(self, pos) if type(self.replace_what[1]) == "table" then - local num = math.random(#self.replace_what) + local num = random(#self.replace_what) what = self.replace_what[num][1] or "" with = self.replace_what[num][2] or "" @@ -2115,7 +1625,7 @@ local replace = function(self, pos) pos.y = pos.y + y_offset - local node = minetest_get_node(pos) + local node = minetest.get_node(pos) if node.name == what then local oldnode = {name = what, param2 = node.param2} @@ -2129,7 +1639,7 @@ local replace = function(self, pos) if on_replace_return ~= false then if mobs_griefing then - minetest_set_node(pos, newnode) + minetest.set_node(pos, newnode) end end @@ -2153,24 +1663,650 @@ local day_docile = function(self) end +local los_switcher = false +local height_switcher = false -local mob_detach_child = function(self, child) +-- 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) - if self.driver == child then - self.driver = nil + 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 -function do_states(self) + +-- 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 math.random(1, 4) == 1 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) + local objs = minetest.get_objects_inside_radius(s, 3) for n = 1, #objs do @@ -2188,11 +2324,11 @@ function do_states(self) z = lp.z - s.z } - yaw = (atan(vec.z / vec.x) + math_pi / 2) - self.rotate + yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - if lp.x > s.x then yaw = yaw + math_pi end + if lp.x > s.x then yaw = yaw + pi end else - yaw = yaw + math.random(-0.5, 0.5) + yaw = yaw + random(-0.5, 0.5) end yaw = set_yaw(self, yaw, 8) @@ -2207,7 +2343,7 @@ function do_states(self) if self.walk_chance ~= 0 and self.facing_fence ~= true - and math.random(1, 100) <= self.walk_chance + and random(1, 100) <= self.walk_chance and is_at_cliff_or_danger(self) == false then set_velocity(self, self.walk_velocity) @@ -2226,19 +2362,19 @@ function do_states(self) and self.lava_damage > 0) or self.breath_max ~= -1 then - lp = minetest_find_node_near(s, 1, {"group:water", "group:lava"}) + 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"}) + lp = minetest.find_node_near(s, 1, {"group:water"}) elseif self.lava_damage > 0 then - lp = minetest_find_node_near(s, 1, {"group:lava"}) + lp = minetest.find_node_near(s, 1, {"group:lava"}) elseif self.fire_damage > 0 then - lp = minetest_find_node_near(s, 1, {"group:fire"}) + lp = minetest.find_node_near(s, 1, {"group:fire"}) end @@ -2252,12 +2388,12 @@ function do_states(self) -- 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( + 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)] + lp = #lp > 0 and lp[random(#lp)] -- did we find land? if lp then @@ -2267,10 +2403,10 @@ function do_states(self) z = lp.z - s.z } - yaw = (atan(vec.z / vec.x) + math_pi / 2) - self.rotate + yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - if lp.x > s.x then yaw = yaw + math_pi end + if lp.x > s.x then yaw = yaw + pi end -- look towards land and move in that direction yaw = set_yaw(self, yaw, 6) @@ -2283,8 +2419,8 @@ function do_states(self) else -- Randomly turn - if math.random(1, 100) <= 30 then - yaw = yaw + math.random(-0.5, 0.5) + if random(1, 100) <= 30 then + yaw = yaw + random(-0.5, 0.5) yaw = set_yaw(self, yaw, 8) end end @@ -2292,9 +2428,9 @@ function do_states(self) yaw = set_yaw(self, yaw, 8) -- otherwise randomly turn - elseif math.random(1, 100) <= 30 then + elseif random(1, 100) <= 30 then - yaw = yaw + math.random(-0.5, 0.5) + yaw = yaw + random(-0.5, 0.5) yaw = set_yaw(self, yaw, 8) end @@ -2305,7 +2441,7 @@ function do_states(self) end if self.facing_fence == true or cliff_or_danger - or math.random(1, 100) <= 30 then + or random(1, 100) <= 30 then set_velocity(self, 0) self.state = "stand" @@ -2380,9 +2516,9 @@ function do_states(self) z = p.z - s.z } - yaw = (atan(vec.z / vec.x) + math_pi / 2) - self.rotate + yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - if p.x > s.x then yaw = yaw + math_pi end + if p.x > s.x then yaw = yaw + pi end yaw = set_yaw(self, yaw, 0, dtime) @@ -2448,10 +2584,10 @@ function do_states(self) local pos = self.object:get_pos() if mod_explosions then - if mobs_griefing and not minetest_is_protected(pos, "") 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, { + minetest.sound_play(self.sounds.explode, { pos = pos, gain = 1.0, max_hear_distance = self.sounds.distance or 32 @@ -2476,9 +2612,9 @@ function do_states(self) and dist > self.reach then local p1 = s - local me_y = math_floor(p1.y) + local me_y = floor(p1.y) local p2 = p - local p_y = math_floor(p2.y + 1) + local p_y = floor(p2.y + 1) local v = self.object:get_velocity() if flight_check(self, s) then @@ -2539,7 +2675,7 @@ function do_states(self) return end - if math_abs(p1.x-s.x) + math_abs(p1.z - s.z) < 0.6 then + 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 @@ -2553,9 +2689,9 @@ function do_states(self) z = p.z - s.z } - yaw = (atan(vec.z / vec.x) + math_pi / 2) - self.rotate + yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - if p.x > s.x then yaw = yaw + math_pi end + if p.x > s.x then yaw = yaw + pi end yaw = set_yaw(self, yaw, 0, dtime) @@ -2605,7 +2741,7 @@ function do_states(self) self.timer = 0 if self.double_melee_attack - and math.random(1, 2) == 1 then + and random(1, 2) == 1 then set_animation(self, "punch2") else set_animation(self, "punch") @@ -2658,9 +2794,9 @@ function do_states(self) z = p.z - s.z } - yaw = (atan(vec.z / vec.x) + math_pi / 2) - self.rotate + yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - if p.x > s.x then yaw = yaw + math_pi end + if p.x > s.x then yaw = yaw + pi end yaw = set_yaw(self, yaw, 0, dtime) @@ -2671,8 +2807,8 @@ function do_states(self) if self.shoot_interval and self.timer > self.shoot_interval - and not minetest_raycast(p, self.attack:get_pos(), false, false):next() - and math.random(1, 100) <= 60 then + 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") @@ -2681,22 +2817,26 @@ function do_states(self) mob_sound(self, "shoot_attack") -- Shoot arrow - if minetest_registered_entities[self.arrow] then + 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() + minetest.after(1, function() self.firing = false end) - arrow = minetest_add_entity(p, self.arrow) + 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 @@ -2718,251 +2858,807 @@ function do_states(self) end +-- falling and fall damage +-- returns true if mob died +local falling = function(self, pos) - --- above function exported for mount.lua -function mobs:set_animation(self, anim) - set_animation(self, anim) -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 + if self.fly and self.state ~= "die" 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 + 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 - self.animation.current = anim + -- floating in water (or falling) + local v = self.object:get_velocity() - local a_start = self.animation[anim .. "_start"] - local a_end - if fixed_frame then - a_end = a_start + 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 - a_end = self.animation[anim .. "_end"] + -- stop accelerating once max fall speed hit + self.object:set_acceleration({x = 0, y = 0, z = 0}) 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 + if minetest.registered_nodes[node_ok(pos).name].groups.lava then + if self.floats_on_lava == 1 then --- Code to execute before custom on_rightclick handling -local function on_rightclick_prefix(self, clicker) - local item = clicker:get_wielded_item() + self.object:set_acceleration({ + x = 0, + y = -self.fall_speed / (max(1, v.y) ^ 2), + z = 0 + }) + end + end - -- Name mob with nametag - if not self.ignores_nametag and item:get_name() == "mcl_mobs:nametag" then + -- in water then float up + if minetest.registered_nodes[node_ok(pos).name].groups.water 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) + 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.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 + self.old_y = self.object:get_pos().y end - end - return false end ---[[local function create_mob_on_rightclick(on_rightclick) - return function(self, clicker) - local stop = on_rightclick_prefix(self, clicker) - if (not stop) and (on_rightclick) then - on_rightclick(self, clicker) +local teleport = function(self, target) + if self.do_teleport then + if self.do_teleport(self, target) == false then + return end end -end]] - --- set and return valid yaw -local function set_yaw(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.yaw(yaw) - update_roll(self) - 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 +-- deal damage and effects when mob punched +local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) - ---mob_step = function() - --if self.state == "die" then - -- print("need custom die stop moving thing") - -- return - --end - - --if not self.fire_resistant then - -- mcl_burning.tick(self.object, dtime, self) - --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.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 - - - -- run custom function (defined in mob lua file) - --if self.do_custom then + -- custom punch function + if self.do_punch then -- when false skip going any further - --if self.do_custom(self, dtime) == false then - -- return - --end - --end + 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, 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 - 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 + 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.lifetimer <= 20 then + + 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 + 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 + + local t = type(stat) + + if t ~= "function" + and t ~= "nil" + and t ~= "userdata" + and _ ~= "_cmi_components" then + tmp[_] = self[_] + end + end + + return minetest.serialize(tmp) +end + + +-- activate mob and reload settings +local mob_activate = function(self, staticdata, def, dtime) + + -- remove monsters in peaceful mode + 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 + for _,stat in pairs(tmp) do + self[_] = stat + end + end + + -- select random texture, set model and size + if not self.base_texture 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)] + 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 = { + x = self.base_size.x * .5, + y = self.base_size.y * .5, + } + + if def.child_texture then + textures = def.child_texture[1] + end + + colbox = { + self.base_colbox[1] * .5, + self.base_colbox[2] * .5, + self.base_colbox[3] * .5, + self.base_colbox[4] * .5, + self.base_colbox[5] * .5, + self.base_colbox[6] * .5 + } + selbox = { + self.base_selbox[1] * .5, + self.base_selbox[2] * .5, + self.base_selbox[3] * .5, + self.base_selbox[4] * .5, + self.base_selbox[5] * .5, + self.base_selbox[6] * .5 + } + end + + if self.health == 0 then + self.health = 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} + self.path.stuck = false + self.path.following = false -- currently following path? + self.path.stuck_timer = 0 -- if stuck for too long search for path + + -- Armor groups + -- immortal=1 because we use custom health + -- handling (using "health" property) + local armor + if type(self.armor) == "table" then + armor = table.copy(self.armor) + armor.immortal = 1 + else + armor = {immortal=1, fleshy = self.armor} + end + self.object:set_armor_groups(armor) + self.old_y = self.object:get_pos().y + self.old_health = self.health + self.sounds.distance = self.sounds.distance or 10 + self.textures = textures + self.mesh = mesh + self.collisionbox = colbox + self.selectionbox = selbox + self.visual_size = vis_size + self.standing_in = "ignore" + self.standing_on = "ignore" + self.jump_sound_cooloff = 0 -- used to prevent jump sound from being played too often in short time + self.opinion_sound_cooloff = 0 -- used to prevent sound spam of particular sound types + + self.texture_mods = {} + self.object:set_texture_mod("") + + self.v_start = false + self.timer = 0 + 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 + end + end + + -- run after_activate + if def.after_activate then + def.after_activate(self, staticdata, def, dtime) + end + + if use_cmi then + self._cmi_components = cmi.activate_components(self.serialized_cmi_components) + cmi.notify_activate(self.object, dtime) + end +end + + +-- main mob function +local mob_step = function(self, dtime) + + if not self.fire_resistant then + mcl_burning.tick(self.object, dtime, self) + 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 + 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) + update_roll(self) + end + + -- end rotation + + -- 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 -- knockback timer - --if self.pause_timer > 0 then + if self.pause_timer > 0 then - -- self.pause_timer = self.pause_timer - dtime + self.pause_timer = self.pause_timer - dtime - -- return - --end + return + end -- attack timer - --self.timer = self.timer + dtime + self.timer = self.timer + dtime - --[[ if self.state ~= "attack" then if self.timer < 1 then - print("returning>>error code 1") return end self.timer = 0 end - ]]-- -- never go over 100 - --if self.timer > 100 then - -- self.timer = 1 - --end + if self.timer > 100 then + self.timer = 1 + end -- mob plays random sound at times - --if math.random(1, 70) == 1 then - -- mob_sound(self, "random", true) - --end + if random(1, 70) == 1 then + mob_sound(self, "random", true) + end -- environmental damage timer (every 1 second) - --self.env_damage_timer = self.env_damage_timer + dtime + 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 - --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 + replace(self, pos) + end - --monster_attack(self) + monster_attack(self) - --npc_attack(self) + npc_attack(self) - --breed(self) + breed(self) - --do_jump(self) - - --runaway_from(self) - - - --if is_at_water_danger(self) and self.state ~= "attack" then - -- if math.random(1, 10) <= 6 then - -- set_velocity(self, 0) - -- self.state = "stand" - -- set_animation(self, "stand") - -- yaw = yaw + math.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[nnenable_physicss if not on/in flowing liquid - self._flowing = false - enable_physics(self.object, self, true) + if do_states(self, dtime) then return end + if not self.object:get_luaentity() then + return false + 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" @@ -2991,6 +3687,698 @@ end end 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 +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 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, { + + use_texture_alpha = def.use_texture_alpha, + stepheight = def.stepheight or 0.6, + name = name, + description = def.description, + 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 + 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, + 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 + 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, + 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) + --this is a temporary hack so mobs stop + --glitching and acting really weird with the + --default built in engine collision detection + self.object:set_properties({ + collide_with_objects = false, + }) + 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 + + +-- 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, + 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 - (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._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) + end + else + mobs:safe_boom(self, pos, strength) + end + + -- delete the object after it punched the player to avoid nil entities in e.g. mcl_shields!! + self.object:remove() +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) + timer = timer + dtime + if timer < 1 then return end + for _, player in pairs(minetest.get_connected_players()) do + local pos = player:get_pos() + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 47)) do + local lua = obj:get_luaentity() + if lua and lua._cmi_is_mob then + lua.lifetimer = math.max(20, lua.lifetimer) + lua.despawn_immediately = false + end + end + end + timer = 0 +end) diff --git a/mods/ENTITIES/mcl_mobs/api.txt b/mods/ENTITIES/mcl_mobs/api.txt index 2d8cef5b0..eda74aeb4 100644 --- a/mods/ENTITIES/mcl_mobs/api.txt +++ b/mods/ENTITIES/mcl_mobs/api.txt @@ -502,6 +502,20 @@ and damages any entity caught inside the blast radius. Protection will limit node destruction but not entity damage. +mobs:capture_mob +---------------- + +mobs:capture_mob(...) + +Does nothing and returns false. + +This function is provided for compability with Mobs Redo for an attempt to +capture a mob. +Mobs cannot be captured in MineClone 2. + +In Mobs Redo, this is generally called inside the on_rightclick section of the mob +api code, it provides a chance of capturing the mob. See Mobs Redo documentation +of parameters. Feeding and Taming/Breeding --------------------------- @@ -521,6 +535,19 @@ Will return true when mob is fed with item it likes. them up +Protecting Mobs +--------------- + +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. + + 'self' mob information + 'clicker' player information + + Riding Mobs ----------- @@ -578,7 +605,7 @@ Note: animation names above are from the pre-defined animation lists inside mob registry without extensions. -mobs.set_mob_animation(self, name) +mobs:set_animation(self, name) This function sets the current animation for mob, defaulting to "stand" if not found. @@ -754,5 +781,8 @@ mobs:register_mob("mob_horse:horse", { inv:remove_item("main", "mobs:saddle") end end + + -- used to capture horse with magic lasso + mobs:capture_mob(self, clicker, 0, 0, 80, false, nil) end }) diff --git a/mods/ENTITIES/mcl_mobs/api/api.lua b/mods/ENTITIES/mcl_mobs/api/api.lua deleted file mode 100644 index 41b522fef..000000000 --- a/mods/ENTITIES/mcl_mobs/api/api.lua +++ /dev/null @@ -1,735 +0,0 @@ --- API for Mobs Redo: MineClone 2 Delux 2.0 DRM Free Early Access Super Extreme Edition - --- mobs library -mobs = {} - --- lua locals - can grab from this to easily plop them into the api lua files - ---localize minetest functions -local minetest_settings = minetest.settings -local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius -local minetest_get_modpath = minetest.get_modpath -local minetest_registered_nodes = minetest.registered_nodes -local minetest_get_node = minetest.get_node ---local minetest_get_item_group = minetest.get_item_group -local minetest_registered_entities = minetest.registered_entities ---local minetest_line_of_sight = minetest.line_of_sight ---local minetest_after = minetest.after ---local minetest_sound_play = minetest.sound_play ---local minetest_add_particlespawner = minetest.add_particlespawner ---local minetest_registered_items = minetest.registered_items ---local minetest_set_node = minetest.set_node -local minetest_add_item = minetest.add_item ---local minetest_get_craft_result = minetest.get_craft_result ---local minetest_find_path = minetest.find_path -local minetest_is_creative_enabled = minetest.is_creative_enabled ---local minetest_find_node_near = minetest.find_node_near ---local minetest_find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air ---local minetest_raycast = minetest.raycast ---local minetest_get_us_time = minetest.get_us_time -local minetest_add_entity = minetest.add_entity ---local minetest_get_natural_light = minetest.get_natural_light ---local minetest_get_node_or_nil = minetest.get_node_or_nil - --- localize math functions -local math = math - --- localize vector functions -local vector = vector - -local string = string - --- mob constants ---local BREED_TIME = 30 ---local BREED_TIME_AGAIN = 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 GRAVITY = minetest_settings:get("movement_gravity")-- + 9.81 - -local MAX_MOB_NAME_LENGTH = 30 - - ---[[local MOB_CAP = {} -MOB_CAP.hostile = 70 -MOB_CAP.passive = 10 -MOB_CAP.ambient = 15 -MOB_CAP.water = 15 -]] - --- Load main settings ---local damage_enabled = minetest_settings:get_bool("enable_damage") ---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) - --- 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") ---local mod_explosions = minetest_get_modpath("mcl_explosions") -local mod_mobspawners = minetest_get_modpath("mcl_mobspawners") ---local mod_hunger = minetest_get_modpath("mcl_hunger") ---local mod_worlds = minetest_get_modpath("mcl_worlds") ---local mod_armor = minetest_get_modpath("mcl_armor") ---local mod_experience = minetest_get_modpath("mcl_experience") - - --- random locals I found ---local los_switcher = false ---local height_switcher = false - --- Get translator -local S = minetest.get_translator("mcl_mobs") - --- CMI support check ---local use_cmi = minetest.global_exists("cmi") - --- creative check -function mobs.is_creative(name) - return minetest_is_creative_enabled(name) -end - ---[[local function atan(x) - if not x or x ~= x then - return 0 - else - return math.atan(x) - end -end]] - --- Shows helpful debug info above each mob ---local mobs_debug = minetest_settings:get_bool("mobs_debug", false) - --- Peaceful mode message so players will know there are no monsters -if minetest_settings:get_bool("only_peaceful_mobs", false) then - minetest.register_on_joinplayer(function(player) - minetest.chat_send_player(player:get_player_name(), - S("Peaceful mode active! No monsters will spawn.")) - end) -end - - -local api_path = minetest.get_modpath(minetest.get_current_modname()).."/api/mob_functions/" - ---ignite all parts of the api -dofile(api_path .. "ai.lua") -dofile(api_path .. "animation.lua") -dofile(api_path .. "collision.lua") -dofile(api_path .. "environment.lua") -dofile(api_path .. "interaction.lua") -dofile(api_path .. "movement.lua") -dofile(api_path .. "set_up.lua") -dofile(api_path .. "attack_type_instructions.lua") -dofile(api_path .. "sound_handling.lua") -dofile(api_path .. "death_logic.lua") -dofile(api_path .. "mob_effects.lua") -dofile(api_path .. "projectile_handling.lua") -dofile(api_path .. "breeding.lua") -dofile(api_path .. "head_logic.lua") - - -mobs.spawning_mobs = {} - - - - --- register mob entity -function mobs:register_mob(name, def) - - 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 - - mobs.spawning_mobs[name] = true - - 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 - - minetest.register_entity(name, { - description = def.description, - use_texture_alpha = def.use_texture_alpha, - stepheight = def.stepheight or 0.6, - stepheight_backup = 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 = def.rotate or 0, -- 0=front, 90=side, 180=back, 270=side2 - hp_min = scale_difficulty(def.hp_min, 5, 1), - hp_max = scale_difficulty(def.hp_max, 10, 1), - xp_min = def.xp_min or 1, - xp_max = def.xp_max or 5, - breath_max = def.breath_max or 6, - breathes_in_water = def.breathes_in_water or false, - physical = true, - collisionbox = collisionbox, - collide_with_objects = def.collide_with_objects or false, - 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 = mobs.create_mob_on_rightclick(def.on_rightclick), - arrow = def.arrow, - shoot_interval = def.shoot_interval, - sounds = def.sounds or {}, - animation = def.animation, - 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 - 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, - timer = 0, - state_timer = 0, - env_damage_timer = 0, - tamed = false, - pause_timer = 0, - gotten = false, - 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, - 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, - - --j4i stuff - yaw = 0, - automatic_face_movement_dir = def.rotate or 0, -- 0=front, 90=side, 180=back, 270=side2 - automatic_face_movement_max_rotation_per_sec = 360, --degrees - backface_culling = true, - walk_timer = 0, - stand_timer = 0, - current_animation = "", - gravity = GRAVITY, - swim = def.swim, - swim_in = def.swim_in or {mobs_mc.items.water_source, "mcl_core:water_flowing", mobs_mc.items.river_water_source}, - pitch_switch = "static", - jump_only = def.jump_only, - hostile = def.hostile, - neutral = def.neutral, - attacking = nil, - visual_size_origin = def.visual_size or {x = 1, y = 1, z = 1}, - punch_timer_cooloff = def.punch_timer_cooloff or 0.5, - death_animation_timer = 0, - hostile_cooldown = def.hostile_cooldown or 15, - tilt_fly = def.tilt_fly, - tilt_swim = def.tilt_swim, - fall_slow = def.fall_slow, - projectile_cooldown_min = def.projectile_cooldown_min or 2, - projectile_cooldown_max = def.projectile_cooldown_max or 6, - skittish = def.skittish, - - minimum_follow_distance = def.minimum_follow_distance or 0.5, --make mobs not freak out when underneath - - memory = 0, -- memory timer if chasing/following - fly_random_while_attack = def.fly_random_while_attack, - - --for spiders - always_climb = def.always_climb, - - --despawn mechanic variables - lifetimer_reset = 30, --30 seconds - lifetimer = 30, --30 seconds - - --breeding stuff - breed_timer = 0, - breed_lookout_timer = 0, - breed_distance = def.breed_distance or 1.5, --how far away mobs have to be to begin actual breeding - breed_lookout_timer_goal = 30, --30 seconds (this timer is for how long the mob looks for a mate) - breed_timer_cooloff = 5*60, -- 5 minutes (this timer is for how long the mob has to wait before being bred again) - bred = false, - follow = def.follow, --this item is also used for the breeding mechanism - follow_distance = def.follow_distance or 2, - baby_size = def.baby_size or 0.5, - baby = false, - grow_up_timer = 0, - grow_up_goal = 20*60, --in 20 minutes the mob grows up - special_breed_timer = 0, --this is used for the AHEM AHEM part of breeding - - backup_visual_size = def.visual_size, - backup_collisionbox = collisionbox, - backup_selectionbox = def.selectionbox or def.collisionbox, - - - --fire timer - burn_timer = 0, - - ignores_cobwebs = def.ignores_cobwebs, - breath = def.breath_max or 6, - - random_sound_timer_min = 3, - random_sound_timer_max = 10, - - --head code variables - --defaults are for the cow's default - --because I don't know what else to set them - --to :P - - --you must use these to adjust the mob's head positions - - --has_head is used as a logic gate (quick easy check) - has_head = def.has_head or false, - --head_bone is the actual bone in the model which the head - --is attached to for animation - head_bone = def.head_bone or "head", - - --this part controls the base position of the head calculations - --localized to the mob's visual yaw when gotten (self.object:get_yaw()) - --you can enable the debug in /mob_functions/head_logic.lua by uncommenting the - --particle spawner code - head_height_offset = def.head_height_offset or 1.0525, - head_direction_offset = def.head_direction_offset or 0.5, - - --this part controls the visual of the head - head_bone_pos_y = def.head_bone_pos_y or 3.6, - head_bone_pos_z = def.head_bone_pos_z or -0.6, - head_pitch_modifier = def.head_pitch_modifier or 0, - - --these variables are switches in case the model - --moves the wrong way - swap_y_with_x = def.swap_y_with_x or false, - reverse_head_yaw = def.reverse_head_yaw or false, - - --END HEAD CODE VARIABLES - - --end j4i stuff - - -- MCL2 extensions - teleport = mobs.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, - eye_height = def.eye_height or 1.5, - defuse_reach = def.defuse_reach or 4, - -- End of MCL2 extensions - - on_spawn = def.on_spawn, - - --on_blast = def.on_blast or do_tnt, - - on_step = mobs.mob_step, - - --do_punch = def.do_punch, - - on_punch = mobs.mob_punch, - - --on_breed = def.on_breed, - - --on_grown = def.on_grown, - - --on_detach_child = mob_detach_child, - - on_activate = function(self, staticdata, dtime) - self.object:set_acceleration(vector.new(0,-GRAVITY, 0)) - return mobs.mob_activate(self, staticdata, def, dtime) - end, - - get_staticdata = function(self) - return mobs.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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --- register arrow for shoot attack -function mobs:register_arrow(name, def) - - -- errorcheck - if not name or not def then - print("failed to register arrow entity") - return - end - - minetest.register_entity(name.."_entity", { - - 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, - speed = def.speed or nil, - on_step = function(self) - - local vel = self.object:get_velocity() - - local pos = self.object:get_pos() - - if self.timer > 150 - or not mobs.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 - - --do this to prevent clipping through main entity sprite - local pos_adjustment = vector.multiply(vector.normalize(vel), -1) - local divider = def.tail_distance_divider or 1 - pos_adjustment = vector.divide(pos_adjustment, divider) - local new_pos = vector.add(pos, pos_adjustment) - minetest.add_particle({ - pos = new_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 = minetest_get_node(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 - - if self.hit_player then - self.hit_player(self, player) - else - mobs.arrow_hit(self, player) - end - - 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 - and (self._shooter and entity.name ~= self._shooter: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 - and (self._shooter and entity.name ~= self._shooter: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 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 - - 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 - - diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua deleted file mode 100644 index 894a1f5e4..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua +++ /dev/null @@ -1,1113 +0,0 @@ -local math = math -local vector = vector -local string = string - -local tonumber = tonumber - -local minetest_yaw_to_dir = minetest.yaw_to_dir -local minetest_get_item_group = minetest.get_item_group -local minetest_get_node = minetest.get_node -local minetest_line_of_sight = minetest.line_of_sight -local minetest_get_node_light = minetest.get_node_light - -local DOUBLE_PI = math.pi * 2 -local THIRTY_SECONDTH_PI = DOUBLE_PI * 0.03125 - ---a simple helper function which is too small to move into movement.lua -local function quick_rotate(self,dtime) - self.yaw = self.yaw + THIRTY_SECONDTH_PI - if self.yaw > DOUBLE_PI then - self.yaw = self.yaw - DOUBLE_PI - end -end - ---a simple helper function for rounding ---http://lua-users.org/wiki/SimpleRound -local function round2(num, numDecimalPlaces) - return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num)) -end - - ---[[ - _ _ -| | | | -| | __ _ _ __ __| | -| | / _` | '_ \ / _` | -| |___| (_| | | | | (_| | -\_____/\__,_|_| |_|\__,_| -]]-- - ---this is basically reverse jump_check -local function cliff_check(self,dtime) - --mobs will flip out if they are falling without this - if self.object:get_velocity().y ~= 0 then - return false - end - - local pos = self.object:get_pos() - local dir = minetest_yaw_to_dir(self.yaw) - local collisionbox = self.object:get_properties().collisionbox - local radius = collisionbox[4] + 0.5 - - dir = vector.multiply(dir,radius) - - local free_fall = minetest_line_of_sight( - {x = pos.x + dir.x, y = pos.y, z = pos.z + dir.z}, - {x = pos.x + dir.x, y = pos.y - self.fear_height, z = pos.z + dir.z}) - - return free_fall -end - --- state switching logic (stand, walk, run, attacks) -local land_state_list_wandering = {"stand", "walk"} - -local function land_state_switch(self, dtime) - - --do math before sure not attacking, following, or running away so continue - --doing random walking for mobs if all states are not met - self.state_timer = self.state_timer - dtime - - --only run away - if self.skittish and self.state == "run" then - self.run_timer = self.run_timer - dtime - if self.run_timer > 0 then - return - end - --continue - end - - --ignore everything else if breeding - if self.breed_lookout_timer and self.breed_lookout_timer > 0 then - self.state = "breed" - return - --reset the state timer to get the mob out of - --the breed state - elseif self.state == "breed" then - self.state_timer = 0 - end - - --ignore everything else if following - if mobs.check_following(self) and - (not self.breed_lookout_timer or (self.breed_lookout_timer and self.breed_lookout_timer == 0)) and - (not self.breed_timer or (self.breed_timer and self.breed_timer == 0)) then - self.state = "follow" - return - --reset the state timer to get the mob out of - --the follow state - not the cleanest option - --but the easiest - elseif self.state == "follow" then - self.state_timer = 0 - end - - --only attack - if self.hostile and self.attacking then - self.state = "attack" - return - end - - --if finally reached here then do random wander - if self.state_timer <= 0 then - self.state_timer = math.random(4,10) + math.random() - self.state = land_state_list_wandering[math.random(1,#land_state_list_wandering)] - end - -end - --- states are executed here -local function land_state_execution(self, dtime) - - --[[ -- this is a debug which shows the timer and makes mobs breed 100 times faster - print(self.breed_timer) - if self.breed_timer > 0 then - self.breed_timer = self.breed_timer - (dtime * 100) - if self.breed_timer <= 0 then - self.breed_timer = 0 - end - end - ]]-- - - --no collisionbox exception - if not self.object:get_properties() then - return - end - - --timer to time out looking for mate - if self.breed_lookout_timer and self.breed_lookout_timer > 0 then - self.breed_lookout_timer = self.breed_lookout_timer - dtime - --looking for mate failed - if self.breed_lookout_timer <= 0 then - self.breed_lookout_timer = 0 - end - end - - --cool off after breeding - if self.breed_timer and self.breed_timer > 0 then - self.breed_timer = self.breed_timer - dtime - --do this to skip the first check, using as switch - if self.breed_timer <= 0 then - self.breed_timer = 0 - end - end - - - local pos = self.object:get_pos() - local collisionbox = self.object:get_properties().collisionbox - --get the center of the mob - pos.y = pos.y + (collisionbox[2] + collisionbox[5] / 2) - local current_node = minetest_get_node(pos).name - local float_now = false - - --recheck if in water or lava - if minetest_get_item_group(current_node, "water") ~= 0 or minetest_get_item_group(current_node, "lava") ~= 0 then - float_now = true - end - - --make slow falling mobs fall slow - if self.fall_slow then - local velocity = self.object:get_velocity() - if velocity then - if velocity.y < 0 then - --lua is acting really weird so we have to help it - if round2(self.object:get_acceleration().y, 1) == -self.gravity then - self.object:set_acceleration(vector.new(0,0,0)) - mobs.mob_fall_slow(self) - end - else - if round2(self.object:get_acceleration().y, 1) == 0 then - self.object:set_acceleration(vector.new(0,-self.gravity,0)) - end - end - end - end - - --calculate fall damage - if self.fall_damage then - mobs.calculate_fall_damage(self) - end - - if self.state == "stand" then - - --do animation - mobs.set_mob_animation(self, "stand") - - --set the velocity of the mob - mobs.set_velocity(self,0) - - --animation fixes for explosive mobs - if self.attack_type == "explode" then - mobs.reverse_explosion_animation(self,dtime) - end - - mobs.lock_yaw(self) - elseif self.state == "follow" then - --always look at players - mobs.set_yaw_while_following(self) - - --check distance - local distance_from_follow_person = vector.distance(self.object:get_pos(), self.following_person:get_pos()) - local distance_2d = mobs.get_2d_distance(self.object:get_pos(), self.following_person:get_pos()) - --don't push the player if too close - --don't spin around randomly - if self.follow_distance < distance_from_follow_person and self.minimum_follow_distance < distance_2d then - mobs.set_mob_animation(self, "run") - mobs.set_velocity(self,self.run_velocity) - - if mobs.jump_check(self) == 1 then - mobs.jump(self) - end - else - mobs.set_mob_animation(self, "stand") - mobs.set_velocity(self,0) - end - - elseif self.state == "walk" then - - self.walk_timer = self.walk_timer - dtime - - --reset the walk timer - if self.walk_timer <= 0 then - - --re-randomize the walk timer - self.walk_timer = math.random(1,6) + math.random() - - --set the mob into a random direction - self.yaw = (math.random() * (math.pi * 2)) - end - - --do animation - mobs.set_mob_animation(self, "walk") - - --enable rotation locking - mobs.movement_rotation_lock(self) - - --check for nodes to jump over - local node_in_front_of = mobs.jump_check(self) - - if node_in_front_of == 1 then - mobs.jump(self) - --turn if on the edge of cliff - --(this is written like this because unlike - --jump_check which simply tells the mob to jump - --this requires a mob to turn, removing the - --ease of a full implementation for it in a single - --function) - elseif node_in_front_of == 2 or (self.fear_height ~= 0 and cliff_check(self,dtime)) then - --turn 45 degrees if so - quick_rotate(self,dtime) - --stop the mob so it doesn't fall off - mobs.set_velocity(self,0) - end - - --only move forward if path is clear - if node_in_front_of == 0 or node_in_front_of == 1 then - --set the velocity of the mob - mobs.set_velocity(self,self.walk_velocity) - end - - --animation fixes for explosive mobs - if self.attack_type == "explode" then - mobs.reverse_explosion_animation(self,dtime) - end - - elseif self.state == "run" then - - --do animation - mobs.set_mob_animation(self, "run") - - --enable rotation locking - mobs.movement_rotation_lock(self) - - --check for nodes to jump over - local node_in_front_of = mobs.jump_check(self) - - if node_in_front_of == 1 then - mobs.jump(self) - --turn if on the edge of cliff - --(this is written like this because unlike - --jump_check which simply tells the mob to jump - --this requires a mob to turn, removing the - --ease of a full implementation for it in a single - --function) - elseif node_in_front_of == 2 or (self.fear_height ~= 0 and cliff_check(self,dtime)) then - --turn 45 degrees if so - quick_rotate(self,dtime) - --stop the mob so it doesn't fall off - mobs.set_velocity(self,0) - end - - --only move forward if path is clear - if node_in_front_of == 0 or node_in_front_of == 1 then - --set the velocity of the mob - mobs.set_velocity(self,self.run_velocity) - end - - elseif self.state == "attack" then - - --execute mob attack type - if self.attack_type == "explode" then - - mobs.explode_attack_walk(self, dtime) - - elseif self.attack_type == "punch" then - - mobs.punch_attack_walk(self,dtime) - - elseif self.attack_type == "projectile" then - - mobs.projectile_attack_walk(self,dtime) - - end - elseif self.state == "breed" then - - mobs.breeding_effect(self) - - local mate = mobs.look_for_mate(self) - - --found a mate - if mate then - mobs.set_yaw_while_breeding(self,mate) - mobs.set_velocity(self, self.walk_velocity) - - --smoosh together basically - if vector.distance(self.object:get_pos(), mate:get_pos()) <= self.breed_distance then - mobs.set_mob_animation(self, "stand") - if self.special_breed_timer == 0 then - self.special_breed_timer = 2 --breeding takes 2 seconds - end - - self.special_breed_timer = self.special_breed_timer - dtime - if self.special_breed_timer <= 0 then - - --pop a baby out, it's a miracle! - local baby_pos = vector.divide(vector.add(self.object:get_pos(), mate:get_pos()), 2) - minetest.add_entity(baby_pos, self.name, minetest.serialize({baby = true, grow_up_timer = self.grow_up_goal, bred = true})) - - mobs.play_sound_specific(self,"item_drop_pickup") - - self.special_breed_timer = 0 - self.breed_lookout_timer = 0 - self.breed_timer = self.breed_timer_cooloff - - mate:get_luaentity().special_breed_timer = 0 - mate:get_luaentity().breed_lookout_timer = 0 - mate:get_luaentity().breed_timer = self.breed_timer_cooloff -- can reuse because it's the same mob - end - else - mobs.set_mob_animation(self, "walk") - end - --couldn't find a mate, just stand there until the player pushes it towards one - --or the timer runs out - else - mobs.set_mob_animation(self, "stand") - mobs.set_velocity(self,0) - end - - end - if float_now then - mobs.float(self) - else - local acceleration = self.object:get_acceleration() - if acceleration and acceleration.y == 0 then - self.object:set_acceleration(vector.new(0,-self.gravity,0)) - end - end -end - - - - ---[[ - _____ _ -/ ___| (_) -\ `--.__ ___ _ __ ___ - `--. \ \ /\ / / | '_ ` _ \ -/\__/ /\ V V /| | | | | | | -\____/ \_/\_/ |_|_| |_| |_| -]]-- - - - --- state switching logic (stand, walk, run, attacks) -local swim_state_list_wandering = {"stand", "swim"} - -local function swim_state_switch(self, dtime) - self.state_timer = self.state_timer - dtime - if self.state_timer <= 0 then - self.state_timer = math.random(4,10) + math.random() - self.state = swim_state_list_wandering[math.random(1,#swim_state_list_wandering)] - end -end - - ---check if a mob needs to turn while swimming -local function swim_turn_check(self,dtime) - - local pos = self.object:get_pos() - pos.y = pos.y + 0.1 - local dir = minetest_yaw_to_dir(self.yaw) - - local collisionbox = self.object:get_properties().collisionbox - local radius = collisionbox[4] + 0.5 - - vector.multiply(dir, radius) - - local test_dir = vector.add(pos,dir) - - local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0 - - return green_flag_1 -end - ---this is to swap the built in engine acceleration modifier -local function swim_physics_swapper(self, inside_swim_node) - --should be swimming, gravity is applied, switch to floating - if inside_swim_node and self.object:get_acceleration().y ~= 0 then - self.object:set_acceleration(vector.new(0,0,0)) - --not be swim, gravity isn't applied, switch to falling - elseif not inside_swim_node and self.object:get_acceleration().y == 0 then - self.pitch = 0 - self.object:set_acceleration(vector.new(0,-self.gravity,0)) - end -end - - -local random_pitch_multiplier = {-1,1} --- states are executed here -local function swim_state_execution(self, dtime) - - local pos = self.object:get_pos() - - pos.y = pos.y + self.object:get_properties().collisionbox[5] - local current_node = minetest_get_node(pos).name - local inside_swim_node = false - - --quick scan everything to see if inside swim node - for _,id in pairs(self.swim_in) do - if id == current_node then - inside_swim_node = true - break - end - end - - --turn gravity on or off - swim_physics_swapper(self, inside_swim_node) - - --swim properly if inside swim node - if inside_swim_node then - - if self.state == "stand" then - - --do animation - mobs.set_mob_animation(self, "stand") - - mobs.set_swim_velocity(self,0) - - if self.tilt_swim then - mobs.set_static_pitch(self) - end - - mobs.lock_yaw(self) - elseif self.state == "swim" then - self.walk_timer = self.walk_timer - dtime - --reset the walk timer - if self.walk_timer <= 0 then - --re-randomize the walk timer - self.walk_timer = math.random(1,6) + math.random() - --set the mob into a random direction - self.yaw = (math.random() * (math.pi * 2)) - - --create a truly random pitch, since there is no easy access to pitch math that I can find - self.pitch = math.random() * math.random(1,3) * random_pitch_multiplier[math.random(1,2)] - end - - --do animation - mobs.set_mob_animation(self, "walk") - - --do a quick turn to make mob continuously move - --if in a fish tank or something - if swim_turn_check(self,dtime) then - quick_rotate(self,dtime) - end - - mobs.set_swim_velocity(self,self.walk_velocity) - - --only enable tilt swimming if enabled - if self.tilt_swim then - mobs.set_dynamic_pitch(self) - end - - --enable rotation locking - mobs.movement_rotation_lock(self) - end - --flop around if not inside swim node - else - --do animation - mobs.set_mob_animation(self, "stand") - - mobs.flop(self) - - if self.tilt_swim then - mobs.set_static_pitch(self) - end - end - -end - - ---[[ -______ _ -| ___| | -| |_ | |_ _ -| _| | | | | | -| | | | |_| | -\_| |_|\__, | - __/ | - |___/ -]]-- - --- state switching logic (stand, walk, run, attacks) -local fly_state_list_wandering = {"stand", "fly"} - -local function fly_state_switch(self, dtime) - - if self.hostile and self.attacking then - self.state = "attack" - return - end - - self.state_timer = self.state_timer - dtime - if self.state_timer <= 0 then - self.state_timer = math.random(4,10) + math.random() - self.state = fly_state_list_wandering[math.random(1,#fly_state_list_wandering)] - end -end - - ---check if a mob needs to turn while flying -local function fly_turn_check(self, dtime) - - local pos = self.object:get_pos() - pos.y = pos.y + 0.1 - local dir = minetest_yaw_to_dir(self.yaw) - - local collisionbox = self.object:get_properties().collisionbox - local radius = collisionbox[4] + 0.5 - - vector.multiply(dir, radius) - - local test_dir = vector.add(pos,dir) - - local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0 - - return green_flag_1 -end - ---this is to swap the built in engine acceleration modifier -local function fly_physics_swapper(self, inside_fly_node) - - --should be flyming, gravity is applied, switch to floating - if inside_fly_node and self.object:get_acceleration().y ~= 0 then - self.object:set_acceleration(vector.new(0,0,0)) - --not be fly, gravity isn't applied, switch to falling - elseif not inside_fly_node and self.object:get_acceleration().y == 0 then - self.pitch = 0 - self.object:set_acceleration(vector.new(0,-self.gravity,0)) - end -end - - -local random_pitch_multiplier = {-1,1} --- states are executed here -local function fly_state_execution(self, dtime) - local pos = self.object:get_pos() - pos.y = pos.y + 0.1 - local current_node = minetest_get_node(pos).name - local inside_fly_node = minetest_get_item_group(current_node, "solid") == 0 - - local float_now = false - --recheck if in water or lava - if minetest_get_item_group(current_node, "water") ~= 0 or minetest_get_item_group(current_node, "lava") ~= 0 then - inside_fly_node = false - float_now = true - end - - --turn gravity on or off - fly_physics_swapper(self,inside_fly_node) - - --fly properly if inside fly node - if inside_fly_node then - if self.state == "stand" then - - --do animation - mobs.set_mob_animation(self, "stand") - - mobs.set_fly_velocity(self,0) - - if self.tilt_fly then - mobs.set_static_pitch(self) - end - - mobs.lock_yaw(self) - - elseif self.state == "fly" then - - self.walk_timer = self.walk_timer - dtime - - --reset the walk timer - if self.walk_timer <= 0 then - --re-randomize the walk timer - self.walk_timer = math.random(1,6) + math.random() - --set the mob into a random direction - self.yaw = (math.random() * (math.pi * 2)) - - --create a truly random pitch, since there is no easy access to pitch math that I can find - self.pitch = math.random() * math.random(1,3) * random_pitch_multiplier[math.random(1,2)] - end - - --do animation - mobs.set_mob_animation(self, "walk") - - --do a quick turn to make mob continuously move - --if in a bird cage or something - if fly_turn_check(self,dtime) then - quick_rotate(self,dtime) - end - - if self.tilt_fly then - mobs.set_dynamic_pitch(self) - end - - mobs.set_fly_velocity(self,self.walk_velocity) - - --enable rotation locking - mobs.movement_rotation_lock(self) - elseif self.state == "attack" then - --execute mob attack type - --if self.attack_type == "explode" then - - --mobs.explode_attack_fly(self, dtime) - - --elseif self.attack_type == "punch" then - - --mobs.punch_attack_fly(self,dtime) - - if self.attack_type == "projectile" then - - mobs.projectile_attack_fly(self,dtime) - - end - end - else - --make the mob float - if self.floats and float_now then - mobs.set_velocity(self, 0) - - mobs.float(self) - - if self.tilt_fly then - mobs.set_static_pitch(self) - end - end - end -end - - ---[[ - ___ - |_ | - | |_ _ _ __ ___ _ __ - | | | | | '_ ` _ \| '_ \ -/\__/ / |_| | | | | | | |_) | -\____/ \__,_|_| |_| |_| .__/ - | | - |_| -]]-- - - ---check if a mob needs to turn while jumping ---[[local function jump_turn_check(self, dtime) - local pos = self.object:get_pos() - pos.y = pos.y + 0.1 - local dir = minetest_yaw_to_dir(self.yaw) - - local collisionbox = self.object:get_properties().collisionbox - local radius = collisionbox[4] + 0.5 - - vector.multiply(dir, radius) - - local test_dir = vector.add(pos,dir) - - local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0 - - return green_flag_1 -end]] - --- state switching logic (stand, jump, run, attacks) -local jump_state_list_wandering = {"stand", "jump"} - -local function jump_state_switch(self, dtime) - self.state_timer = self.state_timer - dtime - if self.state_timer <= 0 then - self.state_timer = math.random(4,10) + math.random() - self.state = jump_state_list_wandering[math.random(1,#jump_state_list_wandering)] - end -end - --- states are executed here -local function jump_state_execution(self, dtime) - local node_in_front_of = mobs.jump_check(self) - local pos = self.object:get_pos() - local collisionbox = self.object:get_properties().collisionbox - --get the center of the mob - pos.y = pos.y + (collisionbox[2] + collisionbox[5] / 2) - local current_node = minetest_get_node(pos).name - - local float_now = false - - --recheck if in water or lava - if minetest_get_item_group(current_node, "water") ~= 0 or minetest_get_item_group(current_node, "lava") ~= 0 then - float_now = true - end - - if self.state == "stand" then - - --do animation - mobs.set_mob_animation(self, "stand") - - --set the velocity of the mob - mobs.set_velocity(self,0) - - mobs.lock_yaw(self) - - elseif self.state == "jump" then - - self.walk_timer = self.walk_timer - dtime - - --reset the jump timer - if self.walk_timer <= 0 then - - --re-randomize the jump timer - self.walk_timer = math.random(1,6) + math.random() - - --set the mob into a random direction - self.yaw = (math.random() * (math.pi * 2)) - end - - --do animation - mobs.set_mob_animation(self, "walk") - - --enable rotation locking - mobs.movement_rotation_lock(self) - - --jumping mobs are more loosey goosey - if node_in_front_of == 1 then - quick_rotate(self,dtime) - end - - --only move forward if path is clear - mobs.jump_move(self,self.walk_velocity) - - elseif self.state == "run" then - print("run") - elseif self.state == "attack" then - print("attack") - end - if float_now then - mobs.float(self) - end -end - - - - ---[[ -___ ___ _ _ _ -| \/ | (_) | | (_) -| . . | __ _ _ _ __ | | ___ __ _ _ ___ -| |\/| |/ _` | | '_ \ | | / _ \ / _` | |/ __| -| | | | (_| | | | | | | |___| (_) | (_| | | (__ -\_| |_/\__,_|_|_| |_| \_____/\___/ \__, |_|\___| - __/ | - |___/ -]]-- - ---the main loop -function mobs.mob_step(self, dtime) - - --do not continue if non-existent - if not self or not self.object or not self.object:get_luaentity() then - self.object:remove() - return false - end - - - --DEBUG TIME! - --REMEMBER TO MOVE THIS AFTER DEATH CHECK - - --if self.has_head then - -- mobs.do_head_logic(self,dtime) - --end - - - - --if true then--DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG - -- return - --end - - --despawn mechanism - --don't despawned tamed or bred mobs - if not self.tamed and not self.bred then - self.lifetimer = self.lifetimer - dtime - if self.lifetimer <= 0 then - self.lifetimer = self.lifetimer_reset - if not mobs.check_for_player_within_area(self, 64) then - --print("removing in MAIN LOGIC!") - self.object:remove() - return - end - end - end - - --color modifier which coincides with the pause_timer - if self.old_health and self.health < self.old_health then - self.object:set_texture_mod("^[colorize:red:120") - --fix double death sound - if self.health > 0 then - mobs.play_sound(self,"damage") - end - end - self.old_health = self.health - - --do death logic (animation, poof, explosion, etc) - if self.health <= 0 or self.dead then - --play death sound once - if not self.played_death_sound then - self.dead = true - mobs.play_sound(self,"death") - self.played_death_sound = true - end - - mobs.death_logic(self, dtime) - - --this is here because the mob must continue to move - --while stunned before coming to a complete halt even during - --the death tilt - if self.pause_timer > 0 then - self.pause_timer = self.pause_timer - dtime - --perfectly reset pause_timer - if self.pause_timer < 0 then - self.pause_timer = 0 - end - end - - return - end - - mobs.random_sound_handling(self,dtime) - - --mobs drowning mechanic - if not self.breathes_in_water then - - local pos = self.object:get_pos() - - pos.y = pos.y + self.eye_height - - local node = minetest_get_node(pos).name - - if minetest_get_item_group(node, "water") ~= 0 then - self.breath = self.breath - dtime - - --reset breath when drowning - if self.breath <= 0 then - self.health = self.health - 4 - self.breath = 1 - self.pause_timer = 0.5 - end - - elseif self.breath < self.breath_max then - self.breath = self.breath + dtime - --clean timer reset - if self.breath > self.breath_max then - self.breath = self.breath_max - end - end - end - - --set mobs on fire when burned by sunlight - if self.ignited_by_sunlight then - local pos = self.object:get_pos() - pos.y = pos.y + 0.1 - - if self.burn_timer > 0 then - self.burn_timer = self.burn_timer - dtime - - if self.burn_timer <= 0 then - self.health = self.health - 4 - self.burn_timer = 0 - end - end - - if self.burn_timer == 0 then - local light_current, light_day = minetest_get_node_light(pos), minetest_get_node_light(pos, 0.5) - if light_current and light_day and light_current > 12 and light_day == 15 then - mcl_burning.set_on_fire(self.object, 1) - self.burn_timer = 1 --1.7 seconds - self.pause_timer = 0.4 - end - end - end - - --baby grows up - if self.baby then - --print(self.grow_up_timer) - --catch missing timer - if not self.grow_up_timer then - self.grow_up_timer = self.grow_up_goal - end - - self.grow_up_timer = self.grow_up_timer - dtime - - --baby grows up! - if self.grow_up_timer <= 0 then - self.grow_up_timer = 0 - mobs.baby_grow_up(self) - end - end - - --do custom mob instructions - if self.do_custom then - -- when false skip going any further - if self.do_custom(self, dtime) == false then - --this needs to be here or the mob becomes immortal - if self.pause_timer > 0 then - self.pause_timer = self.pause_timer - dtime - --perfectly reset pause_timer - if self.pause_timer <= 0 then - self.pause_timer = 0 - self.object:set_texture_mod("") - end - end - --this overrides internal lua collision detection - return - end - end - - local attacking = nil - - --scan for players within eyesight - if self.hostile then - --true for line_of_sight is debug - attacking = mobs.detect_closest_player_within_radius(self,true,self.view_range,self.eye_height) - - --go get the closest player - if attacking then - - self.memory = 6 --6 seconds of memory - - --set initial punch timer - if self.attacking == nil then - if self.attack_type == "punch" then - self.punch_timer = -1 - end - end - self.attacking = attacking - - --no player in area - elseif self.memory > 0 then - --try to remember - self.memory = self.memory - dtime - --get if memory player is within viewing range - if self.attacking and self.attacking:is_player() then - local distance = vector.distance(self.object:get_pos(), self.attacking:get_pos()) - if distance > self.view_range then - self.memory = 0 - end - --out of viewing range, forget em - else - self.memory = 0 - end - - if self.memory <= 0 then - - --reset states when coming out of hostile state - if self.attacking ~= nil then - self.state_timer = -1 - end - - self.attacking = nil - self.memory = 0 - end - end - end - - --count down hostile cooldown timer when no players in range - if self.neutral and self.hostile and not attacking and self.hostile_cooldown_timer then - - self.hostile_cooldown_timer = self.hostile_cooldown_timer - dtime - - if self.hostile_cooldown_timer <= 0 then - self.hostile = false - self.hostile_cooldown_timer = 0 - end - end - - --mob is stunned after being hit - if self.pause_timer > 0 then - self.pause_timer = self.pause_timer - dtime - --don't break eye contact - if self.hostile and self.attacking then - mobs.set_yaw_while_attacking(self) - end - - --perfectly reset pause_timer - if self.pause_timer <= 0 then - self.pause_timer = 0 - self.object:set_texture_mod("") - end - - --stop walking mobs from falling through the water - if not self.jump_only and not self.swim and not self.fly then - local pos = self.object:get_pos() - local collisionbox = self.object:get_properties().collisionbox - --get the center of the mob - pos.y = pos.y + (collisionbox[2] + collisionbox[5] / 2) - local current_node = minetest_get_node(pos).name - - --recheck if in water or lava - if minetest_get_item_group(current_node, "water") ~= 0 or minetest_get_item_group(current_node, "lava") ~= 0 then - mobs.float(self) - end - end - - --stop projectile mobs from being completely disabled while stunned - if self.projectile_timer and self.projectile_timer > 0.01 then - self.projectile_timer = self.projectile_timer - dtime - if self.projectile_timer < 0.01 then - self.projectile_timer = 0.01 - end - end - - return -- don't allow collision detection - --do normal ai - else - --jump only (like slimes) - if self.jump_only then - jump_state_switch(self, dtime) - jump_state_execution(self, dtime) - --swimming - elseif self.swim then - swim_state_switch(self, dtime) - swim_state_execution(self, dtime) - --flying - elseif self.fly then - fly_state_switch(self, dtime) - fly_state_execution(self,dtime) - --regular mobs that walk around - else - land_state_switch(self, dtime) - land_state_execution(self,dtime) - end - end - - --do not continue if non-existent - if not self or not self.object or not self.object:get_luaentity() then - self.object:remove() - return false - end - - --make it so mobs do not glitch out when walking around/jumping - mobs.swap_auto_step_height_adjust(self) - - - -- can mob be pushed, if so calculate direction -- do this last (overrides everything) - if self.pushable then - mobs.collision(self) - end - - --overrides absolutely everything - --mobs get stuck in cobwebs like players - if not self.ignores_cobwebs then - local pos = self.object:get_pos() - local node = pos and minetest_get_node(pos).name - if node == "mcl_core:cobweb" then - --fight the rest of the api - if self.object:get_acceleration().y ~= 0 then - self.object:set_acceleration(vector.new(0,0,0)) - end - mobs.stick_in_cobweb(self) - self.was_stuck_in_cobweb = true - else - --do not override other functions - if self.was_stuck_in_cobweb == true then - --return the mob back to normal - self.was_stuck_in_cobweb = nil - if self.object:get_acceleration().y == 0 and not self.swim and not self.fly then - self.object:set_acceleration(vector.new(0,-self.gravity,0)) - end - end - end - end - - self.old_velocity = self.object:get_velocity() - self.old_pos = self.object:get_pos() -end diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua deleted file mode 100644 index cea6d838b..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/animation.lua +++ /dev/null @@ -1,257 +0,0 @@ -local math = math -local vector = vector - -local HALF_PI = math.pi/2 - - -local vector_direction = vector.direction -local vector_distance = vector.distance -local vector_new = vector.new - -local minetest_dir_to_yaw = minetest.dir_to_yaw - --- set defined animation -mobs.set_mob_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 - - - if (not self.animation[anim .. "_start"] or not self.animation[anim .. "_end"]) then - return - end - - --animations break if they are constantly set - --so we put this return gate to check if it is - --already at the animation we are trying to implement - if self.current_animation == anim then - return - end - - 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) - - self.current_animation = anim -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=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 - - ---this allows auto facedir rotation while making it so mobs ---don't look like wet noodles flopping around -mobs.movement_rotation_lock = function(self) - local current_engine_yaw = self.object:get_yaw() - local current_lua_yaw = self.yaw - - if current_engine_yaw > math.pi * 2 then - current_engine_yaw = current_engine_yaw - (math.pi * 2) - end - - if math.abs(current_engine_yaw - current_lua_yaw) <= 0.05 and self.object:get_properties().automatic_face_movement_dir then - self.object:set_properties{automatic_face_movement_dir = false} - elseif math.abs(current_engine_yaw - current_lua_yaw) > 0.05 and self.object:get_properties().automatic_face_movement_dir == false then - self.object:set_properties{automatic_face_movement_dir = self.rotate} - end -end - - ---this is used when a mob is chasing a player -mobs.set_yaw_while_attacking = function(self) - - if self.object:get_properties().automatic_face_movement_dir then - self.object:set_properties{automatic_face_movement_dir = false} - end - - --turn positions into pseudo 2d vectors - local pos1 = self.object:get_pos() - pos1.y = 0 - - local pos2 = self.attacking:get_pos() - pos2.y = 0 - - local new_direction = vector_direction(pos1,pos2) - local new_yaw = minetest_dir_to_yaw(new_direction) - - self.object:set_yaw(new_yaw) - self.yaw = new_yaw -end - ---this is used to unlock a mob's yaw after attacking -mobs.unlock_yaw = function(self) - if self.object:get_properties().automatic_face_movement_dir == false then - self.object:set_properties{automatic_face_movement_dir = self.rotate} - end -end - ---this is used to lock a mob's yaw when they're standing -mobs.lock_yaw = function(self) - if self.object:get_properties().automatic_face_movement_dir then - self.object:set_properties{automatic_face_movement_dir = false} - end -end - - -local calculate_pitch = function(self) - local pos = self.object:get_pos() - local pos2 = self.old_pos - - if pos == nil or pos2 == nil then - return false - end - - return minetest_dir_to_yaw(vector_new(vector_distance(vector_new(pos.x,0,pos.z),vector_new(pos2.x,0,pos2.z)),0,pos.y - pos2.y)) + HALF_PI -end - ---this is a helper function used to make mobs pitch rotation dynamically flow when flying/swimming -mobs.set_dynamic_pitch = function(self) - local pitch = calculate_pitch(self) - - if not pitch then - return - end - - local current_rotation = self.object:get_rotation() - - current_rotation.x = pitch - - self.object:set_rotation(current_rotation) - - self.pitch_switch = "dynamic" -end - ---this is a helper function used to make mobs pitch rotation reset when flying/swimming -mobs.set_static_pitch = function(self) - - if self.pitch_switch == "static" then - return - end - - local current_rotation = self.object:get_rotation() - - current_rotation.x = 0 - - self.object:set_rotation(current_rotation) - self.pitch_switch = "static" -end - ---this is a helper function for mobs explosion animation -mobs.handle_explosion_animation = function(self) - - --secondary catch-all - if not self.explosion_animation then - self.explosion_animation = 0 - end - - --the timer works from 0 for sense of a 0 based counting - --but this just bumps it up so it's usable in here - local explosion_timer_adjust = self.explosion_animation + 1 - - - local visual_size_modified = table.copy(self.visual_size_origin) - - visual_size_modified.x = visual_size_modified.x * (explosion_timer_adjust ^ 3) - visual_size_modified.y = visual_size_modified.y * explosion_timer_adjust - - self.object:set_properties({visual_size = visual_size_modified}) -end - - ---this is used when a mob is following player -mobs.set_yaw_while_following = function(self) - - if self.object:get_properties().automatic_face_movement_dir then - self.object:set_properties{automatic_face_movement_dir = false} - end - - --turn positions into pseudo 2d vectors - local pos1 = self.object:get_pos() - pos1.y = 0 - - local pos2 = self.following_person:get_pos() - pos2.y = 0 - - local new_direction = vector_direction(pos1,pos2) - local new_yaw = minetest_dir_to_yaw(new_direction) - - self.object:set_yaw(new_yaw) - self.yaw = new_yaw -end - ---this is used for when mobs breed -mobs.set_yaw_while_breeding = function(self, mate) - - if self.object:get_properties().automatic_face_movement_dir then - self.object:set_properties{automatic_face_movement_dir = false} - end - - --turn positions into pseudo 2d vectors - local pos1 = self.object:get_pos() - pos1.y = 0 - - local pos2 = mate:get_pos() - pos2.y = 0 - - local new_direction = vector_direction(pos1,pos2) - local new_yaw = minetest_dir_to_yaw(new_direction) - - self.object:set_yaw(new_yaw) - self.yaw = new_yaw -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/attack_type_instructions.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/attack_type_instructions.lua deleted file mode 100644 index f5d33def4..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/attack_type_instructions.lua +++ /dev/null @@ -1,348 +0,0 @@ -local vector_direction = vector.direction ---local minetest_dir_to_yaw = minetest.dir_to_yaw -local vector_distance = vector.distance -local vector_multiply = vector.multiply -local math_random = math.random - ---[[ - _ _ _ _ -| | | | | | | | -| | | | __ _ _ __ __| | | | -| | | | / _` | '_ \ / _` | | | -|_| | |___| (_| | | | | (_| | |_| -(_) \_____/\__,_|_| |_|\__,_| (_) -]]-- - - - ---[[ - _____ _ _ -| ___| | | | | -| |____ ___ __ | | ___ __| | ___ -| __\ \/ / '_ \| |/ _ \ / _` |/ _ \ -| |___> <| |_) | | (_) | (_| | __/ -\____/_/\_\ .__/|_|\___/ \__,_|\___| - | | - |_| -]]-- - -mobs.explode_attack_walk = function(self,dtime) - - --this needs an exception - if self.attacking == nil or not self.attacking:is_player() then - self.attacking = nil - return - end - - mobs.set_yaw_while_attacking(self) - - local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos()) - - --make mob walk up to player within 2 nodes distance then start exploding - if distance_from_attacking >= self.reach and - --don't allow explosion to cancel unless out of the reach boundary - not (self.explosion_animation ~= nil and self.explosion_animation > 0 and distance_from_attacking <= self.defuse_reach) then - - mobs.set_velocity(self, self.run_velocity) - mobs.set_mob_animation(self,"run") - - mobs.reverse_explosion_animation(self,dtime) - else - mobs.set_velocity(self,0) - - --this is the only way I can reference this without dumping extra data on all mobs - if not self.explosion_animation then - self.explosion_animation = 0 - end - - --play ignite sound - if self.explosion_animation == 0 then - mobs.play_sound(self,"attack") - end - - mobs.set_mob_animation(self,"stand") - - mobs.handle_explosion_animation(self) - - self.explosion_animation = self.explosion_animation + (dtime/2.5) - end - - --make explosive mobs jump - --check for nodes to jump over - --explosive mobs will just ride against walls for now - local node_in_front_of = mobs.jump_check(self) - if node_in_front_of == 1 then - mobs.jump(self) - end - - --do biggening explosion thing - if self.explosion_animation and self.explosion_animation > self.explosion_timer then - mcl_explosions.explode(self.object:get_pos(), self.explosion_strength,{ drop_chance = 1.0 }) - self.object:remove() - end -end - - ---this is a small helper function to make working with explosion animations easier -mobs.reverse_explosion_animation = function(self,dtime) - - --if explosion animation was greater than 0 then reverse it - if self.explosion_animation ~= nil and self.explosion_animation > 0 then - self.explosion_animation = self.explosion_animation - dtime - if self.explosion_animation < 0 then - self.explosion_animation = 0 - end - end - - mobs.handle_explosion_animation(self) -end - - - - ---[[ -______ _ -| ___ \ | | -| |_/ / _ _ __ ___| |__ -| __/ | | | '_ \ / __| '_ \ -| | | |_| | | | | (__| | | | -\_| \__,_|_| |_|\___|_| |_| -]]-- - - - -mobs.punch_attack_walk = function(self,dtime) - --this needs an exception - if self.attacking == nil or not self.attacking:is_player() then - self.attacking = nil - return - end - - local distance_from_attacking = mobs.get_2d_distance(self.object:get_pos(), self.attacking:get_pos()) - - if distance_from_attacking >= self.minimum_follow_distance then - mobs.set_velocity(self, self.run_velocity) - mobs.set_mob_animation(self, "run") - else - mobs.set_velocity(self, 0) - mobs.set_mob_animation(self, "stand") - end - - mobs.set_yaw_while_attacking(self) - - --make punchy mobs jump - --check for nodes to jump over - --explosive mobs will just ride against walls for now - local node_in_front_of = mobs.jump_check(self) - - if node_in_front_of == 1 then - mobs.jump(self) - end - - --mobs that can climb over stuff - if self.always_climb and node_in_front_of > 0 then - mobs.climb(self) - end - - - --auto reset punch_timer - if not self.punch_timer then - self.punch_timer = 0 - end - - if self.punch_timer > 0 then - self.punch_timer = self.punch_timer - dtime - end -end - -mobs.punch_attack = function(self) - - self.attacking:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = self.damage} - }, nil) - - self.punch_timer = self.punch_timer_cooloff - - - --knockback - local pos1 = self.object:get_pos() - pos1.y = 0 - local pos2 = self.attacking:get_pos() - pos2.y = 0 - local dir = vector_direction(pos1,pos2) - - dir = vector_multiply(dir,3) - - if self.attacking:get_velocity().y <= 1 then - dir.y = 5 - end - - self.attacking:add_velocity(dir) -end - - - - ---[[ -______ _ _ _ _ -| ___ \ (_) | | (_) | -| |_/ / __ ___ _ ___ ___| |_ _| | ___ -| __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \ -| | | | | (_) | | __/ (__| |_| | | __/ -\_| |_| \___/| |\___|\___|\__|_|_|\___| - _/ | - |__/ -]]-- - - -mobs.projectile_attack_walk = function(self,dtime) - - --this needs an exception - if self.attacking == nil or not self.attacking:is_player() then - self.attacking = nil - return - end - - mobs.set_yaw_while_attacking(self) - - local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos()) - - - if distance_from_attacking >= self.reach then - mobs.set_velocity(self, self.run_velocity) - mobs.set_mob_animation(self,"run") - else - mobs.set_velocity(self,0) - mobs.set_mob_animation(self,"stand") - end - - --do this to not load data into other mobs - if not self.projectile_timer then - self.projectile_timer = math_random(self.projectile_cooldown_min, self.projectile_cooldown_max) - end - - --run projectile timer - if self.projectile_timer > 0 then - self.projectile_timer = self.projectile_timer - dtime - - --shoot - if self.projectile_timer <= 0 then - --reset timer - self.projectile_timer = math_random(self.projectile_cooldown_min, self.projectile_cooldown_max) - mobs.shoot_projectile(self) - end - end - - --make shooty mobs jump - --check for nodes to jump over - --explosive mobs will just ride against walls for now - local node_in_front_of = mobs.jump_check(self) - if node_in_front_of == 1 then - mobs.jump(self) - end - -end - - - - - - - - - ---[[ - _ ______ _ _ -| | | ___| | | | -| | | |_ | |_ _ | | -| | | _| | | | | | | | -|_| | | | | |_| | |_| -(_) \_| |_|\__, | (_) - __/ | - |___/ -]]-- - - - - ---[[ -______ _ _ _ _ -| ___ \ (_) | | (_) | -| |_/ / __ ___ _ ___ ___| |_ _| | ___ -| __/ '__/ _ \| |/ _ \/ __| __| | |/ _ \ -| | | | | (_) | | __/ (__| |_| | | __/ -\_| |_| \___/| |\___|\___|\__|_|_|\___| - _/ | - |__/ -]]-- - -local random_pitch_multiplier = {-1,1} - -mobs.projectile_attack_fly = function(self, dtime) - --this needs an exception - if self.attacking == nil or not self.attacking:is_player() then - self.attacking = nil - return - end - - --this is specifically for random ghast movement - if self.fly_random_while_attack then - - --enable rotation locking - mobs.movement_rotation_lock(self) - - self.walk_timer = self.walk_timer - dtime - - --reset the walk timer - if self.walk_timer <= 0 then - --re-randomize the walk timer - self.walk_timer = math.random(1,6) + math.random() - --set the mob into a random direction - self.yaw = (math_random() * (math.pi * 2)) - --create a truly random pitch, since there is no easy access to pitch math that I can find - self.pitch = math_random() * math.random(1,3) * random_pitch_multiplier[math_random(1,2)] - end - - mobs.set_fly_velocity(self, self.run_velocity) - - else - - mobs.set_yaw_while_attacking(self) - - local distance_from_attacking = vector_distance(self.object:get_pos(), self.attacking:get_pos()) - - if distance_from_attacking >= self.reach then - mobs.set_pitch_while_attacking(self) - mobs.set_fly_velocity(self, self.run_velocity) - mobs.set_mob_animation(self,"run") - else - mobs.set_pitch_while_attacking(self) - mobs.set_fly_velocity(self, 0) - mobs.set_mob_animation(self,"stand") - end - end - - - --do this to not load data into other mobs - if not self.projectile_timer then - self.projectile_timer = math_random(self.projectile_cooldown_min, self.projectile_cooldown_max) - end - - --run projectile timer - if self.projectile_timer > 0 then - self.projectile_timer = self.projectile_timer - dtime - - --shoot - if self.projectile_timer <= 0 then - - if self.fly_random_while_attack then - mobs.set_yaw_while_attacking(self) - self.walk_timer = 0 - end - --reset timer - self.projectile_timer = math_random(self.projectile_cooldown_min, self.projectile_cooldown_max) - mobs.shoot_projectile(self) - end - end -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/breeding.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/breeding.lua deleted file mode 100644 index c50fb6300..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/breeding.lua +++ /dev/null @@ -1,179 +0,0 @@ -local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius - -local vector = vector - ---check to see if someone nearby has some tasty food -mobs.check_following = function(self) -- returns true or false - --ignore - if not self.follow then - self.following_person = nil - return false - end - - --hey look, this thing works for passive mobs too! - local follower = mobs.detect_closest_player_within_radius(self,true,self.view_range,self.eye_height) - - --check if the follower is a player incase they log out - if follower and follower:is_player() then - local stack = follower:get_wielded_item() - --safety check - if not stack then - self.following_person = nil - return false - end - - local item_name = stack:get_name() - --all checks have passed, that guy has some good looking food - if item_name == self.follow then - self.following_person = follower - return true - end - end - - --everything failed - self.following_person = nil - return false -end - ---a function which attempts to make mobs enter ---the breeding state -mobs.enter_breed_state = function(self,clicker) - - --do not breed if baby - if self.baby then - return false - end - - --do not do anything if looking for mate or - --if cooling off from breeding - if self.breed_lookout_timer > 0 or self.breed_timer > 0 then - return false - end - - --if this is caught, that means something has gone - --seriously wrong - if not clicker or not clicker:is_player() then - return false - end - - local stack = clicker:get_wielded_item() - --safety check - if not stack then - return false - end - - local item_name = stack:get_name() - --all checks have passed, that guy has some good looking food - if item_name == self.follow then - if not minetest.is_creative_enabled(clicker:get_player_name()) then - stack:take_item() - clicker:set_wielded_item(stack) - end - self.breed_lookout_timer = self.breed_lookout_timer_goal - self.bred = true - mobs.play_sound_specific(self,"mobs_mc_animal_eat_generic") - return true - end - - --everything failed - return false -end - - ---find the closest mate in the area -mobs.look_for_mate = function(self) - - local pos1 = self.object:get_pos() - pos1.y = pos1.y + self.eye_height - - local mates_in_area = {} - local winner_mate = nil - local mates_detected = 0 - local radius = self.view_range - - --get mates in radius - for _,mate in pairs(minetest_get_objects_inside_radius(pos1, radius)) do - - --look for a breeding mate - if mate and mate:get_luaentity() - and mate:get_luaentity()._cmi_is_mob - and mate:get_luaentity().name == self.name - and mate:get_luaentity().breed_lookout_timer > 0 - and mate:get_luaentity() ~= self then - - local pos2 = mate:get_pos() - - local distance = vector.distance(pos1,pos2) - - if distance <= radius then - if minetest.line_of_sight then - --must add eye height or stuff breaks randomly because of - --seethrough nodes being a blocker (like grass) - if minetest.line_of_sight( - vector.new(pos1.x, pos1.y, pos1.z), - vector.new(pos2.x, pos2.y + mate:get_properties().eye_height, pos2.z) - ) then - mates_detected = mates_detected + 1 - mates_in_area[mate] = distance - end - else - mates_detected = mates_detected + 1 - mates_in_area[mate] = distance - end - end - end - end - - - --return if there's no one near by - if mates_detected <= 0 then --handle negative numbers for some crazy error that could possibly happen - return nil - end - - --do a default radius max - local shortest_distance = radius + 1 - - --sort through mates and find the closest mate - for mate,distance in pairs(mates_in_area) do - if distance < shortest_distance then - shortest_distance = distance - winner_mate = mate - end - end - return winner_mate -end - ---make the baby grow up -mobs.baby_grow_up = function(self) - self.baby = nil - self.visual_size = self.backup_visual_size - self.collisionbox = self.backup_collisionbox - self.selectionbox = self.backup_selectionbox - self.object:set_properties(self) -end - ---makes the baby grow up faster with diminishing returns -mobs.make_baby_grow_faster = function(self,clicker) - if clicker and clicker:is_player() then - local stack = clicker:get_wielded_item() - --safety check - if not stack then - return false - end - - local item_name = stack:get_name() - --all checks have passed, that guy has some good looking food - if item_name == self.follow then - self.grow_up_timer = self.grow_up_timer - (self.grow_up_timer * 0.10) --take 10 percent off - diminishing returns - - if not minetest.is_creative_enabled(clicker:get_player_name()) then - stack:take_item() - clicker:set_wielded_item(stack) - end - - mobs.play_sound_specific(self,"mobs_mc_animal_eat_generic") - return true - end - end - return false -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/collision.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/collision.lua deleted file mode 100644 index ed9aec6cd..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/collision.lua +++ /dev/null @@ -1,135 +0,0 @@ -local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius - -local math_random = math.random -local vector_multiply = vector.multiply - -local vector_direction = vector.direction - -local integer_test = {-1,1} - -mobs.collision = function(self) - local pos = self.object:get_pos() - - if not self or not self.object or not self.object:get_luaentity() then - return - end - - --do collision detection from the base of the mob - local collisionbox = self.object:get_properties().collisionbox - - pos.y = pos.y + collisionbox[2] - - local collision_boundary = collisionbox[4] - - local radius = collision_boundary - - if collisionbox[5] > collision_boundary then - radius = collisionbox[5] - end - - local collision_count = 0 - - - local check_for_attack = false - - if self.attack_type == "punch" and self.hostile and self.attacking then - check_for_attack = true - end - - for _,object in ipairs(minetest_get_objects_inside_radius(pos, radius*1.25)) do - if object and object ~= self.object and (object:is_player() or (object:get_luaentity() and object:get_luaentity()._cmi_is_mob == true and object:get_luaentity().health > 0)) and - --don't collide with rider, rider don't collide with thing - (not object:get_attach() or (object:get_attach() and object:get_attach() ~= self.object)) and - (not self.object:get_attach() or (self.object:get_attach() and self.object:get_attach() ~= object)) then - --stop infinite loop - collision_count = collision_count + 1 - --mob cramming - if collision_count > 30 then - self.health = -20 - break - end - - local pos2 = object:get_pos() - - local object_collisionbox = object:get_properties().collisionbox - - pos2.y = pos2.y + object_collisionbox[2] - - local object_collision_boundary = object_collisionbox[4] - - - --this is checking the difference of the object collided with's possision - --if positive top of other object is inside (y axis) of current object - local y_base_diff = (pos2.y + object_collisionbox[5]) - pos.y - - local y_top_diff = (pos.y + collisionbox[5]) - pos2.y - - - local distance = vector.distance(vector.new(pos.x,0,pos.z),vector.new(pos2.x,0,pos2.z)) - - if distance <= collision_boundary + object_collision_boundary and y_base_diff >= 0 and y_top_diff >= 0 then - - local dir = vector.direction(pos,pos2) - - dir.y = 0 - - --eliminate mob being stuck in corners - if dir.x == 0 and dir.z == 0 then - --slightly adjust mob position to prevent equal length - --corner/wall sticking - dir.x = dir.x + ((math_random()/10)*integer_test[math.random(1,2)]) - dir.z = dir.z + ((math_random()/10)*integer_test[math.random(1,2)]) - end - - local velocity = dir - - --0.5 is the max force multiplier - local force = 0.5 - (0.5 * distance / (collision_boundary + object_collision_boundary)) - - local vel1 = vector.multiply(velocity, -1.5) - local vel2 = vector.multiply(velocity, 1.5) - - vel1 = vector.multiply(vel1, force * 10) - vel2 = vector.multiply(vel2, force) - - if object:is_player() then - vel2 = vector_multiply(vel2, 2.5) - - --integrate mob punching into collision detection - if check_for_attack and self.punch_timer <= 0 then - if object == self.attacking then - mobs.punch_attack(self) - end - end - end - self.object:add_velocity(vel1) - object:add_velocity(vel2) - end - end - end -end - - ---this is used for arrow collisions -mobs.arrow_hit = function(self, player) - player:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = self._damage} - }, nil) - - - --knockback - local pos1 = self.object:get_pos() - pos1.y = 0 - local pos2 = player:get_pos() - pos2.y = 0 - local dir = vector_direction(pos1,pos2) - - dir = vector_multiply(dir,3) - - if player:get_velocity().y <= 1 then - dir.y = 5 - end - - player:add_velocity(dir) -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua deleted file mode 100644 index 45e46d3db..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/death_logic.lua +++ /dev/null @@ -1,158 +0,0 @@ -local minetest_add_item = minetest.add_item ---local minetest_sound_play = minetest.sound_play - -local math_pi = math.pi -local math_random = math.random -local math_floor = math.floor -local HALF_PI = math_pi / 2 - -local vector_new = vector.new - - --- drop items -local item_drop = function(self, cooked, looting_level) - - 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 - local pos = self.object:get_pos() - - 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 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 - - -- 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 - 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 - - -mobs.death_logic = function(self, dtime) - - --stop crashing game when object is nil - if not self or not self.object or not self.object:get_luaentity() then - return - end - - self.death_animation_timer = self.death_animation_timer + dtime - - --get all attached entities and sort through them - local attached_entities = self.object:get_children() - if #attached_entities > 0 then - for _,entity in pairs(attached_entities) do - --kick the player off - if entity:is_player() then - mobs.detach(entity) - --kick mobs off - --if there is scaling issues, this needs an additional check - else - entity:set_detach() - end - end - end - - --stop mob from getting in the way of other mobs you're fighting - if self.object:get_properties().pointable then - self.object:set_properties({pointable = false}) - end - - --the final POOF of a mob despawning - if self.death_animation_timer >= 1.25 then - item_drop(self,false,1) - mobs.death_effect(self) - mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max)) - self.object:remove() - return - end - - --I'm sure there's a more efficient way to do this - --but this is the easiest, easier to work with 1 variable synced - --this is also not smooth - local death_animation_roll = self.death_animation_timer * 2 -- * 2 to make it faster - if death_animation_roll > 1 then - death_animation_roll = 1 - end - - local rot = self.object:get_rotation() --(no pun intended) - - rot.z = death_animation_roll * HALF_PI - - self.object:set_rotation(rot) - - mobs.set_mob_animation(self,"stand", true) - - - --flying and swimming mobs just fall down - if self.fly or self.swim then - if self.object:get_acceleration().y ~= -self.gravity then - self.object:set_acceleration(vector_new(0,-self.gravity,0)) - end - end - - --when landing allow mob to slow down and just fall if in air - if self.pause_timer <= 0 then - mobs.set_velocity(self,0) - end -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua deleted file mode 100644 index 5c431135e..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua +++ /dev/null @@ -1,250 +0,0 @@ -local minetest_line_of_sight = minetest.line_of_sight ---local minetest_dir_to_yaw = minetest.dir_to_yaw -local minetest_yaw_to_dir = minetest.yaw_to_dir -local minetest_get_node = minetest.get_node -local minetest_get_item_group = minetest.get_item_group -local minetest_get_objects_inside_radius = minetest.get_objects_inside_radius -local minetest_get_node_or_nil = minetest.get_node_or_nil -local minetest_registered_nodes = minetest.registered_nodes -local minetest_get_connected_players = minetest.get_connected_players - -local vector_new = vector.new -local vector_add = vector.add -local vector_multiply = vector.multiply -local vector_distance = vector.distance - -local table_copy = table.copy - -local math_abs = math.abs - --- default function when mobs are blown up with TNT ---[[local function do_tnt(obj, damage) - obj.object:punch(obj.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = damage}, - }, nil) - return false, true, {} -end]] - ---a fast function to be able to detect only players without using objects_in_radius -mobs.detect_closest_player_within_radius = function(self, line_of_sight, radius, object_height_adder) - local pos1 = self.object:get_pos() - local players_in_area = {} - local winner_player = nil - local players_detected = 0 - - --get players in radius - for _,player in pairs(minetest.get_connected_players()) do - if player and player:get_hp() > 0 then - - local pos2 = player:get_pos() - - local distance = vector_distance(pos1,pos2) - - if distance <= radius then - if line_of_sight then - --must add eye height or stuff breaks randomly because of - --seethrough nodes being a blocker (like grass) - if minetest_line_of_sight( - vector_new(pos1.x, pos1.y + object_height_adder, pos1.z), - vector_new(pos2.x, pos2.y + player:get_properties().eye_height, pos2.z) - ) then - players_detected = players_detected + 1 - players_in_area[player] = distance - end - else - players_detected = players_detected + 1 - players_in_area[player] = distance - end - end - end - end - - - --return if there's no one near by - if players_detected <= 0 then --handle negative numbers for some crazy error that could possibly happen - return nil - end - - --do a default radius max - local shortest_distance = radius + 1 - - --sort through players and find the closest player - for player,distance in pairs(players_in_area) do - if distance < shortest_distance then - shortest_distance = distance - winner_player = player - end - end - return winner_player -end - - ---check if a mob needs to jump -mobs.jump_check = function(self,dtime) - - local pos = self.object:get_pos() - pos.y = pos.y + 0.1 - local dir = minetest_yaw_to_dir(self.yaw) - - local collisionbox = self.object:get_properties().collisionbox - local radius = collisionbox[4] + 0.5 - - vector_multiply(dir, radius) - - --only jump if there's a node and a non-solid node above it - local test_dir = vector_add(pos,dir) - - local green_flag_1 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") ~= 0 - - test_dir.y = test_dir.y + 1 - - local green_flag_2 = minetest_get_item_group(minetest_get_node(test_dir).name, "solid") == 0 - - if green_flag_1 and green_flag_2 then - --can jump over node - return 1 - elseif green_flag_1 and not green_flag_2 then - --wall in front of mob - return 2 - end - --nothing to jump over - return 0 -end - --- a helper function to quickly turn neutral passive mobs hostile -local turn_hostile = function(self,detected_mob) - --drop in variables for attacking (stops crash) - detected_mob.punch_timer = 0 - --set to hostile - detected_mob.hostile = true - --hostile_cooldown timer is initialized here - detected_mob.hostile_cooldown_timer = detected_mob.hostile_cooldown - --set target to the same - detected_mob.attacking = self.attacking -end - ---allow hostile mobs to signal to other mobs ---to switch from neutal passive to neutral hostile -mobs.group_attack_initialization = function(self) - - --get basic data - local friends_list - - if self.group_attack == true then - friends_list = {self.name} - else - friends_list = table_copy(self.group_attack) - end - - local objects_in_area = minetest_get_objects_inside_radius(self.object:get_pos(), self.view_range) - - --get the player's name - local name = self.attacking:get_player_name() - - --re-use local variable - local detected_mob - - --run through mobs in viewing distance - for _,object in pairs(objects_in_area) do - if object and object:get_luaentity() then - detected_mob = object:get_luaentity() - -- only alert members of same mob or friends - if detected_mob._cmi_is_mob and detected_mob.state ~= "attack" and detected_mob.owner ~= name then - if detected_mob.name == self.name then - turn_hostile(self,detected_mob) - else - for _,id in pairs(friends_list) do - if detected_mob.name == id then - turn_hostile(self,detected_mob) - break - end - end - end - end - - --THIS NEEDS TO BE RE-IMPLEMENTED AS A GLOBAL HIT IN MOB_PUNCH!! - -- have owned mobs attack player threat - --if obj.owner == name and obj.owner_loyal then - -- do_attack(obj, self.object) - --end - end - end -end - --- check if within physical map limits (-30911 to 30927) --- within_limits, wmin, wmax = nil, -30913, 30928 -mobs.within_limits = function(pos, radius) - local wmin, wmax - 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 - 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 - --- get node but use fallback for nil or unknown -mobs.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 - - ---a teleport functoin -mobs.teleport = function(self, target) - if self.do_teleport then - if self.do_teleport(self, target) == false then - return - end - end -end - ---a function used for despawning mobs -mobs.check_for_player_within_area = function(self, radius) - local pos1 = self.object:get_pos() - --get players in radius - for _,player in pairs(minetest_get_connected_players()) do - if player and player:get_hp() > 0 then - local pos2 = player:get_pos() - local distance = vector_distance(pos1,pos2) - if distance < radius then - --found a player - return true - end - end - end - --did not find a player - return false -end - - ---a simple helper function for mobs following -mobs.get_2d_distance = function(pos1,pos2) - pos1.y = 0 - pos2.y = 0 - return vector_distance(pos1, pos2) -end - --- fall damage onto solid ground -mobs.calculate_fall_damage = function(self) - if self.old_velocity and self.old_velocity.y < -7 and self.object:get_velocity().y == 0 then - local vel = self.object:get_velocity() - if vel then - local damage = math_abs(self.old_velocity.y + 7) * 2 - self.pause_timer = 0.4 - self.health = self.health - damage - end - end -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/head_logic.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/head_logic.lua deleted file mode 100644 index 0f5615504..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/head_logic.lua +++ /dev/null @@ -1,98 +0,0 @@ -local math = math -local vector = vector - ---converts yaw to degrees -local degrees = function(yaw) - return yaw*180.0/math.pi -end - -mobs.do_head_logic = function(self,dtime) - - local player = minetest.get_player_by_name("singleplayer") - - local look_at = player:get_pos() - look_at.y = look_at.y + player:get_properties().eye_height - - local pos = self.object:get_pos() - - local body_yaw = self.object:get_yaw() - - local body_dir = minetest.yaw_to_dir(body_yaw) - - pos.y = pos.y + self.head_height_offset - - local head_offset = vector.multiply(body_dir, self.head_direction_offset) - - pos = vector.add(pos, head_offset) - - minetest.add_particle({ - pos = pos, - velocity = {x=0, y=0, z=0}, - acceleration = {x=0, y=0, z=0}, - expirationtime = 0.2, - size = 1, - texture = "default_dirt.png", - }) - - local bone_pos = vector.new(0,0,0) - - --(horizontal) - bone_pos.y = self.head_bone_pos_y - - --(vertical) - bone_pos.z = self.head_bone_pos_z - - --print(yaw) - - --local _, bone_rot = self.object:get_bone_position("head") - - --bone_rot.x = bone_rot.x + (dtime * 10) - --bone_rot.z = bone_rot.z + (dtime * 10) - - local head_yaw = minetest.dir_to_yaw(vector.direction(pos,look_at)) - body_yaw - - if self.reverse_head_yaw then - head_yaw = head_yaw * -1 - end - - --over rotation protection - --stops radians from going out of spec - if head_yaw > math.pi then - head_yaw = head_yaw - (math.pi * 2) - elseif head_yaw < -math.pi then - head_yaw = head_yaw + (math.pi * 2) - end - - - local check_failed = false - --upper check + 90 degrees or upper math.radians (3.14/2) - if head_yaw > math.pi - (math.pi/2) then - head_yaw = 0 - check_failed = true - --lower check - 90 degrees or lower negative math.radians (-3.14/2) - elseif head_yaw < -math.pi + (math.pi/2) then - head_yaw = 0 - check_failed = true - end - - local head_pitch = 0 - - --DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG - --head_yaw = 0 - --DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG - - if not check_failed then - head_pitch = minetest.dir_to_yaw(vector.new(vector.distance(vector.new(pos.x,0,pos.z),vector.new(look_at.x,0,look_at.z)),0,pos.y-look_at.y))+(math.pi/2) - end - - if self.head_pitch_modifier then - head_pitch = head_pitch + self.head_pitch_modifier - end - - if self.swap_y_with_x then - self.object:set_bone_position(self.head_bone, bone_pos, vector.new(degrees(head_pitch),degrees(head_yaw),0)) - else - self.object:set_bone_position(self.head_bone, bone_pos, vector.new(degrees(head_pitch),0,degrees(head_yaw))) - end - --set_bone_position([bone, position, rotation]) -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/interaction.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/interaction.lua deleted file mode 100644 index fa5b31210..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/interaction.lua +++ /dev/null @@ -1,276 +0,0 @@ -local minetest_after = minetest.after -local minetest_sound_play = minetest.sound_play -local minetest_dir_to_yaw = minetest.dir_to_yaw - -local math = math -local vector = vector - -local MAX_MOB_NAME_LENGTH = 30 - -local mod_hunger = minetest.get_modpath("mcl_hunger") - -mobs.feed_tame = function(self) - return nil -end - --- Code to execute before custom on_rightclick handling -local function on_rightclick_prefix(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 - - mobs.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 - --- I have no idea what this does -mobs.create_mob_on_rightclick = function(on_rightclick) - return function(self, clicker) - --don't allow rightclicking dead mobs - if self.health <= 0 then - return - end - local stop = on_rightclick_prefix(self, clicker) - if (not stop) and (on_rightclick) then - on_rightclick(self, clicker) - end - end -end - - --- deal damage and effects when mob punched -mobs.mob_punch = function(self, hitter, tflp, tool_capabilities, dir) - --don't do anything if the mob is already dead - if self.health <= 0 then - return - end - - --neutral passive mobs switch to neutral hostile - if self.neutral then - --drop in variables for attacking (stops crash) - self.attacking = hitter - self.punch_timer = 0 - self.hostile = true - --hostile_cooldown timer is initialized here - self.hostile_cooldown_timer = self.hostile_cooldown - - --initialize the group attack (check for other mobs in area, make them neutral hostile) - if self.group_attack then - mobs.group_attack_initialization(self) - end - end - - --turn skittish mobs away and RUN - if self.skittish then - - self.state = "run" - - self.run_timer = 5 --arbitrary 5 seconds - - local pos1 = self.object:get_pos() - pos1.y = 0 - local pos2 = hitter:get_pos() - pos2.y = 0 - - - local dir = vector.direction(pos2,pos1) - - local yaw = minetest_dir_to_yaw(dir) - - self.yaw = yaw - end - - -- 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 - - --don't do damage until pause timer resets - if self.pause_timer > 0 then - return - end - - -- error checking when mod profiling is enabled - if not tool_capabilities then - minetest.log("warning", "[mobs_mc] Mod profiling enabled, damage not enabled") - return - end - - local is_player = hitter:is_player() - - -- 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 {} - - --calculate damage groups - for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do - damage = damage + (tool_capabilities.damage_groups[group] or 0) * ((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) - --minetest_is_creative_enabled("") ~= true --removed for now - if 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 - - - --if player is falling multiply damage by 1.5 - --critical hit - if hitter:get_velocity().y < 0 then - damage = damage * 1.5 - mobs.critical_effect(self) - end - - - -- 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 - - minetest_sound_play("default_punch", { - object = self.object, - max_hear_distance = 16 - }, true) - - -- do damage - self.health = self.health - damage - - - --0.4 seconds until you can hurt the mob again - self.pause_timer = 0.4 - - --don't do knockback from a rider - for _,obj in pairs(self.object:get_children()) do - if obj == hitter then - return - end - end - - -- knock back effect - local velocity = self.object:get_velocity() - - --2d direction - local pos1 = self.object:get_pos() - pos1.y = 0 - local pos2 = hitter:get_pos() - pos2.y = 0 - - local dir = vector.direction(pos2,pos1) - - local up = 3 - - -- if already in air then dont go up anymore when hit - if velocity.y ~= 0 then - up = 0 - end - - --0.75 for perfect distance to not be too easy, and not be too hard - local multiplier = 0.75 - - -- check if tool already has specific knockback value - local knockback_enchant = mcl_enchanting.get_enchantment(hitter:get_wielded_item(), "knockback") - if knockback_enchant and knockback_enchant > 0 then - multiplier = knockback_enchant + 1 --(starts from 1, 1 would be no change) - end - - --do this to sure you can punch a mob back when - --it's coming for you - if self.hostile then - multiplier = multiplier + 2 - end - dir = vector.multiply(dir,multiplier) - dir.y = up - --add the velocity - self.object:add_velocity(dir) - end -end - ---do internal per mob projectile calculations -mobs.shoot_projectile = function(self) - local pos1 = self.object:get_pos() - --add mob eye height - pos1.y = pos1.y + self.eye_height - - local pos2 = self.attacking:get_pos() - --add player eye height - pos2.y = pos2.y + self.attacking:get_properties().eye_height - - --get direction - local dir = vector.direction(pos1,pos2) - - --call internal shoot_arrow function - self.shoot_arrow(self,pos1,dir) -end - -mobs.update_tag = function(self) - self.object:set_properties({ - nametag = self.nametag, - }) -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/mob_effects.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/mob_effects.lua deleted file mode 100644 index 83df80992..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/mob_effects.lua +++ /dev/null @@ -1,150 +0,0 @@ -local minetest_add_particlespawner = minetest.add_particlespawner - -mobs.death_effect = function(self) - local pos = self.object:get_pos() - --local yaw = self.object:get_yaw() - local collisionbox = self.object:get_properties().collisionbox - - 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]} - end - - minetest_add_particlespawner({ - amount = 50, - time = 0.0001, - minpos = vector.add(pos, min), - maxpos = vector.add(pos, max), - minvel = vector.new(-0.5,0.5,-0.5), - maxvel = vector.new(0.5,1,0.5), - minexptime = 1.1, - maxexptime = 1.5, - minsize = 1, - maxsize = 2, - collisiondetection = false, - vertical = false, - texture = "mcl_particles_mob_death.png", -- this particle looks strange - }) -end - -mobs.critical_effect = function(self) - - local pos = self.object:get_pos() - --local yaw = self.object:get_yaw() - local collisionbox = self.object:get_properties().collisionbox - - 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]} - end - - minetest_add_particlespawner({ - amount = 10, - time = 0.0001, - minpos = vector.add(pos, min), - maxpos = vector.add(pos, max), - minvel = vector.new(-1,1,-1), - maxvel = vector.new(1,3,1), - minexptime = 0.7, - maxexptime = 1, - minsize = 1, - maxsize = 2, - collisiondetection = false, - vertical = false, - texture = "heart.png^[colorize:black:255", - }) -end - ---when feeding a mob -mobs.feed_effect = function(self) - local pos = self.object:get_pos() - --local yaw = self.object:get_yaw() - local collisionbox = self.object:get_properties().collisionbox - - 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]} - end - - minetest_add_particlespawner({ - amount = 10, - time = 0.0001, - minpos = vector.add(pos, min), - maxpos = vector.add(pos, max), - minvel = vector.new(-1,1,-1), - maxvel = vector.new(1,3,1), - minexptime = 0.7, - maxexptime = 1, - minsize = 1, - maxsize = 2, - collisiondetection = false, - vertical = false, - texture = "heart.png^[colorize:gray:255", - }) -end - ---hearts when tamed -mobs.tamed_effect = function(self) - local pos = self.object:get_pos() - --local yaw = self.object:get_yaw() - local collisionbox = self.object:get_properties().collisionbox - - 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]} - end - - minetest_add_particlespawner({ - amount = 30, - time = 0.0001, - minpos = vector.add(pos, min), - maxpos = vector.add(pos, max), - minvel = vector.new(-1,1,-1), - maxvel = vector.new(1,3,1), - minexptime = 0.7, - maxexptime = 1, - minsize = 1, - maxsize = 2, - collisiondetection = false, - vertical = false, - texture = "heart.png", - }) -end - ---hearts when breeding -mobs.breeding_effect = function(self) - local pos = self.object:get_pos() - --local yaw = self.object:get_yaw() - local collisionbox = self.object:get_properties().collisionbox - - 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]} - end - - minetest_add_particlespawner({ - amount = 2, - time = 0.0001, - minpos = vector.add(pos, min), - maxpos = vector.add(pos, max), - minvel = vector.new(-1,1,-1), - maxvel = vector.new(1,3,1), - minexptime = 0.7, - maxexptime = 1, - minsize = 1, - maxsize = 2, - collisiondetection = false, - vertical = false, - texture = "heart.png", - }) -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua deleted file mode 100644 index 893f8eede..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/movement.lua +++ /dev/null @@ -1,387 +0,0 @@ --- localize math functions -local math = math -local HALF_PI = math.pi / 2 -local DOUBLE_PI = math.pi * 2 - --- localize vector functions -local vector = vector - -local minetest_yaw_to_dir = minetest.yaw_to_dir -local minetest_dir_to_yaw = minetest.dir_to_yaw - -local DEFAULT_JUMP_HEIGHT = 5 -local DEFAULT_FLOAT_SPEED = 4 -local DEFAULT_CLIMB_SPEED = 3 - -mobs.stick_in_cobweb = function(self) - local current_velocity = self.object:get_velocity() - - local goal_velocity = vector.multiply(vector.normalize(current_velocity), 0.4) - - goal_velocity.y = -0.5 - - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) - - --smooths out mobs a bit - if vector.length(new_velocity_addition) >= 0.0001 then - self.object:add_velocity(new_velocity_addition) - end -end - ---this is a generic float function -mobs.float = function(self) - - local acceleration = self.object:get_acceleration() - if acceleration and acceleration.y ~= 0 then - self.object:set_acceleration(vector.new(0,0,0)) - else - return - end - - local current_velocity = self.object:get_velocity() - - local goal_velocity = { - x = 0, - y = DEFAULT_FLOAT_SPEED, - z = 0, - } - - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) - - new_velocity_addition.x = 0 - new_velocity_addition.z = 0 - - --smooths out mobs a bit - if vector.length(new_velocity_addition) >= 0.0001 then - self.object:add_velocity(new_velocity_addition) - end -end - ---this is a generic climb function -mobs.climb = function(self) - - local current_velocity = self.object:get_velocity() - - local goal_velocity = { - x = 0, - y = DEFAULT_CLIMB_SPEED, - z = 0, - } - - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) - - new_velocity_addition.x = 0 - new_velocity_addition.z = 0 - - --smooths out mobs a bit - if vector.length(new_velocity_addition) >= 0.0001 then - self.object:add_velocity(new_velocity_addition) - end -end - - - ---[[ - _ _ -| | | | -| | __ _ _ __ __| | -| | / _` | '_ \ / _` | -| |___| (_| | | | | (_| | -\_____/\__,_|_| |_|\__,_| -]] - - --- move mob in facing direction ---this has been modified to be internal ---internal = lua (self.yaw) ---engine = c++ (self.object:get_yaw()) -mobs.set_velocity = function(self, v) - - local yaw = (self.yaw or 0) - - local current_velocity = self.object:get_velocity() - - local goal_velocity = { - x = (math.sin(yaw) * -v), - y = 0, - z = (math.cos(yaw) * v), - } - - - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) - - if vector.length(new_velocity_addition) > vector.length(goal_velocity) then - vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition))) - end - - new_velocity_addition.y = 0 - - --smooths out mobs a bit - if vector.length(new_velocity_addition) >= 0.0001 then - self.object:add_velocity(new_velocity_addition) - end -end - - - --- calculate mob velocity -mobs.get_velocity = function(self) - - local v = self.object:get_velocity() - - v.y = 0 - - if v then - return vector.length(v) - end - - return 0 -end - ---make mobs jump -mobs.jump = function(self, velocity) - - if self.object:get_velocity().y ~= 0 or not self.old_velocity or (self.old_velocity and self.old_velocity.y > 0) then - return - end - - --fallback velocity to allow modularity - velocity = velocity or DEFAULT_JUMP_HEIGHT - - self.object:add_velocity(vector.new(0,velocity,0)) -end - ---make mobs fall slowly -mobs.mob_fall_slow = function(self) - - local current_velocity = self.object:get_velocity() - - local goal_velocity = { - x = 0, - y = -2, - z = 0, - } - - - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) - - new_velocity_addition.x = 0 - new_velocity_addition.z = 0 - - if vector.length(new_velocity_addition) > vector.length(goal_velocity) then - vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition))) - end - - new_velocity_addition.x = 0 - new_velocity_addition.z = 0 - - --smooths out mobs a bit - if vector.length(new_velocity_addition) >= 0.0001 then - self.object:add_velocity(new_velocity_addition) - end - -end - - ---[[ - _____ _ -/ ___| (_) -\ `--.__ ___ _ __ ___ - `--. \ \ /\ / / | '_ ` _ \ -/\__/ /\ V V /| | | | | | | -\____/ \_/\_/ |_|_| |_| |_| -]]-- - - - - ---make mobs flop -mobs.flop = function(self, velocity) - - if self.object:get_velocity().y ~= 0 or not self.old_velocity or (self.old_velocity and self.old_velocity.y > 0) then - return false - end - - mobs.set_velocity(self, 0) - - --fallback velocity to allow modularity - velocity = velocity or DEFAULT_JUMP_HEIGHT - - --create a random direction (2d yaw) - local dir = DOUBLE_PI * math.random() - - --create a random force value - local force = math.random(0,3) + math.random() - - --convert the yaw to a direction vector then multiply it times the force - local final_additional_force = vector.multiply(minetest_yaw_to_dir(dir), force) - - --place in the "flop" velocity to make the mob flop - final_additional_force.y = velocity - - self.object:add_velocity(final_additional_force) - - return true -end - - - --- move mob in facing direction ---this has been modified to be internal ---internal = lua (self.yaw) ---engine = c++ (self.object:get_yaw()) -mobs.set_swim_velocity = function(self, v) - - local yaw = (self.yaw or 0) - local pitch = (self.pitch or 0) - - if v == 0 then - pitch = 0 - end - - local current_velocity = self.object:get_velocity() - - local goal_velocity = { - x = (math.sin(yaw) * -v), - y = pitch, - z = (math.cos(yaw) * v), - } - - - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) - - if vector.length(new_velocity_addition) > vector.length(goal_velocity) then - vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition))) - end - - --smooths out mobs a bit - if vector.length(new_velocity_addition) >= 0.0001 then - self.object:add_velocity(new_velocity_addition) - end -end - ---[[ -______ _ -| ___| | -| |_ | |_ _ -| _| | | | | | -| | | | |_| | -\_| |_|\__, | - __/ | - |___/ -]]-- - --- move mob in facing direction ---this has been modified to be internal ---internal = lua (self.yaw) ---engine = c++ (self.object:get_yaw()) -mobs.set_fly_velocity = function(self, v) - - local yaw = (self.yaw or 0) - local pitch = (self.pitch or 0) - - if v == 0 then - pitch = 0 - end - - local current_velocity = self.object:get_velocity() - - local goal_velocity = { - x = (math.sin(yaw) * -v), - y = pitch, - z = (math.cos(yaw) * v), - } - - - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) - - if vector.length(new_velocity_addition) > vector.length(goal_velocity) then - vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition))) - end - - --smooths out mobs a bit - if vector.length(new_velocity_addition) >= 0.0001 then - self.object:add_velocity(new_velocity_addition) - end -end - ---a quick and simple pitch calculation between two vector positions -mobs.calculate_pitch = function(pos1, pos2) - - if pos1 == nil or pos2 == nil then - return false - end - - return minetest_dir_to_yaw(vector.new(vector.distance(vector.new(pos1.x,0,pos1.z),vector.new(pos2.x,0,pos2.z)),0,pos1.y - pos2.y)) + HALF_PI -end - ---make mobs fly up or down based on their y difference -mobs.set_pitch_while_attacking = function(self) - local pos1 = self.object:get_pos() - local pos2 = self.attacking:get_pos() - - local pitch = mobs.calculate_pitch(pos2,pos1) - - self.pitch = pitch -end - - - ---[[ - ___ - |_ | - | |_ _ _ __ ___ _ __ - | | | | | '_ ` _ \| '_ \ -/\__/ / |_| | | | | | | |_) | -\____/ \__,_|_| |_| |_| .__/ - | | - |_| -]]-- - ---special mob jump movement -mobs.jump_move = function(self, velocity) - - if self.object:get_velocity().y ~= 0 or not self.old_velocity or (self.old_velocity and self.old_velocity.y > 0) then - return - end - - --make the mob stick for a split second - mobs.set_velocity(self,0) - - --fallback velocity to allow modularity - local jump_height = DEFAULT_JUMP_HEIGHT - - local yaw = (self.yaw or 0) - - local current_velocity = self.object:get_velocity() - - local goal_velocity = { - x = (math.sin(yaw) * -velocity), - y = jump_height, - z = (math.cos(yaw) * velocity), - } - - - local new_velocity_addition = vector.subtract(goal_velocity,current_velocity) - - if vector.length(new_velocity_addition) > vector.length(goal_velocity) then - vector.multiply(new_velocity_addition, (vector.length(goal_velocity) / vector.length(new_velocity_addition))) - end - - --smooths out mobs a bit - if vector.length(new_velocity_addition) >= 0.0001 then - self.object:add_velocity(new_velocity_addition) - end -end - ---make it so mobs do not glitch out and freak out ---when moving around over nodes -mobs.swap_auto_step_height_adjust = function(self) - local y_vel = self.object:get_velocity().y - - if y_vel == 0 and self.stepheight ~= self.stepheight_backup then - self.stepheight = self.stepheight_backup - elseif y_vel ~= 0 and self.stepheight ~= 0 then - self.stepheight = 0 - end -end diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/projectile_handling.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/projectile_handling.lua deleted file mode 100644 index e7ae6ffbe..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/projectile_handling.lua +++ /dev/null @@ -1,44 +0,0 @@ -local GRAVITY = minetest.settings:get("movement_gravity")-- + 9.81 - -mobs.shoot_projectile_handling = function(arrow_item, pos, dir, yaw, shooter, power, damage, is_critical, bow_stack, collectable, gravity) - local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, arrow_item.."_entity") - if power == nil then - power = 19 - end - if damage == nil then - damage = 3 - end - - gravity = gravity or -GRAVITY - - local knockback - if bow_stack then - local enchantments = mcl_enchanting.get_enchantments(bow_stack) - if enchantments.power then - damage = damage + (enchantments.power + 1) / 4 - end - if enchantments.punch then - knockback = enchantments.punch * 3 - end - if enchantments.flame then - mcl_burning.set_on_fire(obj, math.huge) - 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._damage = damage - le._is_critical = is_critical - le._startpos = pos - le._knockback = knockback - le._collectable = collectable - - --play custom shoot sound - if shooter ~= nil and shooter.shoot_sound then - minetest.sound_play(shooter.shoot_sound, {pos=pos, max_hear_distance=16}, true) - end - - return obj -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua deleted file mode 100644 index 65ba764f6..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/set_up.lua +++ /dev/null @@ -1,224 +0,0 @@ -local math_random = math.random - -local minetest_settings = minetest.settings - --- CMI support check -local use_cmi = minetest.global_exists("cmi") - --- get entity staticdata -mobs.mob_staticdata = function(self) - --despawn mechanism - --don't despawned tamed or bred mobs - if not self.tamed and not self.bred then - if not mobs.check_for_player_within_area(self, 64) then - --print("removing SERIALIZED!") - self.object:remove() - return - end - end - - self.remove_ok = true - self.attack = nil - self.following = nil - - if use_cmi then - self.serialized_cmi_components = cmi.serialize_components(self._cmi_components) - end - - local tmp = {} - - for _,stat in pairs(self) do - - local t = type(stat) - - if t ~= "function" - and t ~= "nil" - and t ~= "userdata" - and _ ~= "_cmi_components" then - tmp[_] = self[_] - end - end - - return minetest.serialize(tmp) -end - - --- activate mob and reload settings -mobs.mob_activate = function(self, staticdata, def, dtime) - - -- remove monsters in peaceful mode - 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 - for _,stat in pairs(tmp) do - self[_] = stat - end - end - - --set up wandering - if not self.wandering then - self.wandering = true - end - - --clear animation - self.current_animation = nil - - -- select random texture, set model and size - if not self.base_texture then - - -- compatiblity with old simple mobs textures - if type(def.textures[1]) == "string" then - def.textures = {def.textures} - end - - self.base_texture = def.textures[math_random(1, #def.textures)] - 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 baby mobs to half size - if self.baby == true then - - vis_size = { - x = self.base_size.x * self.baby_size, - y = self.base_size.y * self.baby_size, - } - - if def.child_texture then - textures = def.child_texture[1] - end - - colbox = { - self.base_colbox[1] * self.baby_size, - self.base_colbox[2] * self.baby_size, - self.base_colbox[3] * self.baby_size, - self.base_colbox[4] * self.baby_size, - self.base_colbox[5] * self.baby_size, - self.base_colbox[6] * self.baby_size - } - selbox = { - self.base_selbox[1] * self.baby_size, - self.base_selbox[2] * self.baby_size, - self.base_selbox[3] * self.baby_size, - self.base_selbox[4] * self.baby_size, - self.base_selbox[5] * self.baby_size, - self.base_selbox[6] * self.baby_size - } - end - - --stop mobs from reviving - if not self.dead and not self.health then - self.health = math_random (self.hp_min, self.hp_max) - end - - if not self.random_sound_timer then - self.random_sound_timer = math_random(self.random_sound_timer_min,self.random_sound_timer_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} - self.path.stuck = false - self.path.following = false -- currently following path? - self.path.stuck_timer = 0 -- if stuck for too long search for path - - -- Armor groups - -- immortal=1 because we use custom health - -- handling (using "health" property) - local armor - if type(self.armor) == "table" then - armor = table.copy(self.armor) - armor.immortal = 1 - else - armor = {immortal=1, fleshy = self.armor} - end - self.object:set_armor_groups(armor) - self.old_y = self.object:get_pos().y - self.old_health = self.health - self.sounds.distance = self.sounds.distance or 10 - self.textures = textures - self.mesh = mesh - self.collisionbox = colbox - self.selectionbox = selbox - self.visual_size = vis_size - self.standing_in = "ignore" - self.standing_on = "ignore" - self.jump_sound_cooloff = 0 -- used to prevent jump sound from being played too often in short time - self.opinion_sound_cooloff = 0 -- used to prevent sound spam of particular sound types - - self.texture_mods = {} - - self.v_start = false - self.timer = 0 - self.blinktimer = 0 - self.blinkstatus = false - - - --continue mob effect on server restart - if self.dead or self.health <= 0 then - self.object:set_texture_mod("^[colorize:red:120") - else - self.object:set_texture_mod("") - end - - -- set anything changed above - self.object:set_properties(self) - - --update_tag(self) - --mobs.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 - end - end - - -- run after_activate - if def.after_activate then - def.after_activate(self, staticdata, def, dtime) - end - - if use_cmi then - self._cmi_components = cmi.activate_components(self.serialized_cmi_components) - cmi.notify_activate(self.object, dtime) - end -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/sound_handling.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/sound_handling.lua deleted file mode 100644 index 98d2644e8..000000000 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/sound_handling.lua +++ /dev/null @@ -1,59 +0,0 @@ -local math_random = math.random - - ---generic call for sound handler for mobs (data access) -mobs.play_sound = function(self,sound) - local soundinfo = self.sounds - - if not soundinfo then - return - end - - local play_sound = soundinfo[sound] - - if not play_sound then - return - end - - mobs.play_sound_handler(self, play_sound) -end - - ---generic sound handler for mobs -mobs.play_sound_handler = function(self, sound) - local pitch = (100 + math_random(-15,15) + math_random()) / 100 - local distance = self.sounds.distance or 16 - - minetest.sound_play(sound, { - object = self.object, - gain = 1.0, - max_hear_distance = distance, - pitch = pitch, - }, true) -end - - ---random sound timing handler -mobs.random_sound_handling = function(self,dtime) - - self.random_sound_timer = self.random_sound_timer - dtime - - --play sound and reset timer - if self.random_sound_timer <= 0 then - mobs.play_sound(self,"random") - self.random_sound_timer = math_random(self.random_sound_timer_min,self.random_sound_timer_max) - end -end - ---used for playing a non-mob internal sound at random pitches -mobs.play_sound_specific = function(self,soundname) - local pitch = (100 + math_random(-15,15) + math_random()) / 100 - local distance = self.sounds.distance or 16 - - minetest.sound_play(soundname, { - object = self.object, - gain = 1.0, - max_hear_distance = distance, - pitch = pitch, - }, true) -end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index b0daba2c4..69246b470 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -1,16 +1,14 @@ local path = minetest.get_modpath(minetest.get_current_modname()) -local api_path = path.."/api" - -- Mob API -dofile(api_path .. "/api.lua") +dofile(path .. "/api.lua") -- Spawning Algorithm -dofile(api_path .. "/spawning.lua") +dofile(path .. "/spawning.lua") -- Rideable Mobs -dofile(api_path .. "/mount.lua") +dofile(path .. "/mount.lua") -- Mob Items dofile(path .. "/crafts.lua") \ No newline at end of file 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/lucky_block.lua b/mods/ENTITIES/mcl_mobs/lucky_block.lua new file mode 100644 index 000000000..ea90de74a --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/lucky_block.lua @@ -0,0 +1,8 @@ + +if minetest.get_modpath("lucky_block") then + + lucky_block:add_blocks({ + {"dro", {"mcl_mobs:nametag"}, 1}, + {"lig"}, + }) +end diff --git a/mods/ENTITIES/mcl_mobs/mod.conf b/mods/ENTITIES/mcl_mobs/mod.conf index 2a91a7764..0d622f6a9 100644 --- a/mods/ENTITIES/mcl_mobs/mod.conf +++ b/mods/ENTITIES/mcl_mobs/mod.conf @@ -2,4 +2,4 @@ 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, 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 diff --git a/mods/ENTITIES/mcl_mobs/api/mount.lua b/mods/ENTITIES/mcl_mobs/mount.lua similarity index 88% rename from mods/ENTITIES/mcl_mobs/api/mount.lua rename to mods/ENTITIES/mcl_mobs/mount.lua index 0ed54a46e..9383ee067 100644 --- a/mods/ENTITIES/mcl_mobs/api/mount.lua +++ b/mods/ENTITIES/mcl_mobs/mount.lua @@ -1,11 +1,8 @@ -- lib_mount by Blert2112 (edited by TenPlus1) ---local enable_crash = false ---local crash_threshold = 6.5 -- ignored if enable_crash=false - -local math = math -local vector = vector +local enable_crash = false +local crash_threshold = 6.5 -- ignored if enable_crash=false ------------------------------------------------------------------------------ @@ -13,7 +10,7 @@ local vector = vector -- Helper functions -- ---[[local function node_ok(pos, fallback) +local node_ok = function(pos, fallback) fallback = fallback or mobs.fallback_node @@ -24,10 +21,10 @@ local vector = vector end return {name = fallback} -end]] +end ---[[local function node_is(pos) +local function node_is(pos) local node = node_ok(pos) @@ -48,7 +45,7 @@ end]] end return "other" -end]] +end local function get_sign(i) @@ -63,11 +60,13 @@ local function get_sign(i) end ---[[local function get_velocity(v, yaw, y) +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]] +end local function get_v(v) @@ -173,7 +172,7 @@ function mobs.detach(player, offset) --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 + 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) @@ -188,13 +187,13 @@ end function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) - --local rot_view = 0 + local rot_view = 0 - --if entity.player_rotation.y == 90 then - -- rot_view = math.pi/2 - --end + if entity.player_rotation.y == 90 then + rot_view = math.pi/2 + end - --local acce_y = 0 + local acce_y = 0 local velo = entity.object:get_velocity() entity.v = get_v(velo) * get_sign(entity.v) @@ -207,30 +206,21 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) -- move forwards if ctrl.up then - mobs.set_velocity(entity, entity.run_velocity) - - mobs.set_mob_animation(entity, moving_anim) + entity.v = entity.v + entity.accel / 10 -- move backwards elseif ctrl.down then - mobs.set_velocity(entity, -entity.run_velocity) + if entity.max_speed_reverse == 0 and entity.v == 0 then + return + end - mobs.set_mob_animation(entity, moving_anim) - - --halt - else - - mobs.set_velocity(entity, 0) - - mobs.set_mob_animation(entity, stand_anim) + entity.v = entity.v - entity.accel / 10 end - -- mob rotation + -- fix mob rotation entity.object:set_yaw(entity.driver:get_look_horizontal() - entity.rotate) - entity.yaw = entity.driver:get_look_horizontal() - entity.rotate - --[[ if can_fly then -- fly up @@ -254,21 +244,32 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) end else - ]]-- - -- jump - if ctrl.jump then + -- jump + if ctrl.jump then + + if velo.y == 0 then + velo.y = velo.y + entity.jump_height + acce_y = acce_y + (acce_y * 3) + 1 + end + end - mobs.jump(entity) end - - --end end - --[[ + -- if not moving then set animation and return + if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then + + if stand_anim then + mobs:set_animation(entity, stand_anim) + end + + return + end + -- set moving animation if moving_anim then - mobs:set_mob_animation(entity, moving_anim) + mobs:set_animation(entity, moving_anim) end -- Stop! @@ -382,17 +383,13 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) end entity.v2 = v - ]]-- end -- directional flying routine by D00Med (edited by TenPlus1) function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim) - if true then - print("succ") - return - end + local ctrl = entity.driver:get_player_control() local velo = entity.object:get_velocity() local dir = entity.driver:get_look_dir() @@ -443,9 +440,9 @@ 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_mob_animation(entity, stand_anim) + mobs:set_animation(entity, stand_anim) else -- moving animation - mobs:set_mob_animation(entity, moving_anim) + mobs:set_animation(entity, moving_anim) end end diff --git a/mods/ENTITIES/mcl_mobs/sounds/attributes.txt b/mods/ENTITIES/mcl_mobs/sounds/attributes.txt deleted file mode 100644 index 1228dd9d7..000000000 --- a/mods/ENTITIES/mcl_mobs/sounds/attributes.txt +++ /dev/null @@ -1,4 +0,0 @@ - -default_punch.1 = https://freesound.org/people/Merrick079/sounds/566436/ -default_punch.2 = https://freesound.org/people/Merrick079/sounds/566435/ -default_punch.3 = https://freesound.org/people/Merrick079/sounds/566434/ diff --git a/mods/ENTITIES/mcl_mobs/sounds/default_punch.1.ogg b/mods/ENTITIES/mcl_mobs/sounds/default_punch.1.ogg deleted file mode 100644 index 4d7ba8015..000000000 Binary files a/mods/ENTITIES/mcl_mobs/sounds/default_punch.1.ogg and /dev/null differ diff --git a/mods/ENTITIES/mcl_mobs/sounds/default_punch.2.ogg b/mods/ENTITIES/mcl_mobs/sounds/default_punch.2.ogg deleted file mode 100644 index c022d94f8..000000000 Binary files a/mods/ENTITIES/mcl_mobs/sounds/default_punch.2.ogg and /dev/null differ diff --git a/mods/ENTITIES/mcl_mobs/sounds/default_punch.3.ogg b/mods/ENTITIES/mcl_mobs/sounds/default_punch.3.ogg deleted file mode 100644 index 4c5e3f9b3..000000000 Binary files a/mods/ENTITIES/mcl_mobs/sounds/default_punch.3.ogg and /dev/null differ diff --git a/mods/ENTITIES/mcl_mobs/sounds/default_punch.ogg b/mods/ENTITIES/mcl_mobs/sounds/default_punch.ogg new file mode 100644 index 000000000..28a500bf5 Binary files /dev/null and b/mods/ENTITIES/mcl_mobs/sounds/default_punch.ogg differ diff --git a/mods/ENTITIES/mcl_mobs/api/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua similarity index 66% rename from mods/ENTITIES/mcl_mobs/api/spawning.lua rename to mods/ENTITIES/mcl_mobs/spawning.lua index 70167b421..2e7f523ba 100644 --- a/mods/ENTITIES/mcl_mobs/api/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -1,30 +1,17 @@ --lua locals -local get_node = minetest.get_node -local get_item_group = minetest.get_item_group -local get_node_light = minetest.get_node_light +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 new_vector = vector.new local math_random = math.random -local math_floor = math.floor ---local max = math.max - ---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 get_biome_name = minetest.get_biome_name +local max = math.max +local get_objects_inside_radius = minetest.get_objects_inside_radius +local vector_distance = vector.distance -- range for mob count -local aoc_range = 48 - ---do mobs spawn? -local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false - +local aoc_range = 32 --[[ THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs @@ -166,14 +153,28 @@ Overworld regular: --- count how many mobs are in an area -local function count_mobs(pos) + +local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false +-- count how many mobs of one type are inside an area + +local count_mobs = function(pos,mobtype) local num = 0 - for _,object in pairs(get_objects_inside_radius(pos, aoc_range)) do - if object and object:get_luaentity() and object:get_luaentity()._cmi_is_mob then - num = num + 1 + local objs = 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 hostile mobs only + if mobtype == "hostile" then + if obj.spawn_class == "hostile" then + num = num + 1 + end + -- count passive mobs only + else + num = num + 1 + end end end + return num end @@ -242,7 +243,8 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh end --[[ - local function spawn_action(pos, node, active_object_count, active_object_count_wider, name) + 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? @@ -482,26 +484,25 @@ end local axis --inner and outer part of square donut radius -local inner = 15 -local outer = 64 +local inner = 1 +local outer = 65 local int = {-1,1} +local position_calculation = function(pos) -local function position_calculation(pos) - - pos = vector_floor(pos) + pos = vector.floor(pos) --this is used to determine the axis buffer from the player - axis = math_random(0,1) + axis = math.random(0,1) --cast towards the direction if axis == 0 then --x - pos.x = pos.x + math_random(inner,outer)*int[math_random(1,2)] - pos.z = pos.z + math_random(-outer,outer) + pos.x = pos.x + math.random(inner,outer)*int[math.random(1,2)] + pos.z = pos.z + math.random(-outer,outer) else --z - pos.z = pos.z + math_random(inner,outer)*int[math_random(1,2)] - pos.x = pos.x + math_random(-outer,outer) + pos.z = pos.z + math.random(inner,outer)*int[math.random(1,2)] + pos.x = pos.x + math.random(-outer,outer) end - return pos + return(pos) end --[[ @@ -515,7 +516,7 @@ local decypher_limits_dictionary = { local function decypher_limits(posy) --local min_max_table = decypher_limits_dictionary[dimension] --return min_max_table[1],min_max_table[2] - posy = math_floor(posy) + posy = math.floor(posy) return posy - 32, posy + 32 end @@ -538,169 +539,118 @@ if mobs_spawn then local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime - if timer >= 10 then + if timer >= 8 then timer = 0 for _,player in pairs(minetest.get_connected_players()) do - -- after this line each "break" means "continue" - local do_mob_spawning = true - repeat - --don't need to get these variables more than once - --they happen in a single server step + for i = 1,math_random(3,8) do + repeat -- after this line each "break" means "continue" + local player_pos = player:get_pos() - local player_pos = player:get_pos() - local _,dimension = mcl_worlds.y_to_layer(player_pos.y) + local _,dimension = mcl_worlds.y_to_layer(player_pos.y) - if dimension == "void" or dimension == "default" then - break -- ignore void and unloaded area - end + if dimension == "void" or dimension == "default" then + break -- ignore void and unloaded area + end - local min,max = decypher_limits(player_pos.y) + local min,max = decypher_limits(player_pos.y) - for i = 1,math_random(1,4) do - -- after this line each "break" means "continue" - local do_mob_algorithm = true - repeat + local goal_pos = position_calculation(player_pos) - local goal_pos = position_calculation(player_pos) - - local spawning_position_list = find_nodes_in_area_under_air(vector_new(goal_pos.x,min,goal_pos.z), vector_new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) - - --couldn't find node - if #spawning_position_list <= 0 then - break - end - - local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] - - --Prevent strange behavior --- this is commented out: /too close to player --fixed with inner circle - if not spawning_position then -- or vector_distance(player_pos, spawning_position) < 15 - break - end - - --hard code mob limit in area to 5 for now - if count_mobs(spawning_position) >= 5 then - break - end - - local gotten_node = get_node(spawning_position).name - - if not gotten_node or gotten_node == "air" then --skip air nodes - break - end - - local gotten_biome = minetest.get_biome_data(spawning_position) - - if not gotten_biome then - break --skip if in unloaded area - end - - gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with - - --add this so mobs don't spawn inside nodes - spawning_position.y = spawning_position.y + 1 - - --only need to poll for node light if everything else worked - local gotten_light = get_node_light(spawning_position) - - local is_water = get_item_group(gotten_node, "water") ~= 0 - local is_lava = get_item_group(gotten_node, "lava") ~= 0 - - local mob_def = nil - - --create a disconnected clone of the spawn dictionary - --prevents memory leak - local mob_library_worker_table = table_copy(spawn_dictionary) - - --grab mob that fits into the spawning location - --randomly grab a mob, don't exclude any possibilities - local repeat_mob_search = true - repeat - - --do not infinite loop - if #mob_library_worker_table <= 0 then - --print("breaking infinite loop") - break - end - - local skip = false - - --use this for removing table elements of mobs that do not match - local temp_index = math_random(1,#mob_library_worker_table) - - local temp_def = mob_library_worker_table[temp_index] - - --skip if something ridiculous happens (nil mob def) - --something truly horrible has happened if skip gets - --activated at this point - if not temp_def then - skip = true - end - - if not skip and (spawning_position.y < temp_def.min_height or spawning_position.y > temp_def.max_height) then - skip = true - end - - --skip if not correct dimension - if not skip and (temp_def.dimension ~= dimension) then - skip = true - end - - --skip if not in correct biome - if not skip and (not biome_check(temp_def.biomes, gotten_biome)) then - skip = true - end - - --don't spawn if not in light limits - if not skip and (gotten_light < temp_def.min_light or gotten_light > temp_def.max_light) then - skip = true - end - - --skip if not in correct spawning type - if not skip and (temp_def.type_of_spawning == "ground" and is_water) then - skip = true - end - - if not skip and (temp_def.type_of_spawning == "ground" and is_lava) then - skip = true - end - - --found a mob, exit out of loop - if not skip then - --minetest.log("warning", "found mob:"..temp_def.name) - --print("found mob:"..temp_def.name) - mob_def = table_copy(temp_def) - break - else - --minetest.log("warning", "deleting temp index "..temp_index) - --print("deleting temp index") - table_remove(mob_library_worker_table, temp_index) - end - - until repeat_mob_search == false --this is needed to sort through mobs randomly - - - --catch if went through all mobs and something went horribly wrong - --could not find a valid mob to spawn that fits the environment - if not mob_def then - break - end - - --adjust the position for water and lava mobs - if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then - spawning_position.y = spawning_position.y - 1 - end - - --print("spawning: " .. mob_def.name) - - --everything is correct, spawn mob - minetest.add_entity(spawning_position, mob_def.name) + local spawning_position_list = find_nodes_in_area_under_air(new_vector(goal_pos.x,min,goal_pos.z), vector.new(goal_pos.x,max,goal_pos.z), {"group:solid", "group:water", "group:lava"}) + --couldn't find node + if #spawning_position_list <= 0 then break - until do_mob_algorithm == false --this is a safety catch - end + end - break - until do_mob_spawning == false --this is a performance catch + local spawning_position = spawning_position_list[math_random(1,#spawning_position_list)] + + --Prevent strange behavior/too close to player + if not spawning_position or vector_distance(player_pos, spawning_position) < 15 then + break + end + + local gotten_node = get_node(spawning_position) + local gotten_node_name = gotten_node.name + local gotten_node_def = minetest.registered_nodes[gotten_node_name] + + if not gotten_node_name or not gotten_node_def or gotten_node_name == "air" then --skip air nodes + break + end + + if gotten_node_def.use_texture_alpha and gotten_node_def.use_texture_alpha ~= "opaque" then + break + end --don't spawn on nonopaque nodes + + local leaf = minetest.get_item_group(gotten_node_name,"leaves") + if leaf ~= 0 then + break end --don't spawn on treetops + + local gotten_biome = minetest.get_biome_data(spawning_position) + + if not gotten_biome then + break --skip if in unloaded area + end + + gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with + + --grab random mob + local mob_def = spawn_dictionary[math.random(1,#spawn_dictionary)] + + if not mob_def then + break --skip if something ridiculous happens (nil mob def) + end + + --skip if not correct dimension + if mob_def.dimension ~= dimension then + break + end + + --skip if not in correct biome + if not biome_check(mob_def.biomes, gotten_biome) then + break + end + + --add this so mobs don't spawn inside nodes + spawning_position.y = spawning_position.y + 1 + + if spawning_position.y < mob_def.min_height or spawning_position.y > mob_def.max_height then + break + end + + --only need to poll for node light if everything else worked + local gotten_light = get_node_light(spawning_position) + + --don't spawn if not in light limits + if gotten_light < mob_def.min_light or gotten_light > mob_def.max_light then + break + end + + local is_water = get_item_group(gotten_node_name, "water") ~= 0 + local is_lava = get_item_group(gotten_node_name, "lava") ~= 0 + + if mob_def.type_of_spawning == "ground" and is_water then + break + end + + if mob_def.type_of_spawning == "ground" and is_lava then + break + end + + --finally do the heavy check (for now) of mobs in area + if count_mobs(spawning_position, mob_def.spawn_class) >= mob_def.aoc then + break + end + + --adjust the position for water and lava mobs + if mob_def.type_of_spawning == "water" or mob_def.type_of_spawning == "lava" then + spawning_position.y = spawning_position.y - 1 + end + + --everything is correct, spawn mob + minetest.add_entity(spawning_position, mob_def.name) + until true --this is a safety catch + end end end end) diff --git a/mods/ENTITIES/mcl_mobs/todo.txt b/mods/ENTITIES/mcl_mobs/todo.txt deleted file mode 100644 index 7598b14ed..000000000 --- a/mods/ENTITIES/mcl_mobs/todo.txt +++ /dev/null @@ -1 +0,0 @@ ---use vector.distance to count down mob despawn timer \ No newline at end of file diff --git a/mods/ENTITIES/mcl_paintings/init.lua b/mods/ENTITIES/mcl_paintings/init.lua index be210c74c..26bd2c61b 100644 --- a/mods/ENTITIES/mcl_paintings/init.lua +++ b/mods/ENTITIES/mcl_paintings/init.lua @@ -1,8 +1,9 @@ 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 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/mobs_mc/0_gameconfig.lua b/mods/ENTITIES/mobs_mc/0_gameconfig.lua index f21d946fe..c92ccbba5 100644 --- a/mods/ENTITIES/mobs_mc/0_gameconfig.lua +++ b/mods/ENTITIES/mobs_mc/0_gameconfig.lua @@ -15,7 +15,7 @@ with name "mobs_mc_gameconfig". ]] -- 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 = {} mobs_mc.items = { -- Items defined in mobs_mc @@ -81,9 +81,7 @@ mobs_mc.items = { gunpowder = "tnt:gunpowder", flint_and_steel = "fire:flint_and_steel", water_source = "default:water_source", - water_flowing = "default:water_flowing", river_water_source = "default:river_water_source", - --water_flowing = "default:river_water_flowing", black_dye = "dye:black", poppy = "flowers:rose", dandelion = "flowers:dandelion_yellow", @@ -128,6 +126,7 @@ mobs_mc.items = { nether_portal = "nether:portal", netherrack = "nether:rack", + nether_brick_block = "nether:brick", -- Wool (Minecraft color scheme) wool_white = "wool:white", diff --git a/mods/ENTITIES/mobs_mc/1_items_default.lua b/mods/ENTITIES/mobs_mc/1_items_default.lua index bdadbfdc5..d792af0a2 100644 --- a/mods/ENTITIES/mobs_mc/1_items_default.lua +++ b/mods/ENTITIES/mobs_mc/1_items_default.lua @@ -8,7 +8,7 @@ -- 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 S = minetest.get_translator(minetest.get_current_modname()) local c = mobs_mc.is_item_variable_overridden @@ -234,8 +234,8 @@ 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'}, + output = "mobs_mc:ender_eye", + recipe = { "mobs_mc:blaze_powder", "mobs_mc:blaze_rod"}, }) end @@ -525,7 +525,7 @@ if c("totem") then inventory_image = "mcl_totems_totem.png", wield_image = "mcl_totems_totem.png", stack_max = 1, - groups = {combat_item=1}, + groups = {combat_item = 1, offhand_item = 1}, }) end diff --git a/mods/ENTITIES/mobs_mc/2_throwing.lua b/mods/ENTITIES/mobs_mc/2_throwing.lua index 6f01ae6e6..23ae86d80 100644 --- a/mods/ENTITIES/mobs_mc/2_throwing.lua +++ b/mods/ENTITIES/mobs_mc/2_throwing.lua @@ -6,7 +6,7 @@ -- 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") +local S = minetest.get_translator("mobs_mc") --maikerumines throwing code --arrow (weapon) diff --git a/mods/ENTITIES/mobs_mc/3_shared.lua b/mods/ENTITIES/mobs_mc/3_shared.lua index fce0850b4..e30e41cf3 100644 --- a/mods/ENTITIES/mobs_mc/3_shared.lua +++ b/mods/ENTITIES/mobs_mc/3_shared.lua @@ -50,8 +50,10 @@ mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval) 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 + 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 diff --git a/mods/ENTITIES/mobs_mc/4_heads.lua b/mods/ENTITIES/mobs_mc/4_heads.lua index 2ba0d548b..01b8ee577 100644 --- a/mods/ENTITIES/mobs_mc/4_heads.lua +++ b/mods/ENTITIES/mobs_mc/4_heads.lua @@ -3,9 +3,8 @@ -- 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. --- TODO: Add translation. ---local S = minetest.get_translator("mobs_mc") +local S = minetest.get_translator("mobs_mc") -- Heads system diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index 70e084ee2..e9e1c1a16 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -8,9 +8,6 @@ mobs:register_mob("mobs_mc:bat", { spawn_class = "ambient", can_despawn = true, passive = true, - rotate = 270, - tilt_fly = true, - fly = true, hp_min = 6, hp_max = 6, collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25}, @@ -48,7 +45,9 @@ mobs:register_mob("mobs_mc:bat", { fall_damage = 0, view_range = 16, fear_height = 0, + jump = false, + fly = true, makes_footstep_sound = false, }) diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index a5e6f2bd3..577ed7107 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -5,6 +5,8 @@ local S = minetest.get_translator("mobs_mc") +local mod_target = minetest.get_modpath("mcl_target") + --################### --################### BLAZE --################### @@ -18,9 +20,6 @@ mobs:register_mob("mobs_mc:blaze", { hp_max = 20, xp_min = 10, xp_max = 10, - tilt_fly = false, - hostile = true, - --rotate = 270, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.79, 0.3}, rotate = -180, visual = "mesh", @@ -39,7 +38,7 @@ mobs:register_mob("mobs_mc:blaze", { walk_velocity = .8, run_velocity = 1.6, damage = 6, - reach = 4, -- don't want blaze getting too close + reach = 2, pathfinding = 1, drops = { {name = mobs_mc.items.blaze_rod, @@ -67,7 +66,7 @@ mobs:register_mob("mobs_mc:blaze", { fall_speed = -2.25, light_damage = 0, view_range = 16, - attack_type = "projectile", + attack_type = "dogshoot", arrow = "mobs_mc:blaze_fireball", shoot_interval = 3.5, shoot_offset = 1.0, @@ -79,18 +78,9 @@ mobs:register_mob("mobs_mc:blaze", { fear_height = 0, glow = 14, fire_resistant = true, - eye_height = 0.75, - projectile_cooldown_min = 2, - projectile_cooldown_max = 3, - shoot_arrow = function(self, pos, dir) - -- 2-4 damage per arrow - local dmg = math.random(2,4) - mobs.shoot_projectile_handling("mobs_mc:blaze_fireball", pos, dir, self.object:get_yaw(), self.object, 7, dmg,nil,nil,nil,-0.4) - end, - do_custom = function(self) - if self.attacking and self.state == "attack" and vector.distance(self.object:get_pos(), self.attacking:get_pos()) < 1.2 then - mcl_burning.set_on_fire(self.attacking, 5) + 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({ @@ -160,11 +150,6 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { visual_size = {x = 0.3, y = 0.3}, textures = {"mcl_fire_fire_charge.png"}, velocity = 15, - speed = 5, - tail = 1, - tail_texture = "mobs_mc_spit.png^[colorize:black:255", --repurpose spit texture - tail_size = 2, - tail_distance_divider = 3, _is_fireball = true, -- Direct hit, no fire... just plenty of pain @@ -172,7 +157,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { mcl_burning.set_on_fire(player, 5) player:punch(self.object, 1.0, { full_punch_interval = 1.0, - damage_groups = {fleshy = self._damage}, + damage_groups = {fleshy = 5}, }, nil) end, @@ -180,7 +165,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { mcl_burning.set_on_fire(mob, 5) mob:punch(self.object, 1.0, { full_punch_interval = 1.0, - damage_groups = {fleshy = self._damage}, + damage_groups = {fleshy = 5}, }, nil) end, @@ -195,19 +180,20 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { -- Node hit, make fire hit_node = function(self, pos, node) - if node.name ~= "air" then - local pos_above = table.copy(pos) - pos_above.y = pos_above.y + 1 - minetest.set_node(pos_above, {name=mobs_mc.items.fire}) + if node == "air" then + minetest.set_node(pos, {name = mobs_mc.items.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 = mobs_mc.items.fire}) end end end diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 9146a012f..0b43fca0d 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -18,8 +18,7 @@ mobs:register_mob("mobs_mc:chicken", { xp_min = 1, xp_max = 3, collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2}, - skittish = true, - fall_slow = true, + runaway = true, floats = 1, visual = "mesh", mesh = "mobs_mc_chicken.b3d", @@ -27,10 +26,9 @@ mobs:register_mob("mobs_mc:chicken", { {"mobs_mc_chicken.png"}, }, visual_size = {x=2.2, y=2.2}, - rotate = 270, + makes_footstep_sound = true, walk_velocity = 1, - run_velocity = 3, drops = { {name = mobs_mc.items.chicken_raw, chance = 1, @@ -66,25 +64,14 @@ mobs:register_mob("mobs_mc:chicken", { run_start = 0, run_end = 40, }, - follow = "mcl_farming:wheat_seeds", - breed_distance = 1.5, - baby_size = 0.5, - follow_distance = 2, + follow = mobs_mc.follow.chicken, view_range = 16, fear_height = 4, - --why do chickend breed if they lay eggs?? on_rightclick = function(self, clicker) - --attempt to enter breed state - if mobs.enter_breed_state(self,clicker) then - return - end - - --make baby grow faster - if self.baby then - mobs.make_baby_grow_faster(self,clicker) - return - end + 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 end, do_custom = function(self, dtime) @@ -111,21 +98,6 @@ mobs:register_mob("mobs_mc:chicken", { }, true) end, - --head code - has_head = true, - head_bone = "head", - - swap_y_with_x = false, - reverse_head_yaw = false, - - head_bone_pos_y = 1.675, - head_bone_pos_z = 0, - - head_height_offset = 0.55, - head_direction_offset = 0.0925, - - head_pitch_modifier = -math.pi/2, - --end head code }) --spawn @@ -134,53 +106,42 @@ mobs:spawn_specific( "overworld", "ground", { - "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", - "Mesa", - "FlowerForest", - "Swampland", - "Taiga", - "ExtremeHills", - "Jungle", - "Savanna", - "BirchForest", - "MegaSpruceTaiga", - "MegaTaiga", - "ExtremeHills+", - "Forest", - "Plains", - "Desert", - "ColdTaiga", + "flat", "IcePlainsSpikes", - "SunflowerPlains", - "IcePlains", - "RoofedForest", - "ExtremeHills+_snowtop", - "MesaPlateauFM_grasstop", - "JungleEdgeM", + "ColdTaiga", + "ColdTaiga_beach", + "ColdTaiga_beach_water", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", "ExtremeHillsM", - "JungleM", + "ExtremeHills+", + "ExtremeHills+_snowtop", + "StoneBeach", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", "BirchForestM", - "MesaPlateauF", - "MesaPlateauFM", - "MesaPlateauF_grasstop", - "MesaBryce", - "JungleEdge", + "RoofedForest", + "Savanna", + "Savanna_beach", "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" }, 9, minetest.LIGHT_MAX+1, diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 6100e5899..0b9a7ec71 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -10,7 +10,6 @@ local cow_def = { hp_max = 10, xp_min = 1, xp_max = 3, - rotate = 270, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45}, visual = "mesh", mesh = "mobs_mc_cow.b3d", @@ -21,7 +20,6 @@ local cow_def = { visual_size = {x=2.8, y=2.8}, makes_footstep_sound = true, walk_velocity = 1, - run_velocity = 3, drops = { {name = mobs_mc.items.beef_raw, chance = 1, @@ -34,7 +32,7 @@ local cow_def = { max = 2, looting = "common",}, }, - skittish = true, + runaway = true, sounds = { random = "mobs_mc_cow", damage = "mobs_mc_cow_hurt", @@ -49,17 +47,12 @@ local cow_def = { walk_end = 40, run_start = 0, run_end = 40, }, - --follow = mobs_mc.follow.cow, + 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 - --attempt to enter breed state - if mobs.enter_breed_state(self,clicker) then - return - end - - --make baby grow faster - if self.baby then - mobs.make_baby_grow_faster(self,clicker) + if self.child then return end @@ -78,28 +71,11 @@ local cow_def = { end return end + mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) end, - breed_distance = 1.5, - baby_size = 0.5, - follow_distance = 2, follow = mobs_mc.items.wheat, view_range = 10, fear_height = 4, - - --head code - has_head = true, - head_bone = "head", - - swap_y_with_x = false, - reverse_head_yaw = false, - - head_bone_pos_y = 3.6, - head_bone_pos_z = -0.6, - - head_height_offset = 1.0525, - head_direction_offset = 0.5, - head_pitch_modifier = 0, - --end head code } mobs:register_mob("mobs_mc:cow", cow_def) @@ -110,17 +86,12 @@ mooshroom_def.description = S("Mooshroom") mooshroom_def.mesh = "mobs_mc_cow.b3d" 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) - --attempt to enter breed state - if mobs.enter_breed_state(self,clicker) then + if mobs:feed_tame(self, clicker, 1, true, true) then return end + if mobs:protect(self, clicker) then return end + + if self.child then return end - - --make baby grow faster - if self.baby then - mobs.make_baby_grow_faster(self,clicker) - 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 @@ -169,6 +140,7 @@ mooshroom_def.on_rightclick = function(self, clicker) minetest.add_item(pos, {name = mobs_mc.items.mushroom_stew}) end end + mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) end mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) @@ -179,53 +151,42 @@ mobs:spawn_specific( "overworld", "ground", { - "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", - "Mesa", - "FlowerForest", - "Swampland", - "Taiga", - "ExtremeHills", - "Jungle", - "Savanna", - "BirchForest", - "MegaSpruceTaiga", - "MegaTaiga", - "ExtremeHills+", - "Forest", - "Plains", - "Desert", - "ColdTaiga", + "flat", "IcePlainsSpikes", - "SunflowerPlains", - "IcePlains", - "RoofedForest", - "ExtremeHills+_snowtop", - "MesaPlateauFM_grasstop", - "JungleEdgeM", + "ColdTaiga", + "ColdTaiga_beach", + "ColdTaiga_beach_water", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", "ExtremeHillsM", - "JungleM", + "ExtremeHills+", + "ExtremeHills+_snowtop", + "StoneBeach", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", "BirchForestM", - "MesaPlateauF", - "MesaPlateauFM", - "MesaPlateauF_grasstop", - "MesaBryce", - "JungleEdge", + "RoofedForest", + "Savanna", + "Savanna_beach", "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" }, 9, minetest.LIGHT_MAX+1, diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 4d0539996..827d08aab 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -12,8 +12,6 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:creeper", { type = "monster", spawn_class = "hostile", - hostile = true, - rotate = 270, hp_min = 20, hp_max = 20, xp_min = 5, @@ -35,39 +33,23 @@ mobs:register_mob("mobs_mc:creeper", { explode = "tnt_explode", distance = 16, }, - makes_footstep_sound = false, + makes_footstep_sound = true, walk_velocity = 1.05, - run_velocity = 3.25, + run_velocity = 2.1, runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" }, attack_type = "explode", - eye_height = 1.25, + --hssssssssssss explosion_strength = 3, - --explosion_radius = 3, - --explosion_damage_radius = 6, - --explosiontimer_reset_radius = 6, - reach = 1.5, - defuse_reach = 4, - explosion_timer = 0.3, + 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, - --head code - has_head = true, - head_bone = "head", - - swap_y_with_x = true, - reverse_head_yaw = true, - - head_bone_pos_y = 2.4, - head_bone_pos_z = 0, - - head_height_offset = 1.1, - head_direction_offset = 0, - head_pitch_modifier = 0, - --end head code - -- 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. @@ -148,7 +130,7 @@ mobs:register_mob("mobs_mc:creeper", { }) mobs:register_mob("mobs_mc:creeper_charged", { - description = S("Charged Creeper"), + description = S("Creeper"), type = "monster", spawn_class = "hostile", hp_min = 20, @@ -167,7 +149,6 @@ mobs:register_mob("mobs_mc:creeper_charged", { "mobs_mc_creeper_charge.png"}, }, visual_size = {x=3, y=3}, - rotate = 270, sounds = { attack = "tnt_ignite", death = "mobs_mc_creeper_death", @@ -176,19 +157,18 @@ mobs:register_mob("mobs_mc:creeper_charged", { explode = "tnt_explode", distance = 16, }, - makes_footstep_sound = false, + 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 = 3, - --explosion_damage_radius = 6, - --explosiontimer_reset_radius = 3, - reach = 1.5, - defuse_reach = 4, - explosion_timer = 0.3, + 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, diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index d2d040ad2..0372fbe00 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -8,22 +8,15 @@ mobs:register_mob("mobs_mc:enderdragon", { description = S("Ender Dragon"), type = "monster", spawn_class = "hostile", + pathfinding = 1, attacks_animals = true, walk_chance = 100, - rotate = 270, - tilt_fly = true, - hostile = true, - shoot_arrow = function(self, pos, dir) - -- 2-4 damage per arrow - local dmg = math.random(2,4) - mobs.shoot_projectile_handling("mobs_mc:dragon_fireball", pos, dir, self.object:get_yaw(), self.object, nil, dmg) - end, hp_max = 200, hp_min = 200, xp_min = 500, xp_max = 500, - collisionbox = {-2, 0, -2, 2, 2, 2}, - eye_height = 1, + collisionbox = {-2, 3, -2, 2, 5, 2}, + physical = false, visual = "mesh", mesh = "mobs_mc_dragon.b3d", textures = { @@ -31,7 +24,6 @@ mobs:register_mob("mobs_mc:enderdragon", { }, visual_size = {x=3, y=3}, view_range = 35, - reach = 20, walk_velocity = 6, run_velocity = 6, can_despawn = false, @@ -55,10 +47,12 @@ mobs:register_mob("mobs_mc:enderdragon", { lava_damage = 0, fire_damage = 0, on_rightclick = nil, - attack_type = "projectile", + attack_type = "dogshoot", arrow = "mobs_mc:dragon_fireball", shoot_interval = 0.5, shoot_offset = -1.0, + xp_min = 500, + xp_max = 500, animation = { fly_speed = 8, stand_speed = 8, stand_start = 0, stand_end = 20, @@ -103,7 +97,7 @@ mobs:register_mob("mobs_mc:enderdragon", { mcl_portals.spawn_gateway_portal() mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open") if self._initial then - mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000 + mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000 minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg}) end end @@ -111,8 +105,8 @@ mobs:register_mob("mobs_mc:enderdragon", { fire_resistant = true, }) ---TODO: replace this setting by a proper gamerules system -local mobs_griefing = minetest.settings:get_bool("mobs_griefing", true) + +local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false -- dragon fireball (projectile) mobs:register_arrow("mobs_mc:dragon_fireball", { @@ -139,13 +133,10 @@ mobs:register_arrow("mobs_mc:dragon_fireball", { -- node hit, explode hit_node = function(self, pos, node) - --mobs:boom(self, pos, 2) - if mobs_griefing then - mcl_explosions.explode(self.object:get_pos(), 2, { drop_chance = 1.0 }) - end + mobs:boom(self, pos, 2) end }) mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true) ---mcl_wip.register_wip_item("mobs_mc:enderdragon") +mcl_wip.register_wip_item("mobs_mc:enderdragon") diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 0b6985711..6ab376366 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -193,19 +193,18 @@ mobs:register_mob("mobs_mc:enderman", { description = S("Enderman"), type = "monster", spawn_class = "passive", - neutral = true, + passive = true, + pathfinding = 1, hp_min = 40, hp_max = 40, xp_min = 5, xp_max = 5, - rotate = 270, collisionbox = {-0.3, -0.01, -0.3, 0.3, 2.89, 0.3}, visual = "mesh", mesh = "mobs_mc_enderman.b3d", textures = create_enderman_textures(), visual_size = {x=3, y=3}, makes_footstep_sound = true, - eye_height = 2.5, sounds = { -- TODO: Custom war cry sound war_cry = "mobs_sandmonster", @@ -214,8 +213,8 @@ mobs:register_mob("mobs_mc:enderman", { random = {name="mobs_mc_enderman_random", gain=0.5}, distance = 16, }, - walk_velocity = 1, - run_velocity = 4, + walk_velocity = 0.2, + run_velocity = 3.4, damage = 7, reach = 2, drops = { @@ -225,22 +224,6 @@ mobs:register_mob("mobs_mc:enderman", { max = 1, looting = "common"}, }, - - --head code - has_head = false, - head_bone = "head.low", - - swap_y_with_x = false, - reverse_head_yaw = false, - - head_bone_pos_y = 2.4, - head_bone_pos_z = 0, - - head_height_offset = 1.1, - head_direction_offset = 0, - head_pitch_modifier = 0, - --end head code - animation = select_enderman_animation("normal"), _taken_node = "", do_custom = function(self, dtime) @@ -299,8 +282,8 @@ mobs:register_mob("mobs_mc:enderman", { --self:teleport(nil) --self.state = "" --else - if self.attacking then - local target = self.attacking + 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 @@ -318,12 +301,12 @@ mobs:register_mob("mobs_mc:enderman", { for n = 1, #objs do local obj = objs[n] if obj then - --if minetest.is_player(obj) then + if minetest.is_player(obj) then -- Warp from players during day. --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then -- self:teleport(nil) --end - if not obj:is_player() then + else local lua = obj:get_luaentity() if lua then if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then @@ -377,16 +360,11 @@ mobs:register_mob("mobs_mc:enderman", { --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.state = "stand" - self.hostile = false + self.attack = minetest.get_player_by_name(obj:get_player_name()) break - --begin attacking the player - 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" - self.hostile = true - self.state = "attack" - self.attacking = obj end end @@ -452,7 +430,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_mob_animation(self, self.animation.current) + mobs:set_animation(self, 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 @@ -475,7 +453,7 @@ mobs:register_mob("mobs_mc:enderman", { local def = minetest.registered_nodes[self._taken_node] -- Update animation accordingly (removes visible block) self.animation = select_enderman_animation("normal") - mobs.set_mob_animation(self, self.animation.current) + mobs:set_animation(self, 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 @@ -500,7 +478,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 @@ -534,7 +513,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 @@ -579,7 +559,7 @@ mobs:register_mob("mobs_mc:enderman", { water_damage = 8, view_range = 64, fear_height = 4, - attack_type = "punch", + attack_type = "dogfight", }) diff --git a/mods/ENTITIES/mobs_mc/endermite.lua b/mods/ENTITIES/mobs_mc/endermite.lua index 712086828..2bffa8304 100644 --- a/mods/ENTITIES/mobs_mc/endermite.lua +++ b/mods/ENTITIES/mobs_mc/endermite.lua @@ -9,15 +9,12 @@ mobs:register_mob("mobs_mc:endermite", { type = "monster", spawn_class = "hostile", passive = false, - rotate = 270, - hostile = true, hp_min = 8, hp_max = 8, xp_min = 3, xp_max = 3, armor = {fleshy = 100, arthropod = 100}, group_attack = true, - attack_type = "punch", collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.29, 0.2}, visual = "mesh", mesh = "mobs_mc_endermite.b3d", diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 609110bdb..1d7179162 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -14,17 +14,13 @@ mobs:register_mob("mobs_mc:ghast", { description = S("Ghast"), type = "monster", spawn_class = "hostile", + pathfinding = 1, group_attack = true, - hostile = true, - fly_random_while_attack = true, hp_min = 10, hp_max = 10, - rotate = 270, xp_min = 5, xp_max = 5, - reach = 20, - eye_height = 2.5, - collisionbox = {-2, 0, -2, 2, 4, 2}, + collisionbox = {-2, 5, -2, 2, 9, 2}, visual = "mesh", mesh = "mobs_mc_ghast.b3d", textures = { @@ -40,10 +36,8 @@ mobs:register_mob("mobs_mc:ghast", { -- TODO: damage -- TODO: better death }, - 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}, @@ -54,23 +48,22 @@ mobs:register_mob("mobs_mc:ghast", { walk_start = 0, walk_end = 40, run_start = 0, run_end = 40, }, - fall_damage = 0, - view_range = 28, - attack_type = "projectile", - arrow = "mobs_mc:ghast_fireball", + view_range = 100, + attack_type = "dogshoot", + arrow = "mobs_mc:fireball", + shoot_interval = 3.5, + shoot_offset = -5, + dogshoot_switch = 1, + dogshoot_count_max =1, + passive = false, + jump = true, + jump_height = 4, floats=1, fly = true, makes_footstep_sound = false, + instant_death = true, fire_resistant = true, - projectile_cooldown_min = 5, - projectile_cooldown_max = 7, - shoot_arrow = function(self, pos, dir) - -- 2-4 damage per arrow - local dmg = math.random(2,4) - mobs.shoot_projectile_handling("mobs_mc:ghast_fireball", pos, dir, self.object:get_yaw(), self.object, 11, dmg,nil,nil,nil,-0.6) - end, - --[[ do_custom = function(self) if self.firing == true then self.base_texture = {"mobs_mc_ghast_firing.png"} @@ -80,7 +73,6 @@ mobs:register_mob("mobs_mc:ghast", { self.object:set_properties({textures=self.base_texture}) end end, - ]]-- }) @@ -100,40 +92,32 @@ mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- fireball (projectile) -mobs:register_arrow("mobs_mc:ghast_fireball", { +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}, - tail = 1, - tail_texture = "mobs_mc_spit.png^[colorize:black:255", --repurpose spit texture - tail_size = 5, _is_fireball = true, hit_player = function(self, player) - --[[ 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) - mcl_explosions.explode(self.object:get_pos(), 3,{ drop_chance = 1.0 }) + mobs:boom(self, self.object:get_pos(), 1, true) end, hit_mob = function(self, mob) mob:punch(self.object, 1.0, { full_punch_interval = 1.0, - damage_groups = {fleshy = self._damage}, + damage_groups = {fleshy = 6}, }, nil) - --mobs:boom(self, self.object:get_pos(), 1, true) - mcl_explosions.explode(self.object:get_pos(), 3,{ drop_chance = 1.0 }) + mobs:boom(self, self.object:get_pos(), 1, true) end, hit_node = function(self, pos, node) - --mobs:boom(self, pos, 1, true) - mcl_explosions.explode(self.object:get_pos(), 3,{ drop_chance = 1.0 }) + mobs:boom(self, pos, 1, true) end }) diff --git a/mods/ENTITIES/mobs_mc/guardian.lua b/mods/ENTITIES/mobs_mc/guardian.lua index 0916010d2..06a2ba2e2 100644 --- a/mods/ENTITIES/mobs_mc/guardian.lua +++ b/mods/ENTITIES/mobs_mc/guardian.lua @@ -13,8 +13,8 @@ mobs:register_mob("mobs_mc:guardian", { xp_min = 10, xp_max = 10, breath_max = -1, - passive = false, - attack_type = "punch", + passive = false, + attack_type = "dogfight", pathfinding = 1, view_range = 16, walk_velocity = 2, @@ -94,6 +94,7 @@ mobs:register_mob("mobs_mc:guardian", { makes_footstep_sound = false, fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, jump = false, + view_range = 16, }) -- Spawning disabled due to size issues diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua index 0c871da7a..5b8150dd4 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -15,8 +15,8 @@ mobs:register_mob("mobs_mc:guardian_elder", { xp_min = 10, xp_max = 10, breath_max = -1, - passive = false, - attack_type = "punch", + passive = false, + attack_type = "dogfight", pathfinding = 1, view_range = 16, walk_velocity = 2, @@ -104,6 +104,7 @@ mobs:register_mob("mobs_mc:guardian_elder", { makes_footstep_sound = false, fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, jump = false, + view_range = 16, }) -- Spawning disabled due to size issues <- what do you mean? -j4i diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index db23d410b..5fe605573 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -38,9 +38,9 @@ end 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" end ---[[local can_equip_chest = function(entity_id) +local can_equip_chest = function(entity_id) return entity_id == "mobs_mc:mule" or entity_id == "mobs_mc:donkey" -end]] +end local can_breed = function(entity_id) return entity_id == "mobs_mc:horse" or "mobs_mc:mule" or entity_id == "mobs_mc:donkey" end @@ -88,10 +88,6 @@ local horse = { spawn_class = "passive", visual = "mesh", mesh = "mobs_mc_horse.b3d", - rotate = 270, - walk_velocity = 1, - run_velocity = 8, - skittish = true, visual_size = {x=3.0, y=3.0}, collisionbox = {-0.69825, -0.01, -0.69825, 0.69825, 1.59, 0.69825}, animation = { @@ -101,7 +97,7 @@ local horse = { walk_speed = 25, walk_start = 0, walk_end = 40, - run_speed = 120, + run_speed = 60, run_start = 0, run_end = 40, }, @@ -118,8 +114,7 @@ local horse = { fly = false, walk_chance = 60, view_range = 16, - follow = "mcl_farming:wheat_item", - follow_distance = 3, + follow = mobs_mc.follow.horse, passive = true, hp_min = 15, hp_max = 30, @@ -187,7 +182,7 @@ local horse = { -- if driver present and horse has a saddle allow control of horse if self.driver and self._saddle then - mobs.drive(self, "run", "stand", false, dtime) + mobs.drive(self, "walk", "stand", false, dtime) return false -- skip rest of mob functions end @@ -219,21 +214,6 @@ local horse = { local iname = item:get_name() local heal = 0 - --sneak click to breed the horse/feed it - if self.owner and self.owner == clicker:get_player_name() then - --attempt to enter breed state - if mobs.enter_breed_state(self,clicker) then - return - end - end - - --don't do any other logic with the baby - --make baby grow faster - if self.baby then - mobs.make_baby_grow_faster(self,clicker) - return - end - -- Taming self.temper = self.temper or (math.random(1,100)) @@ -259,7 +239,6 @@ local horse = { 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 - mobs.tamed_effect(self) if not self.owner or self.owner == "" then self.owner = clicker:get_player_name() end @@ -274,14 +253,6 @@ local horse = { -- If nothing happened temper_increase = 0 and addition does nothing self.temper = self.temper + temper_increase - --give the player some kind of idea - --of what's happening with the horse's temper - if self.temper <= 100 then - mobs.feed_effect(self) - else - mobs.tamed_effect(self) - end - return end @@ -311,10 +282,14 @@ local horse = { return end + if mobs:protect(self, clicker) then + return + end + -- Make sure tamed horse is mature and being clicked by owner only if self.tamed and not self.child and self.owner == clicker:get_player_name() then - --local inv = clicker:get_inventory() + local inv = clicker:get_inventory() -- detatch player already riding horse if self.driver and clicker == self.driver then @@ -382,6 +357,9 @@ local horse = { self.object:set_properties({stepheight = 1.1}) 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) end end end, @@ -542,53 +520,42 @@ mobs:spawn_specific( "overworld", "ground", { - "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", - "Mesa", - "FlowerForest", - "Swampland", - "Taiga", - "ExtremeHills", - "Jungle", - "Savanna", - "BirchForest", - "MegaSpruceTaiga", - "MegaTaiga", - "ExtremeHills+", - "Forest", - "Plains", - "Desert", - "ColdTaiga", + "flat", "IcePlainsSpikes", - "SunflowerPlains", - "IcePlains", - "RoofedForest", - "ExtremeHills+_snowtop", - "MesaPlateauFM_grasstop", - "JungleEdgeM", + "ColdTaiga", + "ColdTaiga_beach", + "ColdTaiga_beach_water", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", "ExtremeHillsM", - "JungleM", + "ExtremeHills+", + "ExtremeHills+_snowtop", + "StoneBeach", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", "BirchForestM", - "MesaPlateauF", - "MesaPlateauFM", - "MesaPlateauF_grasstop", - "MesaBryce", - "JungleEdge", + "RoofedForest", + "Savanna", + "Savanna_beach", "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" }, 0, minetest.LIGHT_MAX+1, diff --git a/mods/ENTITIES/mobs_mc/iron_golem.lua b/mods/ENTITIES/mobs_mc/iron_golem.lua index d68dc157b..0d3e74645 100644 --- a/mods/ENTITIES/mobs_mc/iron_golem.lua +++ b/mods/ENTITIES/mobs_mc/iron_golem.lua @@ -16,11 +16,8 @@ mobs:register_mob("mobs_mc:iron_golem", { type = "npc", spawn_class = "passive", passive = true, - rotate = 270, hp_min = 100, hp_max = 100, - protect = true, - neutral = true, breath_max = -1, collisionbox = {-0.7, -0.01, -0.7, 0.7, 2.69, 0.7}, visual = "mesh", @@ -43,7 +40,7 @@ mobs:register_mob("mobs_mc:iron_golem", { reach = 3, group_attack = true, attacks_monsters = true, - attack_type = "punch", + attack_type = "dogfight", drops = { {name = mobs_mc.items.iron_ingot, chance = 1, diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 9803b582b..b6566059a 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -28,15 +28,6 @@ mobs:register_mob("mobs_mc:llama", { description = S("Llama"), type = "animal", spawn_class = "passive", - rotate = 270, - neutral = true, - group_attack = true, - attack_type = "projectile", - shoot_arrow = function(self, pos, dir) - -- 2-4 damage per arrow - local dmg = 1 - mobs.shoot_projectile_handling("mobs_mc:spit", pos, dir, self.object:get_yaw(), self.object, nil, dmg) - end, hp_min = 15, hp_max = 30, xp_min = 1, @@ -59,11 +50,7 @@ mobs:register_mob("mobs_mc:llama", { walk_velocity = 1, run_velocity = 4.4, follow_velocity = 4.4, - breed_distance = 1.5, - baby_size = 0.5, - follow_distance = 2, floats = 1, - reach = 6, drops = { {name = mobs_mc.items.leather, chance = 1, @@ -96,7 +83,7 @@ mobs:register_mob("mobs_mc:llama", { look_start = 78, look_end = 108, }, - follow = mobs_mc.items.hay_bale, + follow = mobs_mc.follow.llama, view_range = 16, do_custom = function(self, dtime) @@ -139,71 +126,30 @@ mobs:register_mob("mobs_mc:llama", { return end - --owner is broken for this - --we'll make the owner this guy - --attempt to enter breed state - if mobs.enter_breed_state(self,clicker) then - self.tamed = true - self.owner = clicker:get_player_name() - return + local item = clicker:get_wielded_item() + if item:get_name() == mobs_mc.items.hay_bale then + -- Breed with hay bale + if mobs:feed_tame(self, clicker, 1, true, false) then return end + else + -- Feed with anything else + if mobs:feed_tame(self, clicker, 1, false, true) then return end end - - --ignore other logic - --make baby grow faster - if self.baby then - mobs.make_baby_grow_faster(self,clicker) - return - end - + if 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 - local item = clicker:get_wielded_item() - --safety catch - if not item then - return - end - - - - --put chest on carpeted llama - if self.carpet and not self.chest and item:get_name() == "mcl_chests:chest" then - if not minetest.is_creative_enabled(clicker:get_player_name()) then - item:take_item() - clicker:set_wielded_item(item) - end - - self.base_texture = table.copy(self.base_texture) - self.base_texture[1] = "mobs_mc_llama_chest.png" - self.object:set_properties({ - textures = self.base_texture, - }) - self.chest = true - - return --don't attempt to ride - end - - -- Place carpet - --TODO: Re-enable this code when carpet textures arrived. - if minetest.get_item_group(item:get_name(), "carpet") == 1 then - + --[[ 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 if not minetest.is_creative_enabled(clicker:get_player_name()) then item:take_item() clicker:set_wielded_item(item) - - --shoot off old carpet - if self.carpet then - minetest.add_item(self.object:get_pos(), self.carpet) - end end - local substr = carpetdata[2] local tex_carpet = "mobs_mc_llama_decor_"..substr..".png" - self.base_texture = table.copy(self.base_texture) self.base_texture[2] = tex_carpet self.object:set_properties({ @@ -224,21 +170,23 @@ mobs:register_mob("mobs_mc:llama", { end end end + ]] - if self.carpet then - -- detatch player already riding llama - if self.driver and clicker == self.driver then + -- detatch player already riding llama + if self.driver and clicker == self.driver then - mobs.detach(clicker, {x = 1, y = 0, z = 1}) + mobs.detach(clicker, {x = 1, y = 0, z = 1}) - -- attach player to llama - elseif not self.driver then + -- attach player to llama + elseif not self.driver then - self.object:set_properties({stepheight = 1.1}) - mobs.attach(self, clicker) - end + self.object:set_properties({stepheight = 1.1}) + 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, @@ -275,12 +223,18 @@ mobs:spawn_specific( "overworld", "ground", { -"Mesa", -"MesaPlateauFM_grasstop", -"MesaPlateauF", -"MesaPlateauFM", -"MesaPlateauF_grasstop", -"MesaBryce", + "Mesa", + "MesaPlateauFM_grasstop", + "MesaPlateauF", + "MesaPlateauFM", + "MesaPlateauF_grasstop", + "MesaBryce", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", }, 0, minetest.LIGHT_MAX+1, @@ -292,38 +246,3 @@ mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) - - --- llama spit -mobs:register_arrow("mobs_mc:spit", { - visual = "sprite", - visual_size = {x = 0.3, y = 0.3}, - textures = {"mobs_mc_spit.png"}, - velocity = 1, - speed = 1, - tail = 1, - tail_texture = "mobs_mc_spit.png", - tail_size = 2, - tail_distance_divider = 4, - - hit_player = function(self, player) - --[[if rawget(_G, "armor") and armor.last_damage_types then - armor.last_damage_types[player:get_player_name()] = "spit" - end]] - player:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = self._damage}, - }, nil) - end, - - hit_mob = function(self, mob) - mob:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = self._damage}, - }, nil) - end, - - hit_node = function(self, pos, node) - --does nothing - end -}) \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr index 6598cd481..24d3fa324 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr @@ -28,7 +28,6 @@ Pig=Schwein Polar Bear=Eisbär Rabbit=Kaninchen Killer Bunny=Killerkaninchen -The Killer Bunny=Das Killerkaninchen Sheep=Schaf Shulker=Shulker Silverfish=Silberfischchen diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr index c61c09943..240e7759f 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr @@ -28,7 +28,6 @@ Pig=Cerdo Polar Bear=Oso polar Rabbit=Conejo Killer Bunny=Conejo asesino -The Killer Bunny=El Conejo asesino Sheep=Oveja Shulker=Shulker Silverfish=Lepisma diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr index 4c8bd562d..ff1e2b9c0 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr @@ -28,7 +28,6 @@ Pig=Cochon Polar Bear=Ours blanc Rabbit=Lapin Killer Bunny=Lapin tueur -The Killer Bunny=Le Lapin tueur Sheep=Mouton Shulker=Shulker Silverfish=Poisson d'argent diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr index 8857dda97..73807c001 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr @@ -28,7 +28,6 @@ Pig=Свинья Polar Bear=Полярный медведь Rabbit=Кролик Killer Bunny=Кролик-убийца -The Killer Bunny=Кролик-убийца Sheep=Овца Shulker=Шалкер Silverfish=Чешуйница diff --git a/mods/ENTITIES/mobs_mc/models/attributes.txt b/mods/ENTITIES/mobs_mc/models/attributes.txt deleted file mode 100644 index ec59e0f70..000000000 --- a/mods/ENTITIES/mobs_mc/models/attributes.txt +++ /dev/null @@ -1 +0,0 @@ -Ghast fixed by epCode - Thanks! \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_ghast.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_ghast.b3d index ab34f334f..cebc037c0 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_ghast.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_ghast.b3d differ diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index 933d7aad4..5a3f135a1 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -31,8 +31,6 @@ local ocelot = { type = "animal", spawn_class = "passive", can_despawn = true, - rotate = 270, - skittish = true, hp_min = 10, hp_max = 10, xp_min = 1, @@ -45,7 +43,7 @@ local ocelot = { makes_footstep_sound = true, walk_chance = default_walk_chance, walk_velocity = 1, - run_velocity = 10, + run_velocity = 3, follow_velocity = 1, floats = 1, runaway = true, @@ -59,7 +57,7 @@ local ocelot = { }, animation = { speed_normal = 25, - run_speed = 150, + run_speed = 50, stand_start = 0, stand_end = 0, walk_start = 0, @@ -125,6 +123,8 @@ cat.sounds = { } 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.child then return end @@ -151,7 +151,7 @@ end mobs:register_mob("mobs_mc:cat", cat) ---local base_spawn_chance = 5000 +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 diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 88ab54ff5..c04ea77c6 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -20,14 +20,11 @@ mobs:register_mob("mobs_mc:parrot", { hp_max = 6, xp_min = 1, xp_max = 3, - tilt_fly = true, - collisionbox = {-0.25, 0, -0.25, 0.25, 0.9, 0.25}, - eye_height = 0.45, + collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25}, visual = "mesh", mesh = "mobs_mc_parrot.b3d", textures = {{"mobs_mc_parrot_blue.png"},{"mobs_mc_parrot_green.png"},{"mobs_mc_parrot_grey.png"},{"mobs_mc_parrot_red_blue.png"},{"mobs_mc_parrot_yellow_blue.png"}}, visual_size = {x=3, y=3}, - rotate = 270, walk_velocity = 3, run_velocity = 5, sounds = { @@ -44,7 +41,7 @@ mobs:register_mob("mobs_mc:parrot", { max = 2, looting = "common",}, }, - animation = { + animation = { stand_speed = 50, walk_speed = 50, fly_speed = 50, @@ -88,6 +85,8 @@ mobs:register_mob("mobs_mc:parrot", { -- 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 end, }) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 14c9595b6..837d743f0 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -6,8 +6,7 @@ mobs:register_mob("mobs_mc:pig", { description = S("Pig"), type = "animal", spawn_class = "passive", - skittish = true, - rotate = 270, + runaway = true, hp_min = 10, hp_max = 10, xp_min = 1, @@ -20,30 +19,11 @@ mobs:register_mob("mobs_mc:pig", { "mobs_mc_pig.png", -- base "blank.png", -- saddle }}, - - --head code - has_head = true, - head_bone = "head", - - swap_y_with_x = false, - reverse_head_yaw = false, - - head_bone_pos_y = 2.4, - head_bone_pos_z = 0, - - head_height_offset = 1.1, - head_direction_offset = 0, - head_pitch_modifier = 0, - --end head code - visual_size = {x=2.5, y=2.5}, makes_footstep_sound = true, walk_velocity = 1, run_velocity = 3, follow_velocity = 3.4, - breed_distance = 1.5, - baby_size = 0.5, - follow_distance = 2, drops = { {name = mobs_mc.items.porkchop_raw, chance = 1, @@ -70,7 +50,7 @@ mobs:register_mob("mobs_mc:pig", { run_start = 0, run_end = 40, }, - follow = "mcl_farming:carrot_item", + follow = mobs_mc.follow.pig, view_range = 8, do_custom = function(self, dtime) @@ -111,17 +91,12 @@ mobs:register_mob("mobs_mc:pig", { return end - --attempt to enter breed state - if mobs.enter_breed_state(self,clicker) then - return - end - - --ignore other logic - --make baby grow faster - if self.baby then - mobs.make_baby_grow_faster(self,clicker) - return + 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 end + if mobs:protect(self, clicker) then return end if self.child then return @@ -129,8 +104,6 @@ mobs:register_mob("mobs_mc:pig", { -- Put saddle on pig local item = clicker:get_wielded_item() - local wielditem = item - if item:get_name() == mobs_mc.items.saddle and self.saddle ~= "yes" then self.base_texture = { "blank.png", -- baby @@ -163,7 +136,7 @@ mobs:register_mob("mobs_mc:pig", { end -- Mount or detach player - --local name = clicker:get_player_name() + 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}) @@ -191,6 +164,10 @@ mobs:register_mob("mobs_mc:pig", { inv:set_stack("main",self.driver:get_wield_index(), wielditem) end 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) end end, @@ -211,53 +188,42 @@ mobs:spawn_specific( "overworld", "ground", { - "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", - "Mesa", - "FlowerForest", - "Swampland", - "Taiga", - "ExtremeHills", - "Jungle", - "Savanna", - "BirchForest", - "MegaSpruceTaiga", - "MegaTaiga", - "ExtremeHills+", - "Forest", - "Plains", - "Desert", - "ColdTaiga", + "flat", "IcePlainsSpikes", - "SunflowerPlains", - "IcePlains", - "RoofedForest", - "ExtremeHills+_snowtop", - "MesaPlateauFM_grasstop", - "JungleEdgeM", + "ColdTaiga", + "ColdTaiga_beach", + "ColdTaiga_beach_water", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", "ExtremeHillsM", - "JungleM", + "ExtremeHills+", + "ExtremeHills+_snowtop", + "StoneBeach", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", "BirchForestM", - "MesaPlateauF", - "MesaPlateauFM", - "MesaPlateauF_grasstop", - "MesaBryce", - "JungleEdge", + "RoofedForest", + "Savanna", + "Savanna_beach", "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" }, 9, minetest.LIGHT_MAX+1, diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 0476229b5..98268961b 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -31,7 +31,7 @@ mobs:register_mob("mobs_mc:polar_bear", { walk_velocity = 1.2, run_velocity = 2.4, group_attack = true, - attack_type = "punch", + attack_type = "dogfight", drops = { -- 3/4 chance to drop raw fish (poor approximation) {name = mobs_mc.items.fish_raw, diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index 3214925ac..6b47fec70 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -8,7 +8,7 @@ local rabbit = { spawn_class = "passive", passive = true, reach = 1, - rotate = 270, + hp_min = 3, hp_max = 3, xp_min = 1, @@ -62,6 +62,8 @@ local rabbit = { 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 end, do_custom = function(self) -- Easter egg: Change texture if rabbit is named “Toast” @@ -99,7 +101,7 @@ killer_bunny.on_rightclick = nil killer_bunny.run_velocity = 6 killer_bunny.do_custom = function(self) if not self._killer_bunny_nametag_set then - self.nametag = S("The Killer Bunny") + self.nametag = "The Killer Bunny" self._killer_bunny_nametag_set = true end end @@ -114,53 +116,22 @@ mobs:spawn_specific( "overworld", "ground", { - "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", - "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", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", }, 9, minetest.LIGHT_MAX+1, diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index 7e01a1403..f16b64c66 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -63,13 +63,8 @@ mobs:register_mob("mobs_mc:sheep", { hp_max = 8, xp_min = 1, xp_max = 3, - skittish = true, - breed_distance = 1.5, - baby_size = 0.5, - follow_distance = 2, - follow = mobs_mc.items.wheat, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45}, - rotate = 270, + visual = "mesh", visual_size = {x=3, y=3}, mesh = "mobs_mc_sheepfur.b3d", @@ -78,23 +73,6 @@ mobs:register_mob("mobs_mc:sheep", { color = "unicolor_white", makes_footstep_sound = true, walk_velocity = 1, - run_velocity = 3, - - --head code - has_head = true, - head_bone = "head", - - swap_y_with_x = false, - reverse_head_yaw = false, - - head_bone_pos_y = 3.6, - head_bone_pos_z = -0.6, - - head_height_offset = 1.0525, - head_direction_offset = 0.5, - head_pitch_modifier = 0, - --end head code - drops = { {name = mobs_mc.items.mutton_raw, chance = 1, @@ -121,6 +99,7 @@ mobs:register_mob("mobs_mc:sheep", { walk_start = 0, walk_end = 40, run_start = 0, run_end = 40, }, + follow = mobs_mc.follow.sheep, view_range = 12, -- Eat grass @@ -150,6 +129,7 @@ mobs:register_mob("mobs_mc:sheep", { do_custom = function(self, dtime) if not self.initial_color_set then local r = math.random(0,100000) + local textures if r <= 81836 then -- 81.836% self.color = "unicolor_white" @@ -215,16 +195,8 @@ mobs:register_mob("mobs_mc:sheep", { on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() - --attempt to enter breed state - if mobs.enter_breed_state(self,clicker) then - return - end - - --make baby grow faster - if self.baby then - mobs.make_baby_grow_faster(self,clicker) - return - end + if mobs:feed_tame(self, clicker, 1, true, true) then return end + if mobs:protect(self, clicker) then return end if item:get_name() == mobs_mc.items.shears and not self.gotten and not self.child then self.gotten = true @@ -280,6 +252,7 @@ mobs:register_mob("mobs_mc:sheep", { end return end + if 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. @@ -336,53 +309,42 @@ mobs:spawn_specific( "overworld", "ground", { - "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", - "Mesa", - "FlowerForest", - "Swampland", - "Taiga", - "ExtremeHills", - "Jungle", - "Savanna", - "BirchForest", - "MegaSpruceTaiga", - "MegaTaiga", - "ExtremeHills+", - "Forest", - "Plains", - "Desert", - "ColdTaiga", + "flat", "IcePlainsSpikes", - "SunflowerPlains", - "IcePlains", - "RoofedForest", - "ExtremeHills+_snowtop", - "MesaPlateauFM_grasstop", - "JungleEdgeM", + "ColdTaiga", + "ColdTaiga_beach", + "ColdTaiga_beach_water", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", "ExtremeHillsM", - "JungleM", + "ExtremeHills+", + "ExtremeHills+_snowtop", + "StoneBeach", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", "BirchForestM", - "MesaPlateauF", - "MesaPlateauFM", - "MesaPlateauF_grasstop", - "MesaBryce", - "JungleEdge", + "RoofedForest", + "Savanna", + "Savanna_beach", "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" }, 0, minetest.LIGHT_MAX+1, @@ -394,4 +356,3 @@ mobs_mc.spawn_height.overworld_max) -- spawn eggs mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) - diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index 9932c5add..0d5ad880a 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -15,7 +15,7 @@ mobs:register_mob("mobs_mc:shulker", { description = S("Shulker"), type = "monster", spawn_class = "hostile", - attack_type = "projectile", + attack_type = "shoot", shoot_interval = 0.5, arrow = "mobs_mc:shulkerbullet", shoot_offset = 0.5, diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index 05485bc51..5af3c8aa0 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -44,8 +44,9 @@ mobs:register_mob("mobs_mc:silverfish", { run_start = 0, run_end = 20, }, view_range = 16, - attack_type = "punch", + attack_type = "dogfight", damage = 1, + reach = 1, }) mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0) diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index e0aaef215..61e1c6eb2 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -16,37 +16,21 @@ local skeleton = { description = S("Skeleton"), type = "monster", spawn_class = "hostile", - hostile = true, - rotate = 270, hp_min = 20, hp_max = 20, xp_min = 6, xp_max = 6, breath_max = -1, - eye_height = 1.5, - projectile_cooldown = 1.5, armor = {undead = 100, fleshy = 100}, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3}, pathfinding = 1, group_attack = true, visual = "mesh", mesh = "mobs_mc_skeleton.b3d", - - --head code - has_head = false, - head_bone = "head", - - swap_y_with_x = true, - reverse_head_yaw = true, - - head_bone_pos_y = 2.4, - head_bone_pos_z = 0, - - head_height_offset = 1.1, - head_direction_offset = 0, - head_pitch_modifier = 0, - --end head code - + textures = { { + "mcl_bows_bow_0.png", -- bow + "mobs_mc_skeleton.png", -- skeleton + } }, visual_size = {x=1, y=1}, makes_footstep_sound = true, textures = { @@ -59,7 +43,7 @@ local skeleton = { walk_velocity = 1.2, run_velocity = 2.4, damage = 2, - reach = 3, + reach = 2, drops = { {name = mobs_mc.items.arrow, chance = 1, @@ -91,8 +75,6 @@ local skeleton = { walk_speed = 15, walk_start = 40, walk_end = 60, - run_start = 40, - run_end = 60, run_speed = 30, shoot_start = 70, shoot_end = 90, @@ -104,13 +86,13 @@ local skeleton = { ignited_by_sunlight = true, view_range = 16, fear_height = 4, - attack_type = "projectile", + attack_type = "dogshoot", arrow = "mcl_bows:arrow_entity", shoot_arrow = function(self, pos, dir) if mod_bows then -- 2-4 damage per arrow - local dmg = math.random(2,4) - mobs.shoot_projectile_handling("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + 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, diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index 279a1d8cb..1c0bdbea1 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -87,7 +87,7 @@ mobs:register_mob("mobs_mc:witherskeleton", { fire_damage = 0, light_damage = 0, view_range = 16, - attack_type = "punch", + attack_type = "dogfight", dogshoot_switch = 1, dogshoot_count_max =0.5, fear_height = 4, diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 0cae6757d..8d855e761 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -16,7 +16,8 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance if not eject_speed then eject_speed = 1 end - local mother_stuck = minetest.registered_nodes[minetest.get_node(pos).name].walkable + local mndef = minetest.registered_nodes[minetest.get_node(pos).name] + local mother_stuck = mndef and mndef.walkable angle = math.random(0, math.pi*2) local children = {} for i=1,children_count do @@ -26,7 +27,8 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance -- 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 + local cndef = minetest.registered_nodes[minetest.get_node(newpos).name] + if (not mother_stuck) and cndef and cndef.walkable then newpos = pos speed_penalty = 0.5 end @@ -64,7 +66,6 @@ local slime_big = { hp_max = 16, xp_min = 4, xp_max = 4, - rotate = 270, 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", "mobs_mc_slime.png"}}, @@ -96,9 +97,8 @@ local slime_big = { }, fall_damage = 0, view_range = 16, - attack_type = "jump_punch", + attack_type = "dogfight", passive = false, - jump_only = true, jump = true, walk_velocity = 2.5, run_velocity = 2.5, @@ -311,7 +311,6 @@ local magma_cube_big = { }, walk_velocity = 4, run_velocity = 4, - rotate = 270, damage = 6, reach = 3, armor = 53, @@ -335,13 +334,12 @@ local magma_cube_big = { }, water_damage = 0, lava_damage = 0, - fire_damage = 0, + fire_damage = 0, light_damage = 0, fall_damage = 0, view_range = 16, - attack_type = "jump_punch", + attack_type = "dogfight", passive = false, - jump_only = true, jump = true, jump_height = 8, walk_chance = 0, diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg index acb236445..5c9ee492b 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg 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 index 1ef7a5227..acb236445 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg 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 index c2743fbcc..1ef7a5227 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg 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..c2743fbcc 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_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.1.ogg deleted file mode 100644 index 5c9ee492b..000000000 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.1.ogg and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 6ade915ab..c1cb5be4b 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -17,22 +17,17 @@ local spider = { type = "monster", spawn_class = "hostile", passive = false, - hostile = true, - always_climb = true, docile_by_day = true, - attack_type = "punch", - punch_timer_cooloff = 0.5, - rotate = 270, + attack_type = "dogfight", + pathfinding = 1, damage = 2, reach = 2, hp_min = 16, hp_max = 16, - ignores_cobwebs = true, xp_min = 5, xp_max = 5, - eye_height = 0.475, armor = {fleshy = 100, arthropod = 100}, - collisionbox = {-0.45, 0, -0.45, 0.45, 0.9, 0.45}, + collisionbox = {-0.7, -0.01, -0.7, 0.7, 0.89, 0.7}, visual = "mesh", mesh = "mobs_mc_spider.b3d", textures = { @@ -49,7 +44,7 @@ local spider = { distance = 16, }, walk_velocity = 1.3, - run_velocity = 2.75, --spider can become extremely difficult if any higher + run_velocity = 2.8, jump = true, jump_height = 4, view_range = 16, diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index 55d4b05c3..0c425bb51 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -17,8 +17,6 @@ mobs:register_mob("mobs_mc:squid", { xp_min = 1, xp_max = 3, armor = 100, - rotate = 270, - tilt_swim = true, -- FIXME: If the squid is near the floor, it turns black collisionbox = {-0.4, 0.0, -0.4, 0.4, 0.9, 0.4}, visual = "mesh", @@ -50,7 +48,8 @@ mobs:register_mob("mobs_mc:squid", { }, visual_size = {x=3, y=3}, makes_footstep_sound = false, - swim = true, + fly = true, + fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, breathes_in_water = true, jump = false, view_range = 16, diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_chest.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_chest.png deleted file mode 100644 index e0715af9f..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_chest.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_black.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_black.png deleted file mode 100644 index 40c39648f..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_black.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_blue.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_blue.png deleted file mode 100644 index b02c41b26..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_blue.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_brown.png deleted file mode 100644 index 2c7c71c2f..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_brown.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_cyan.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_cyan.png deleted file mode 100644 index 83f7a8faa..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_cyan.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_gray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_gray.png deleted file mode 100644 index a4bd9cb1f..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_gray.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_green.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_green.png deleted file mode 100644 index c3297ce94..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_green.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_blue.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_blue.png deleted file mode 100644 index 71eabea53..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_blue.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_gray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_gray.png deleted file mode 100644 index 929a60950..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_gray.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_lime.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_lime.png deleted file mode 100644 index 1507d6d79..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_lime.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_magenta.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_magenta.png deleted file mode 100644 index 809e645fb..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_magenta.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_orange.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_orange.png deleted file mode 100644 index ff17ff67c..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_orange.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_pink.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_pink.png deleted file mode 100644 index 7009e6efc..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_pink.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_purple.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_purple.png deleted file mode 100644 index 1de65a407..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_purple.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_red.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_red.png deleted file mode 100644 index 645df4977..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_red.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_white.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_white.png deleted file mode 100644 index c6ae669dd..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_white.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_yellow.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_yellow.png deleted file mode 100644 index 6318e163d..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_yellow.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spit.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spit.png deleted file mode 100644 index 6cdb3e0b3..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spit.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/vex.lua b/mods/ENTITIES/mobs_mc/vex.lua index da162e5bf..a72827d5d 100644 --- a/mods/ENTITIES/mobs_mc/vex.lua +++ b/mods/ENTITIES/mobs_mc/vex.lua @@ -36,6 +36,7 @@ mobs:register_mob("mobs_mc:vex", { view_range = 16, walk_velocity = 3.2, run_velocity = 5.9, + attack_type = "dogfight", sounds = { -- TODO: random death = "mobs_mc_vex_death", diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 4e4b40553..7fed4cbf8 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -195,7 +195,7 @@ local professions = { { -- TODO: replace with empty map - { { "mcl_core:emerald", 7, 11}, { "mcl_maps:empty_map", 1, 1 } }, + { { "mcl_core:emerald", 7, 11}, { "mcl_maps:filled_map", 1, 1 } }, }, -- TODO: special maps @@ -409,7 +409,7 @@ 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) @@ -962,18 +962,14 @@ mobs:register_mob("mobs_mc:villager", { }, }, visual_size = {x=2.75, y=2.75}, - rotate = 270, - skittish = true, makes_footstep_sound = true, walk_velocity = 1.2, - run_velocity = 3, + run_velocity = 2.4, drops = {}, can_despawn = false, -- TODO: sounds sounds = { random = "mobs_mc_villager", - damage = "mobs_mc_villager_hurt", - death = "mobs_mc_villager_hurt", distance = 10, }, animation = { diff --git a/mods/ENTITIES/mobs_mc/villager_evoker.lua b/mods/ENTITIES/mobs_mc/villager_evoker.lua index f87483e2b..04c95b88f 100644 --- a/mods/ENTITIES/mobs_mc/villager_evoker.lua +++ b/mods/ENTITIES/mobs_mc/villager_evoker.lua @@ -35,7 +35,7 @@ mobs:register_mob("mobs_mc:evoker", { walk_velocity = 0.2, run_velocity = 1.4, group_attack = true, - attack_type = "punch", + attack_type = "dogfight", -- Summon vexes custom_attack = function(self, to_attack) local r = pr:next(2,4) diff --git a/mods/ENTITIES/mobs_mc/villager_illusioner.lua b/mods/ENTITIES/mobs_mc/villager_illusioner.lua index 46b8760a1..496f08fc6 100644 --- a/mods/ENTITIES/mobs_mc/villager_illusioner.lua +++ b/mods/ENTITIES/mobs_mc/villager_illusioner.lua @@ -10,7 +10,7 @@ mobs:register_mob("mobs_mc:illusioner", { description = S("Illusioner"), type = "monster", spawn_class = "hostile", - attack_type = "projectile", + attack_type = "shoot", shoot_interval = 2.5, shoot_offset = 1.5, arrow = "mcl_bows:arrow_entity", @@ -18,7 +18,7 @@ mobs:register_mob("mobs_mc:illusioner", { if mod_bows then -- 1-4 damage per arrow local dmg = math.random(1, 4) - mobs.shoot_projectile_handling("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + mcl_bows.shoot_arrow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) end end, hp_min = 32, diff --git a/mods/ENTITIES/mobs_mc/villager_vindicator.lua b/mods/ENTITIES/mobs_mc/villager_vindicator.lua index 7df54ef58..276f80011 100644 --- a/mods/ENTITIES/mobs_mc/villager_vindicator.lua +++ b/mods/ENTITIES/mobs_mc/villager_vindicator.lua @@ -37,7 +37,7 @@ mobs:register_mob("mobs_mc:vindicator", { reach = 2, walk_velocity = 1.2, run_velocity = 2.4, - attack_type = "punch", + attack_type = "dogfight", drops = { {name = mobs_mc.items.emerald, chance = 1, diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index 450710c49..1948b693d 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -29,9 +29,6 @@ mobs:register_mob("mobs_mc:villager_zombie", { description = S("Zombie Villager"), type = "monster", spawn_class = "hostile", - hostile = true, - rotate = 270, - eye_height = 1.65, hp_min = 20, hp_max = 20, xp_min = 5, @@ -54,8 +51,8 @@ mobs:register_mob("mobs_mc:villager_zombie", { damage = 3, reach = 2, walk_velocity = 1.2, - run_velocity = 3.5, - attack_type = "punch", + run_velocity = 2.4, + attack_type = "dogfight", group_attack = true, drops = { {name = mobs_mc.items.rotten_flesh, diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index 0c72d0018..8ebe71fc0 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -34,7 +34,7 @@ mobs:register_mob("mobs_mc:witch", { run_velocity = 2.4, pathfinding = 1, group_attack = true, - attack_type = "projectile", + attack_type = "dogshoot", arrow = "mobs_mc:potion_arrow", shoot_interval = 2.5, shoot_offset = 1, diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 8bd8f5341..72459a354 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -26,6 +26,7 @@ mobs:register_mob("mobs_mc:wither", { {"mobs_mc_wither.png"}, }, visual_size = {x=4, y=4}, + makes_footstep_sound = true, view_range = 16, fear_height = 4, walk_velocity = 2, @@ -52,7 +53,7 @@ mobs:register_mob("mobs_mc:wither", { }, lava_damage = 0, fire_damage = 0, - attack_type = "projectile", + attack_type = "dogshoot", explosion_strength = 8, dogshoot_stop = true, arrow = "mobs_mc:wither_skull", @@ -80,7 +81,7 @@ mobs:register_mob("mobs_mc:wither", { end, }) ---local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false +local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false mobs:register_arrow("mobs_mc:wither_skull", { visual = "sprite", diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index 2ce142c33..7f14ac6b0 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -23,31 +23,13 @@ local wolf = { type = "animal", spawn_class = "passive", can_despawn = true, - neutral = true, hp_min = 8, hp_max = 8, xp_min = 1, xp_max = 3, - rotate = 270, passive = false, group_attack = true, - - --head code - has_head = false, - head_bone = "head", - - swap_y_with_x = false, - reverse_head_yaw = false, - - head_bone_pos_y = 3.6, - head_bone_pos_z = -0.6, - - head_height_offset = 1.0525, - head_direction_offset = 0.5, - head_pitch_modifier = 0, - --end head code - - collisionbox = {-0.3, -0.00, -0.3, 0.3, 0.85, 0.3}, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3}, visual = "mesh", mesh = "mobs_mc_wolf.b3d", textures = { @@ -71,7 +53,7 @@ local wolf = { run_velocity = 3, damage = 4, reach = 2, - attack_type = "punch", + attack_type = "dogfight", fear_height = 4, follow = mobs_mc.follow.wolf, on_rightclick = function(self, clicker) @@ -93,7 +75,6 @@ local wolf = { dog:set_yaw(yaw) ent = dog:get_luaentity() ent.owner = clicker:get_player_name() - ent.tamed = true -- cornfirm taming minetest.sound_play("mobs_mc_wolf_bark", {object=dog, max_hear_distance=16}, true) -- Replace wolf @@ -161,32 +142,20 @@ dog.owner_loyal = true 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.attack_animals = nil dog.specific_attack = nil -dog.breed_distance = 1.5 -dog.baby_size = 0.5 -dog.follow_distance = 2 -dog.follow = "mcl_mobitems:beef" - dog.on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() - --owner is broken for this - --attempt to enter breed state - if mobs.enter_breed_state(self,clicker) then + if mobs:protect(self, clicker) then return - end - - --make baby grow faster - if self.baby then - mobs.make_baby_grow_faster(self,clicker) + elseif item:get_name() ~= "" and mobs:capture_mob(self, clicker, 0, 2, 80, false, nil) then return - end - - if is_food(item:get_name()) then + elseif is_food(item:get_name()) then -- Feed to increase health local hp = self.health - local hp_add + local hp_add = 0 -- Use eatable group to determine health boost local eatable = minetest.get_item_group(item, "eatable") if eatable > 0 then diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index 7d0fb1491..4ae5796b3 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -49,8 +49,6 @@ local zombie = { description = S("Zombie"), type = "monster", spawn_class = "hostile", - hostile = true, - rotate = 270, hp_min = 20, hp_max = 20, xp_min = 5, @@ -76,25 +74,8 @@ local zombie = { damage = "mobs_mc_zombie_hurt", distance = 16, }, - - --head code - has_head = false, - head_bone = "Head", - - swap_y_with_x = true, - reverse_head_yaw = true, - - head_bone_pos_y = 2.4, - head_bone_pos_z = 0, - - head_height_offset = 1.1, - head_direction_offset = 0, - head_pitch_modifier = 0, - --end head code - - eye_height = 1.65, - walk_velocity = 1, - run_velocity = 3.5, + walk_velocity = .8, + run_velocity = 1.6, damage = 3, reach = 2, fear_height = 4, @@ -112,8 +93,7 @@ local zombie = { ignited_by_sunlight = true, sunlight_damage = 2, view_range = 16, - attack_type = "punch", - punch_timer_cooloff = 0.5, + attack_type = "dogfight", harmed_by_heal = true, } diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua index 72a19f413..1ea4197c1 100644 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ b/mods/ENTITIES/mobs_mc/zombiepig.lua @@ -15,16 +15,13 @@ local pigman = { -- type="animal", passive=false: This combination is needed for a neutral mob which becomes hostile, if attacked type = "animal", passive = false, - neutral = true, - rotate = 270, spawn_class = "passive", - hostile_cooldown = 15, --seconds hp_min = 20, hp_max = 20, xp_min = 6, xp_max = 6, armor = {undead = 90, fleshy = 90}, - attack_type = "punch", + attack_type = "dogfight", group_attack = { "mobs_mc:pigman", "mobs_mc:baby_pigman" }, damage = 9, reach = 2, @@ -44,22 +41,6 @@ local pigman = { damage = "mobs_mc_zombiepig_hurt", distance = 16, }, - - --head code - has_head = false, - head_bone = "head", - - swap_y_with_x = true, - reverse_head_yaw = true, - - head_bone_pos_y = 2.4, - head_bone_pos_z = 0, - - head_height_offset = 1.1, - head_direction_offset = 0, - head_pitch_modifier = 0, - --end head code - jump = true, makes_footstep_sound = true, walk_velocity = .8, diff --git a/mods/ENTITIES/mobs_mc_gameconfig/init.lua b/mods/ENTITIES/mobs_mc_gameconfig/init.lua index 27cb4b4bf..06d7eb87f 100644 --- a/mods/ENTITIES/mobs_mc_gameconfig/init.lua +++ b/mods/ENTITIES/mobs_mc_gameconfig/init.lua @@ -200,14 +200,14 @@ 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)", - }, + ["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 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/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 2b79bf5ce..3579316e8 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,7 +10,7 @@ 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()) local get_connected_players = minetest.get_connected_players local line_of_sight = minetest.line_of_sight @@ -22,22 +23,23 @@ 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 = {} - -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 @@ -53,6 +55,18 @@ 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 @@ -78,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 = 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 = 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 @@ -93,10 +107,9 @@ 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) +function lightning.strike(pos) if lightning.auto then after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) end @@ -107,21 +120,28 @@ lightning.strike = function(pos) if not pos then return false end + local objects = get_objects_inside_radius(pos2, 3.5) + if lightning.on_strike_functions then + for _, func in pairs(lightning.on_strike_functions) do + func(pos, pos2, objects) + end + end +end +lightning.register_on_strike(function(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 @@ -134,44 +154,27 @@ lightning.strike = function(pos) sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true) -- damage nearby objects, transform mobs - -- TODO: use an API insteed of hardcoding this behaviour - local objs = 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() - -- pig → zombie pigman (no damage) + if lua and lua._on_strike then + lua._on_strike(lua, pos, pos2, objects) + end + -- remove this when mob API is done if lua and lua.name == "mobs_mc:pig" then - local rot = obj:get_yaw() - obj:remove() - obj = add_entity(pos2, "mobs_mc:pigman") - obj:set_yaw(rot) - -- mooshroom: toggle color red/brown (no damage) + mcl_util.replace_mob(obj, "mobs_mc:pigman") elseif lua and 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 and 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) - ]] - -- charged creeper + obj:set_properties({ textures = lua.base_texture }) + elseif lua and lua.name == "mobs_mc:villager" then + mcl_util.replace_mob(obj, "mobs_mc:witch") elseif lua and lua.name == "mobs_mc:creeper" then - local rot = obj:get_yaw() - obj:remove() - obj = add_entity(pos2, "mobs_mc:creeper_charged") - obj:set_yaw(rot) - -- Other objects: Just damage + mcl_util.replace_mob(obj, "mobs_mc:creeper_charged") else - mcl_util.deal_damage(obj, 5, {type = "lightning_bolt"}) + mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" }) end end @@ -185,7 +188,7 @@ lightning.strike = function(pos) 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 @@ -200,7 +203,7 @@ lightning.strike = function(pos) if rng:next(1,100) <= 3 then skeleton_lightning = true end - if get_item_group(get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 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 @@ -209,21 +212,22 @@ lightning.strike = function(pos) 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 = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton") - mob:set_yaw(angle-math.pi/2) + if mob then + mob:set_yaw(angle-math.pi/2) + end angle = angle + (math.pi*2) / 3 end -- Cause a fire else - set_node(pos2, {name = "mcl_fire:fire"}) + set_node(pos2, { name = "mcl_fire:fire" }) end end end - -end +end) -- if other mods disable auto lightning during initialization, don't trigger the first lightning. after(5, function(dtime) 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/mcl_void_damage/init.lua b/mods/ENVIRONMENT/mcl_void_damage/init.lua index c3819c1da..084028dd1 100644 --- a/mods/ENVIRONMENT/mcl_void_damage/init.lua +++ b/mods/ENVIRONMENT/mcl_void_damage/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_void_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 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_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.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/nether_dust.lua b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua index 16cdc9487..4ab9e4081 100644 --- a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua +++ b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua @@ -1,36 +1,66 @@ 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 psdef= { + amount = 150, + 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 + +mcl_weather.nether_dust.add_particlespawners = function(player) + local name=player:get_player_name(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 -local timer = 0 -minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer < 0.7 then return end - timer = 0 - - for _, player in pairs(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(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 c128da942..0caef5c6f 100644 --- a/mods/ENVIRONMENT/mcl_weather/rain.lua +++ b/mods/ENVIRONMENT/mcl_weather/rain.lua @@ -1,5 +1,5 @@ -local PARTICLES_COUNT_RAIN = 30 -local PARTICLES_COUNT_THUNDER = 45 +local PARTICLES_COUNT_RAIN = 100 +local PARTICLES_COUNT_THUNDER = 300 local get_connected_players = minetest.get_connected_players @@ -19,6 +19,45 @@ mcl_weather.rain = { init_done = false, } +local update_sound={} +local vel=math.random(0,3) +local falling_speed=math.random(10,15) +local size = math.random(1,3) +local psdef= { + amount = mcl_weather.rain.particles_count, + time=0, + minpos = vector.new(-6,3,-6), + maxpos = vector.new(6,15,6), + minvel = vector.new(-vel,-falling_speed,-vel), + maxvel = vector.new(vel,-falling_speed+vel,vel), + minacc = vector.new(0,0,0), + maxacc = vector.new(0,-0.4,0), + minexptime = 0.5, + maxexptime = 2, + minsize = size, + maxsize= size*2, + collisiondetection = true, + collision_removal = true, + vertical = true, +} +local psdef_backsplash= { + amount = 10, + time=0, + minpos = vector.new(-3,-1,-3), + maxpos = vector.new(3,0,3), + minvel = vector.new(-vel,falling_speed*2,-vel), + maxvel = vector.new(vel,falling_speed*2+vel,vel), + minacc = vector.new(0,0,0), + maxacc = vector.new(0,0,0), + minexptime = 0.1, + maxexptime = 0.2, + minsize = size*0.1, + maxsize= size*0.5, + collisiondetection = true, + collision_removal = true, + vertical = true, +} +local textures = {"weather_pack_rain_raindrop_1.png", "weather_pack_rain_raindrop_2.png", "weather_pack_rain_raindrop_1.png"} function mcl_weather.rain.sound_handler(player) return minetest.sound_play("weather_rain", { @@ -44,42 +83,18 @@ function mcl_weather.rain.set_sky_box() end end --- creating manually parctiles instead of particles spawner because of easier to control --- spawn position. +-- 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 = 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 + mcl_weather.rain.last_rp_count = mcl_weather.rain.particles_count + for k,v in pairs(textures) do + psdef.texture=v + mcl_weather.add_spawner_player(player,"rain"..k,psdef) end -end - --- Simple random texture getter -function mcl_weather.rain.get_texture() - 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" + psdef_backsplash.texture=textures[math.random(1,#textures)] + local l=mcl_weather.add_spawner_player(player,"rainbacksplash",psdef_backsplash) + if l then + update_sound[player:get_player_name()]=true end - return texture_name; end -- register player for rain weather. @@ -89,6 +104,7 @@ function mcl_weather.rain.add_player(player) local player_meta = {} player_meta.origin_sky = {player:get_sky()} mcl_weather.players[player:get_player_name()] = player_meta + update_sound[player:get_player_name()]=true end end @@ -96,36 +112,25 @@ end -- be sure to remove sound before removing player otherwise soundhandler reference will be lost. 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. 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 @@ -136,12 +141,13 @@ function mcl_weather.rain.update_sound(player) player_meta.sound_updated = minetest.get_gametime() end + update_sound[player:get_player_name()]=false end -- rain sound removed from 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 @@ -158,7 +164,8 @@ function mcl_weather.rain.clear() for _, player in pairs(get_connected_players()) do mcl_weather.rain.remove_sound(player) mcl_weather.rain.remove_player(player) - end + mcl_weather.remove_spawners_player(player) + end end minetest.register_globalstep(function(dtime) @@ -177,8 +184,10 @@ function mcl_weather.rain.make_weather() end for _, player in pairs(get_connected_players()) do - if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then + local pos=player:get_pos() + if mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(pos) or not mcl_weather.is_outdoor(pos) then mcl_weather.rain.remove_sound(player) + mcl_weather.remove_spawners_player(player) return false end mcl_weather.rain.add_player(player) @@ -190,8 +199,12 @@ end -- Switch the number of raindrops: "thunder" for many raindrops, otherwise for normal raindrops function mcl_weather.rain.set_particles_mode(mode) if mode == "thunder" then + psdef.amount=PARTICLES_COUNT_THUNDER + psdef_backsplash.amount=PARTICLES_COUNT_THUNDER mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER else + psdef.amount=PARTICLES_COUNT_RAIN + psdef_backsplash.amount=PARTICLES_COUNT_RAIN mcl_weather.rain.particles_count = PARTICLES_COUNT_RAIN end end diff --git a/mods/ENVIRONMENT/mcl_weather/skycolor.lua b/mods/ENVIRONMENT/mcl_weather/skycolor.lua index 488f6b1a1..7b6183d44 100644 --- a/mods/ENVIRONMENT/mcl_weather/skycolor.lua +++ b/mods/ENVIRONMENT/mcl_weather/skycolor.lua @@ -235,13 +235,12 @@ minetest.register_globalstep(function(dtime) end) -local initsky = function(player) +local function initsky(player) 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 9ec9fbac1..b60283127 100644 --- a/mods/ENVIRONMENT/mcl_weather/snow.lua +++ b/mods/ENVIRONMENT/mcl_weather/snow.lua @@ -5,32 +5,27 @@ mcl_weather.snow = {} mcl_weather.snow.particles_count = 15 mcl_weather.snow.init_done = false --- 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_z = mcl_weather.get_random_pos_by_player_look_dir(player) - local 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 -end +local psdef= { + amount = 99, + time = 0, --stay on til we turn it off + minpos = vector.new(-15,-5,-15), + maxpos =vector.new(15,10,15), + minvel = vector.new(0,-1,0), + maxvel = vector.new(0,-4,0), + minacc = vector.new(0,-1,0), + maxacc = vector.new(0,-4,0), + minexptime = 1, + maxexptime = 1, + minsize = 0.5, + maxsize = 5, + collisiondetection = true, + collision_removal = true, + object_collision = true, + vertical = true, + glow = 1 +} -mcl_weather.snow.set_sky_box = function() +function mcl_weather.snow.set_sky_box() mcl_weather.skycolor.add_layer( "weather-pack-snow-sky", {{r=0, g=0, b=0}, @@ -48,6 +43,7 @@ end 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 @@ -74,10 +70,14 @@ minetest.register_globalstep(function(dtime) end for _, player in pairs(get_connected_players()) do - if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then + if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos()) or not mcl_weather.is_outdoor(player:get_pos())) then + mcl_weather.remove_spawners_player(player) return false end - mcl_weather.snow.add_snow_particles(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 end) diff --git a/mods/ENVIRONMENT/mcl_weather/weather_core.lua b/mods/ENVIRONMENT/mcl_weather/weather_core.lua index b8deba318..f7316bcfb 100644 --- a/mods/ENVIRONMENT/mcl_weather/weather_core.lua +++ b/mods/ENVIRONMENT/mcl_weather/weather_core.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_weather") +local S = minetest.get_translator(minetest.get_current_modname()) local math = math @@ -39,7 +39,7 @@ 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) @@ -47,9 +47,38 @@ local save_weather = function() 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 + 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) @@ -57,7 +86,7 @@ mcl_weather.get_rand_end_time = function(min_duration, max_duration) 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 @@ -68,7 +97,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 @@ -79,7 +108,7 @@ 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, @@ -92,37 +121,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, random_pos_y, random_pos_z - - 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 @@ -146,7 +146,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) @@ -166,11 +166,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 @@ -199,7 +199,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 @@ -268,12 +268,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 -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/HELP/doc/doc/init.lua b/mods/HELP/doc/doc/init.lua index a04d83bda..304900753 100644 --- a/mods/HELP/doc/doc/init.lua +++ b/mods/HELP/doc/doc/init.lua @@ -1,6 +1,10 @@ -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 +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 = {} @@ -63,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 @@ -93,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 @@ -123,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 @@ -177,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 @@ -224,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) @@ -427,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 @@ -448,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 @@ -476,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 @@ -502,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 = "" @@ -591,7 +595,7 @@ doc.widgets.gallery = function(imagedata, playername, x, y, aspect_ratio, width, end -- Direct formspec -doc.entry_builders.formspec = function(data) +function doc.entry_builders.formspec(data) return data end @@ -605,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] = {} @@ -672,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 @@ -701,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 @@ -711,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") @@ -802,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 @@ -944,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 @@ -959,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" @@ -984,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 @@ -1014,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 @@ -1040,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) @@ -1101,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 @@ -1169,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", @@ -1190,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.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_identifier/init.lua b/mods/HELP/doc/doc_identifier/init.lua index a3a35e2fa..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,7 +69,7 @@ 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 + if minetest.registered_nodes[node.name] then --local nodedef = minetest.registered_nodes[node.name] if(node.name == "ignore") then show_message(username, "error_ignore") @@ -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,7 +198,7 @@ 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" }, 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_items/init.lua b/mods/HELP/doc/doc_items/init.lua index edba0dae3..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 = "" @@ -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" @@ -597,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" @@ -617,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" @@ -630,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 @@ -652,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) @@ -756,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 @@ -771,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]) @@ -779,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") @@ -810,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 @@ -828,7 +838,7 @@ 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 @@ -882,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) @@ -904,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) @@ -953,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) @@ -988,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 @@ -1051,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 @@ -1156,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 @@ -1169,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 @@ -1184,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) @@ -1203,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 @@ -1232,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 @@ -1297,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 @@ -1323,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 @@ -1332,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) @@ -1340,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) @@ -1348,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) @@ -1360,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) @@ -1368,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 @@ -1380,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.fr.tr b/mods/HELP/doc/doc_items/locale/doc_items.fr.tr index 5d655404d..824ceeeba 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×@ # Itemname (25%) @1 (@2%)=@1 (@2%) # Itemname (<0.5%) 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/mcl_craftguide/init.lua b/mods/HELP/mcl_craftguide/init.lua index bfaef6011..5e3686047 100644 --- a/mods/HELP/mcl_craftguide/init.lua +++ b/mods/HELP/mcl_craftguide/init.lua @@ -155,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") @@ -548,7 +548,7 @@ local function get_recipe_fs(data, iY) 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 @@ -726,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 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/textures/craftguide_furnace.png b/mods/HELP/mcl_craftguide/textures/craftguide_furnace.png new file mode 100644 index 000000000..c425604d2 Binary files /dev/null and b/mods/HELP/mcl_craftguide/textures/craftguide_furnace.png differ diff --git a/mods/HELP/mcl_doc/init.lua b/mods/HELP/mcl_doc/init.lua index fa6ae6c05..9be688ec2 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") @@ -50,8 +50,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) @@ -399,7 +399,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 @@ -408,7 +408,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.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_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.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_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..f3e6d2735 --- /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/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.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/snippets_base.lua b/mods/HELP/mcl_tt/snippets_base.lua index bd5495721..4e200d539 100644 --- a/mods/HELP/mcl_tt/snippets_base.lua +++ b/mods/HELP/mcl_tt/snippets_base.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_tt") +local S = minetest.get_translator(minetest.get_current_modname()) --[[local function get_min_digtime(caps) local mintime diff --git a/mods/HELP/mcl_tt/snippets_mcl.lua b/mods/HELP/mcl_tt/snippets_mcl.lua index b10021640..825776f5f 100644 --- a/mods/HELP/mcl_tt/snippets_mcl.lua +++ b/mods/HELP/mcl_tt/snippets_mcl.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_tt") +local S = minetest.get_translator(minetest.get_current_modname()) -- Armor tt.register_snippet(function(itemstring) @@ -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 a5ae24a35..f2b83b612 100644 --- a/mods/HELP/tt/init.lua +++ b/mods/HELP/tt/init.lua @@ -7,11 +7,11 @@ 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 -tt.register_priority_snippet = function(func) +function tt.register_priority_snippet(func) table.insert(tt.registered_snippets, 1, func) end @@ -43,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() @@ -60,7 +60,7 @@ 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() @@ -76,8 +76,6 @@ tt.reload_itemstack_description = function(itemstack) 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) - if desc ~= orig_desc then - meta:set_string("description", desc) - end + meta:set_string("description", desc) end end diff --git a/mods/HUD/awards/api.lua b/mods/HUD/awards/api.lua index d795f0dca..49b11a6cf 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 diff --git a/mods/HUD/awards/chat_commands.lua b/mods/HUD/awards/chat_commands.lua index 88e799dfe..88bed0afe 100644 --- a/mods/HUD/awards/chat_commands.lua +++ b/mods/HUD/awards/chat_commands.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()) minetest.register_chatcommand("awards", { params = S("[c|clear|disable|enable]"), 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.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/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/triggers.lua b/mods/HUD/awards/triggers.lua index 995dd005c..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 = { @@ -382,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/hudbars/default_settings.lua b/mods/HUD/hudbars/default_settings.lua index ce43cc8be..865a7cb6a 100644 --- a/mods/HUD/hudbars/default_settings.lua +++ b/mods/HUD/hudbars/default_settings.lua @@ -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 a88d14dcf..505ff403b 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -27,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 @@ -114,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 @@ -179,7 +179,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction, 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 @@ -215,7 +215,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, direction, 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, @@ -335,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 @@ -343,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 @@ -353,29 +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 @@ -425,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}) @@ -443,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 @@ -548,7 +550,7 @@ local function update_hud(player, has_damage) 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) 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/mcl_achievements/init.lua b/mods/HUD/mcl_achievements/init.lua index 2f1db1fe6..c963773d1 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 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..78ab53f82 --- /dev/null +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.pl.tr @@ -0,0 +1,50 @@ +# textdomain:mcl_achievements +Aquire 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_credits/init.lua b/mods/HUD/mcl_credits/init.lua index 294373875..db3ac8436 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -1,122 +1,10 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + mcl_credits = { players = {}, -} - -mcl_credits.description = "A faithful Open Source clone of Minecraft" - --- Sub-lists are sorted by number of commits, but the list should not be rearranged (-> new contributors are just added at the end of the list) -mcl_credits.people = { - {"Creator of MineClone", 0x0A9400, { - "davedevils", - }}, - {"Creator of MineClone2", 0xFBF837, { - "Wuzzy", - }}, - {"Maintainers", 0xFF51D5, { - "Fleckenstein", - "kay27", - "oilboi", - }}, - {"Developers", 0xF84355, { - "bzoss", - "AFCMS", - "epCode", - "ryvnf", - "iliekprogrammar", - "MysticTempest", - "Rootyjr", - "Nicu", - "aligator", - "Code-Sploit", - "NO11", - }}, - {"Contributors", 0x52FF00, { - "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", - "ztianyang", - "j45", - }}, - {"MineClone5", 0xA60014, { - "kay27", - "Debiankaios", - "epCode", - "NO11", - "j45", - }}, - {"Original Mod Authors", 0x343434, { - "Wuzzy", - "Fleckenstein", - "BlockMen", - "TenPlus1", - "PilzAdam", - "ryvnf", - "stujones11", - "Arcelmi", - "celeron55", - "maikerumine", - "GunshipPenguin", - "Qwertymine3", - "Rochambeau", - "rubenwardy", - "stu", - "oilboi", - "4aiman", - "Kahrl", - "Krock", - "UgnilJoZ", - "lordfingle", - "22i", - "bzoss", - "kilbith", - "xeranas", - "kddekadenz", - "sofar", - "4Evergreen4", - "jordan4ibanez", - "paramat", - }}, - {"3D Models", 0x0019FF, { - "22i", - "tobyplowy", - "epCode", - }}, - {"Textures", 0xFF9705, { - "XSSheep", - "Wuzzy", - "kingoscargames", - "leorockway", - "xMrVizzy", - "yutyo", - "NO11", - }}, - {"Translations", 0x00FF60, { - "Wuzzy", - "Rocher Laurent", - "wuniversales", - "kay27", - "pitchum", - }}, + 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) @@ -142,7 +30,7 @@ function mcl_credits.show(player) ids = { player:hud_add({ hud_elem_type = "image", - text = "menu_bg.png", + text = "credits_bg.png", position = {x = 0, y = 0}, alignment = {x = 1, y = 1}, scale = {x = -100, y = -100}, @@ -150,13 +38,22 @@ function mcl_credits.show(player) }), player:hud_add({ hud_elem_type = "text", - text = "Sneak to skip", + 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({ @@ -216,13 +113,22 @@ end) minetest.register_globalstep(function(dtime) for _, huds in pairs(mcl_credits.players) do local player = huds.player - if not huds.new and player:get_player_control().sneak then + 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) 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.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/people.lua b/mods/HUD/mcl_credits/people.lua new file mode 100644 index 000000000..8f1d4c2e9 --- /dev/null +++ b/mods/HUD/mcl_credits/people.lua @@ -0,0 +1,144 @@ +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, { + "Fleckenstein", + "Nicu", + "kay27", + }}, + {S("Developers"), 0xF84355, { + "bzoss", + "AFCMS", + "epCode", + "ryvnf", + "iliekprogrammar", + "MysticTempest", + "Rootyjr", + "aligator", + "Code-Sploit", + "NO11", + "cora", + "jordan4ibanez", + }}, + {S("Contributors"), 0x52FF00, { + "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", + "Benjamin Schötz", + "Doloment", + "Sydney Gems", + "talamh", + "Emily2255", + "Emojigit", + "FinishedFragment", + "sfan5", + "Blue Blancmange", + "Jared Moody", + "SmallJoker", + "Sven792", + "aldum", + }}, + {S("MineClone5"), 0xA60014, { + "kay27", + "Debiankaios", + "epCode", + "NO11", + "j45", + }}, + {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", + }}, + {S("3D Models"), 0x0019FF, { + "22i", + "tobyplowy", + "epCode", + }}, + {S("Textures"), 0xFF9705, { + "XSSheep", + "Wuzzy", + "kingoscargames", + "leorockway", + "xMrVizzy", + "yutyo", + "NO11", + "kay27", + }}, + {S("Translations"), 0x00FF60, { + "Wuzzy", + "Rocher Laurent", + "wuniversales", + "kay27", + "pitchum", + "todoporlalibertad", + "Marcin Serwin", + }}, + {S("Funders"), 0xF7FF00, { + "40W", + }}, + {S("Special thanks"), 0x00E9FF, { + "celeron55 for creating Minetest", + "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", + }}, +} diff --git a/mods/HUD/mcl_credits/textures/credits_bg.png b/mods/HUD/mcl_credits/textures/credits_bg.png new file mode 100644 index 000000000..ad74cbd30 Binary files /dev/null and b/mods/HUD/mcl_credits/textures/credits_bg.png differ diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index 107daa2a3..91e13995b 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_death_messages") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_death_messages = { assist = {}, 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..65fcde760 --- /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 was killed by @3 trying to hurt @2=@1 została zabita przez @3 gdy próbowała skrzywdzić @2 +@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 from @3 by @2=@1 odeszła z hukiem przez fajerwerki wystrzelone z @3 przez @2 + diff --git a/mods/HUD/mcl_experience/bottle.lua b/mods/HUD/mcl_experience/bottle.lua new file mode 100644 index 000000000..17a70054d --- /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 = "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 a40599d17..aea805fa2 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -1,641 +1,227 @@ -local S = minetest.get_translator("mcl_experience") - -mcl_experience = {} - -local vector = vector -local math = math -local string = string - -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() - if minetest.is_creative_enabled(name) then - return - end - 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 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}, - } - 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 = experience * multiplier - local new_wear = wear - repair - if new_wear < 0 then - experience = math.floor(-new_wear / multiplier + 0.5) - new_wear = 0 - else - experience = 0 - end - stack:set_wear(math.floor(new_wear)) - inv:set_stack(list, index, stack) - end + return xp_min + bar * (xp_max - xp_min) +end - 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) +local function get_time() + return minetest.get_us_time() / 1000000 +end - if (temp_pool.xp < temp_pool.xp_next_level) and (temp_pool.xp >= old_xp) then - temp_pool.bar = temp_pool.bar + temp_pool.bar_step * experience - 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 +-- api - 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 +function mcl_experience.get_level(player) + return caches[player].level +end - 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.set_level(player, level) + local cache = caches[player] - if old_level ~= temp_pool.level then - hud_manager.change_hud({player = player, hud_name = "xp_level", element = "text", data = tostring(temp_pool.level)}) + 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 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_experience(collector, self._xp) - 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)) + + 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 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_item_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)) - 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", - }) - self.object:remove() - end - end, -}) +function mcl_experience.update(player) + local xp = mcl_experience.get_xp(player) + local cache = caches[player] -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) + cache.level = xp_to_level(xp) + + if not minetest.is_creative_enabled(player:get_player_name()) then + 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^[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 + 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() - end - return itemstack - end, - _on_dispense = function(_, pos, _, _, dir) - throw_xp_bottle(vector.add(pos, vector.multiply(dir, 0.51)), dir, 10) +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) + caches[player] = { + last_time = get_time(), + } + + 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 = 2.8, y = 3.0}, + 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 -}) + + 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.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/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/experience_bar.png b/mods/HUD/mcl_experience/textures/mcl_experience_bar.png similarity index 100% rename from mods/HUD/mcl_experience/textures/experience_bar.png rename to mods/HUD/mcl_experience/textures/mcl_experience_bar.png diff --git a/mods/HUD/mcl_experience/textures/experience_bar_background.png b/mods/HUD/mcl_experience/textures/mcl_experience_bar_background.png similarity index 100% rename from mods/HUD/mcl_experience/textures/experience_bar_background.png rename to mods/HUD/mcl_experience/textures/mcl_experience_bar_background.png diff --git a/mods/HUD/mcl_experience/textures/experience_orb.png b/mods/HUD/mcl_experience/textures/mcl_experience_orb.png similarity index 100% rename from mods/HUD/mcl_experience/textures/experience_orb.png rename to mods/HUD/mcl_experience/textures/mcl_experience_orb.png diff --git a/mods/HUD/mcl_hbarmor/init.lua b/mods/HUD/mcl_hbarmor/init.lua index 422a409fb..34ac205ac 100644 --- a/mods/HUD/mcl_hbarmor/init.lua +++ b/mods/HUD/mcl_hbarmor/init.lua @@ -19,7 +19,7 @@ local mcl_hbarmor = { local tick_config = minetest.settings:get("mcl_hbarmor_tick") -if tonumber(tick_config) ~= nil then +if tonumber(tick_config) then mcl_hbarmor.tick = tonumber(tick_config) end 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_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 4d73aca35..d66aa06d2 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -1,673 +1,709 @@ -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 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() - 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["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 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 player_preview - if minetest.settings:get_bool("3d_player_preview", true) then - player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") - else - player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]" - 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[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).. - 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 - - 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 - if filter == nil then - filter = "" - end - 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 ~= 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.search == "" and not fields.creative_next and not fields.creative_prev then - set_inv_page("all", player) - page = "nix" - elseif fields.search ~= nil and not fields.creative_next and not fields.creative_prev then - set_inv_search(string.lower(fields.search),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.search ~= nil and fields.search ~= "" then - filter = fields.search - 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 - - 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) 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() + 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, 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 and page ~= "inv" then + inv_size = #(inventory_lists[page]) + else + inv_size = 0 + end + end + local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1)) + local name = "nix" + local main_list + local listrings = "listring[detached:creative_"..playername..";main]".. + "listring[current_player;main]".. + "listring[detached:trash;main]" + + if page 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 player_preview + if minetest.settings:get_bool("3d_player_preview", true) then + player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") + else + player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]" + 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 + + 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 + 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")).."]".. + -- switch stack size button + "image_button[9,5;1,1;default_apple.png;__switch_stack;]".. + "label[9.4,5.4;".. F(C("#FFFFFF", stack_size ~= 1 and stack_size or "")) .."]".. + "tooltip[__switch_stack;"..F(S("Switch stack size")).."]" + + -- 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 + if filter == nil then + filter = "" + end + 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 + 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 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.search and fields.search ~= "" then + filter = fields.search + 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 + + 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 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) + +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/init.lua b/mods/HUD/mcl_inventory/init.lua index 4c50a6c13..0d411502d 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -1,10 +1,10 @@ -local S = minetest.get_translator("mcl_inventory") +local S = minetest.get_translator(minetest.get_current_modname()) local F = minetest.formspec_escape mcl_inventory = {} ---local mod_player = minetest.get_modpath("mcl_player") ~= nil ---local mod_craftguide = minetest.get_modpath("mcl_craftguide") ~= nil +--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) @@ -76,6 +76,10 @@ local function set_inventory(player, armor_change_only) 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]".. player_preview.. @@ -88,6 +92,8 @@ local function set_inventory(player, armor_change_only) 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"))).."]".. @@ -134,7 +140,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end) if not minetest.is_creative_enabled("") then - mcl_inventory.update_inventory_formspec = function(player) + function mcl_inventory.update_inventory_formspec(player) set_inventory(player) end end @@ -148,8 +154,10 @@ end) minetest.register_on_joinplayer(function(player) --init inventory - player:get_inventory():set_width("main", 9) - player:get_inventory():set_size("main", 36) + 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) @@ -158,7 +166,7 @@ minetest.register_on_joinplayer(function(player) player:hud_set_hotbar_selected_image("mcl_inventory_hotbar_selected.png") local old_update_player = mcl_armor.update_player - mcl_armor.update_player = function(player, info) + function mcl_armor.update_player(player, info) old_update_player(player, info) set_inventory(player, true) end 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.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/mod.conf b/mods/HUD/mcl_inventory/mod.conf index 7585d9f70..10e669265 100644 --- a/mods/HUD/mcl_inventory/mod.conf +++ b/mods/HUD/mcl_inventory/mod.conf @@ -1,6 +1,5 @@ name = mcl_inventory author = BlockMen description = Adds the player inventory and creative inventory. -depends = mcl_init, mcl_formspec, mcl_player -optional_depends = _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide - +depends = mcl_init, mcl_formspec, mcl_enchanting +optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide, mcl_player diff --git a/mods/HUD/mcl_offhand/init.lua b/mods/HUD/mcl_offhand/init.lua new file mode 100644 index 000000000..b0fc223ec --- /dev/null +++ b/mods/HUD/mcl_offhand/init.lua @@ -0,0 +1,171 @@ +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 + if offhand_item ~= "" then + local item_texture = minetest.registered_items[offhand_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 = 2.75, y = 2.75}, + text = "mcl_offhand_slot.png", + 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.4, y = 0.4}, + 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_offhand/textures/mcl_offhand_slot.png b/mods/HUD/mcl_offhand/textures/mcl_offhand_slot.png new file mode 100644 index 000000000..69ceb5973 Binary files /dev/null and b/mods/HUD/mcl_offhand/textures/mcl_offhand_slot.png differ diff --git a/mods/HUD/mcl_offhand/textures/mcl_wear_bar.png b/mods/HUD/mcl_offhand/textures/mcl_wear_bar.png new file mode 100644 index 000000000..6fee6bba6 Binary files /dev/null and b/mods/HUD/mcl_offhand/textures/mcl_wear_bar.png differ 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..2ea1571c8 --- /dev/null +++ b/mods/HUD/mcl_title/init.lua @@ -0,0 +1,236 @@ +--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 + +local huds_idx = {} + +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 + +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 +--[[ +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 +]] + +--PARAMS SYSTEM +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 = 0, + 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 = 0, + 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 = 0, + 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) + +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 + +function mcl_title.params_get(player) + return player_params[player] +end + +--API FUNCTIONS + +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 + +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", 0) --no styling + end +end + +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!! +--[[ +minetest.register_chatcommand("title", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.set(player, "title", {text=param, color="gold", bold=true, italic=true}) + end, +}) + +minetest.register_chatcommand("subtitle", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.set(player, "subtitle", {text=param, color="gold"}) + end, +}) + +minetest.register_chatcommand("actionbar", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.set(player, "actionbar", {text=param, color="gold"}) + end, +}) + +minetest.register_chatcommand("timeout", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + mcl_title.params_set(player, {stay = 600}) + end, +}) + +minetest.register_chatcommand("all", { + func = function(name, param) + local player = minetest.get_player_by_name(name) + 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"}) + end, +}) +]] \ No newline at end of file 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/API.md b/mods/HUD/mcl_tmp_message/API.md deleted file mode 100644 index 0a3fc06a3..000000000 --- a/mods/HUD/mcl_tmp_message/API.md +++ /dev/null @@ -1,7 +0,0 @@ -# mcl_temp_message - -Allow mods to show short messages in the hud of players. - -## mcl_tmp_message.message(player, message) - -Show above the hotbar a hud message to player . \ 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_tmp_message/mod.conf b/mods/HUD/mcl_tmp_message/mod.conf deleted file mode 100644 index ad453643e..000000000 --- a/mods/HUD/mcl_tmp_message/mod.conf +++ /dev/null @@ -1,3 +0,0 @@ -name = mcl_tmp_message -author = Fleckenstein -description = A simple API to show a temporary message to a player diff --git a/mods/HUD/show_wielded_item/init.lua b/mods/HUD/show_wielded_item/init.lua index 456dc23e0..dfa87a85c 100644 --- a/mods/HUD/show_wielded_item/init.lua +++ b/mods/HUD/show_wielded_item/init.lua @@ -6,6 +6,10 @@ 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") @@ -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 @@ -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/ITEMS/REDSTONE/mcl_comparators/init.lua b/mods/ITEMS/REDSTONE/mcl_comparators/init.lua index a76821543..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) @@ -260,7 +266,7 @@ for _, mode in pairs{"comp", "sub"} do paramtype2 = "facedir", sunlight_propagates = false, is_ground_content = false, - drop = 'mcl_comparators:comparator_off_comp', + drop = "mcl_comparators:comparator_off_comp", on_construct = update_self, on_rightclick = make_rightclick_handler(state_str, mode), 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_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 73bc1f0da..0cd0608c4 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,14 +92,14 @@ 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) + action_on = function(pos, node) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local droppos, dropdir @@ -129,8 +129,13 @@ local dispenserdef = { dropitem:set_count(1) local stack_id = stacks[r].stackpos local stackdef = stack:get_definition() + + if not stackdef then + return + end + local iname = stack:get_name() - local igroups = minetest.registered_items[iname].groups + local igroups = stackdef.groups --[===[ Dispense item ]===] @@ -163,6 +168,56 @@ local dispenserdef = { end inv:set_stack("main", stack_id, stack) + + -- 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 + minetest.add_item(pos, entity.drops[2].name .. " " .. math.random(1, 3)) + 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 = mobs_mc.items.mutton_raw, 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, mobs_mc.items.mushroom_brown .. " 5") + else + minetest.add_item(droppos, mobs_mc.items.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 + end + -- Spawn Egg elseif igroups.spawn_egg then -- Spawn mob @@ -246,10 +301,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", @@ -287,7 +343,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.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_droppers/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index 715a85f3d..abb351091 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,7 @@ local dropperdef = { _mcl_hardness = 3.5, mesecons = {effector = { -- Drop random item when triggered - action_on = function (pos, node) + action_on = function(pos, node) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local droppos @@ -152,7 +152,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 +195,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 index 1bf968a82..bd8c0a3c3 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init_new.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]".. "background[-0.19,-0.25;9.41,9.49;crafting_inventory_9_slots.png]".. @@ -19,8 +19,8 @@ local setup_dropper = function(pos) "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]".. + "list[context;main;3,0.5;3,3;]".. + "listring[context;main]".. "listring[current_player;main]" local meta = minetest.get_meta(pos) meta:set_string("formspec", form) @@ -28,7 +28,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 @@ -53,7 +53,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 @@ -63,7 +63,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() @@ -96,7 +96,7 @@ local dropperdef = { _mcl_hardness = 3.5, mesecons = {effector = { -- Drop random item when triggered - action_on = function (pos, node) + action_on = function(pos, node) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local droppos @@ -149,14 +149,16 @@ 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) + +function horizontal_def.after_place_node(pos, placer, itemstack, pointed_thing) setup_dropper(pos) orientate_dropper(pos, placer) end + horizontal_def.tiles = { "default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png", "default_furnace_side.png", - "default_furnace_side.png", "mcl_droppers_dropper_front_horizontal.png" + "default_furnace_side.png", "mcl_droppers_dropper_front_horizontal.png", } horizontal_def.paramtype2 = "facedir" horizontal_def.groups = {pickaxey=1, container=2, material_stone=1} @@ -170,7 +172,7 @@ 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" + "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 @@ -184,7 +186,7 @@ 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" + "default_furnace_side.png", "default_furnace_side.png", } minetest.register_node("mcl_droppers:dropper_up", up_def) @@ -192,7 +194,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/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_observers/init.lua b/mods/ITEMS/REDSTONE/mcl_observers/init.lua index 8f7f6c262..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: @@ -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 @@ -47,7 +51,7 @@ end -- TODO: Also scan metadata changes. -- TODO: Ignore some node changes. local function observer_scan(pos, initialize) - local node = minetest.get_node(pos) + 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 function observer_scan(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") @@ -94,7 +98,7 @@ local function observer_orientate(pos, placer) -- 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"}) @@ -156,7 +160,7 @@ mesecon.register_node("mcl_observers:observer", { timer:start(mcl_vars.redstone_tick) end, on_timer = function(pos, elapsed) - local node = minetest.get_node(pos) + 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, @@ -208,7 +212,7 @@ mesecon.register_node("mcl_observers:observer_down", { timer:start(mcl_vars.redstone_tick) end, on_timer = function(pos, elapsed) - local node = minetest.get_node(pos) + 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, @@ -291,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 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_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/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/mcl_target/textures/mcl_target_target_side.png b/mods/ITEMS/REDSTONE/mcl_target/textures/mcl_target_target_side.png new file mode 100755 index 000000000..286f7767e Binary files /dev/null and b/mods/ITEMS/REDSTONE/mcl_target/textures/mcl_target_target_side.png differ diff --git a/mods/ITEMS/REDSTONE/mcl_target/textures/mcl_target_target_top.png b/mods/ITEMS/REDSTONE/mcl_target/textures/mcl_target_target_top.png new file mode 100755 index 000000000..b55ef3ec8 Binary files /dev/null and b/mods/ITEMS/REDSTONE/mcl_target/textures/mcl_target_target_top.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua b/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua index eabe73d1a..489a81b4a 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) @@ -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 diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index a5bcb80e8..dbe3ebe12 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -138,7 +138,7 @@ 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 @@ -179,7 +179,7 @@ function mesecon.effector_get_rules(node) local effector = mesecon.get_effector(node.name) if effector then local rules = effector.rules - if type(rules) == 'function' then + if type(rules) == "function" then return rules(node) elseif rules then return rules @@ -352,7 +352,7 @@ 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 diff --git a/mods/ITEMS/REDSTONE/mesecons_button/init.lua b/mods/ITEMS/REDSTONE/mesecons_button/init.lua index a8c671004..2812b2758 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 @@ -37,7 +37,7 @@ function mesecon.push_button(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,7 +86,7 @@ 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 @@ -132,7 +132,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, @@ -159,7 +159,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, 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_commandblock/init.lua b/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua index 9c0914efb..3902c3c18 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua @@ -1,6 +1,8 @@ -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) @@ -27,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. @@ -137,7 +139,7 @@ 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 @@ -192,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 @@ -295,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.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/mod.conf b/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf index a35c425f5..26059530a 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf @@ -1,3 +1,3 @@ name = mesecons_commandblock -depends = mesecons, mcl_colors +depends = mesecons, mcl_colors, mcl_util optional_depends = doc, doc_items diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua b/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua index 0a330ef2c..fc12c0a36 100644 --- a/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua @@ -1,4 +1,4 @@ -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] @@ -264,8 +264,8 @@ for i = 1, 4 do paramtype2 = "facedir", sunlight_propagates = false, is_ground_content = false, - drop = 'mesecons_delayer:delayer_off_1', - on_rightclick = function (pos, node, clicker) + 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) @@ -330,8 +330,8 @@ for i = 1, 4 do paramtype2 = "facedir", sunlight_propagates = false, is_ground_content = false, - drop = 'mesecons_delayer:delayer_off_1', - on_rightclick = function (pos, node, clicker) + 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) @@ -410,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 = { @@ -465,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.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_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.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_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.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_pistons/init.lua b/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua index 0073aeb48..93b8df96d 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mesecons_pistons") +local S = minetest.get_translator(minetest.get_current_modname()) local PISTON_MAXIMUM_PUSH = 12 @@ -66,7 +66,7 @@ local function piston_remove_pusher(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, @@ -87,7 +87,7 @@ local function piston_remove_base(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, @@ -865,7 +865,7 @@ 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"}, 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_pressureplates/init.lua b/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua index 34730760d..c0894224c 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mesecons_pressureplates") +local S = minetest.get_translator(minetest.get_current_modname()) local PRESSURE_PLATE_INTERVAL = 0.04 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_solarpanel/init.lua b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua index b256d87e2..129c28eea 100644 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua @@ -1,4 +1,68 @@ -local S = minetest.get_translator("mesecons_solarpanel") +local S = minetest.get_translator(minetest.get_current_modname()) + +local function path_to_sunlight_exists(position, light_level) + local neighbours = { + { x = 0, y = 0, z =-1 }, + { x = 0, y = 0, z = 1 }, + { x = 0, y =-1, z = 0 }, + { x = 0, y = 1, z = 0 }, + { x =-1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + } + for i=1, #neighbours do + local offset = neighbours[i] + local position_new = vector.add( + position, + offset + ) + local light_level_new = minetest.get_node_light( + position_new, + nil + ) + if 15 == light_level_new then + -- found the sunlight + return true + elseif light_level_new > light_level then + -- search where light is brighter + if path_to_sunlight_exists( + position_new, + light_level_new + ) then + return true + end + end + end +end + +local function sunlight_visible(position) + local light_level + -- Minetest 5.4.0+ can measure the daylight level at a position + if nil ~= minetest.get_natural_light then + light_level = minetest.get_natural_light( + position, + nil + ) + if light_level >= 12 then + return true + end + else -- Minetest 5.3.0 or less can only measure the light level + local time = minetest.get_timeofday() * 24000 + -- only check light level during day + if time > 6000 and time < 18000 then + light_level = minetest.get_node_light( + position, + nil + ) + if light_level >= 12 then + return path_to_sunlight_exists( + position, + 12 + ) + end + end + end + return false +end local boxes = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 } @@ -81,11 +145,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 +159,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 +172,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 +262,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 +275,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.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_torch/init.lua b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua index 9aefae96c..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,7 +111,7 @@ 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"},} @@ -222,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.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_walllever/init.lua b/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua index 92c809785..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 @@ -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) @@ -148,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) @@ -166,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.pl.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr new file mode 100644 index 000000000..924fe3dd0 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr @@ -0,0 +1,5 @@ +# textdomain: mesecons_wallever +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_wires/init.lua b/mods/ITEMS/REDSTONE/mesecons_wires/init.lua index 3d00e5f20..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,7 +28,7 @@ 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 @@ -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 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/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index 09f4d954c..d3b32b844 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 @@ -53,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. @@ -60,9 +69,15 @@ 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 @@ -121,11 +136,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) @@ -180,7 +212,7 @@ local function update_anvil_slots(meta) end -- Set the new output slot - if new_output ~= nil then + if new_output then inv:set_stack("output", 1, new_output) end end @@ -284,6 +316,12 @@ 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"}, @@ -297,11 +335,14 @@ 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, 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.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/textures/mcl_anvils_anvil_top_damaged_0.png b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_0.png index 84c64e915..43938aa72 100644 Binary files a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_0.png and b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_0.png 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 index 61c2ac6ab..e8cfbe5b7 100644 Binary files a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_1.png and b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_1.png 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 index 5f5cfbffa..096f65eac 100644 Binary files a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_2.png and b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_2.png differ diff --git a/mods/ITEMS/mcl_armor/API.md b/mods/ITEMS/mcl_armor/API.md new file mode 100644 index 000000000..ede33ebb9 --- /dev/null +++ b/mods/ITEMS/mcl_armor/API.md @@ -0,0 +1,298 @@ +# 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, + }, + + --WARNING: 2d preview is deprecated and will be removed soon + --specify textures that will be shown in player inventory then you disabled the 3d player inventory preview + --its similar to how works the textures field + previews = { + head = "dummy_texture.png", --default: "_helmet__preview.png" + torso = "dummy_texture.png", --default: "_chestplate__preview.png" + legs = "dummy_texture.png", --default: "_leggings__preview.png" + feet = "dummy_texture.png", --default: "_boots__preview.png" + }, + + --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/init.lua b/mods/ITEMS/mcl_armor/init.lua index 6a3522b96..c10ff8f0c 100644 --- a/mods/ITEMS/mcl_armor/init.lua +++ b/mods/ITEMS/mcl_armor/init.lua @@ -1,5 +1,5 @@ local S = minetest.get_translator("mcl_armor") -local modpath = minetest.get_modpath(minetest.get_current_modname()) +local modpath = minetest.get_modpath("mcl_armor") mcl_armor = { longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive."), @@ -60,11 +60,9 @@ mcl_armor = { player_view_range_factors = {}, } -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") -dofile(modpath.."/leather.lua") +dofile(modpath .."/leather.lua") 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.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/mod.conf b/mods/ITEMS/mcl_armor/mod.conf index 9264e8362..fad2e494c 100644 --- a/mods/ITEMS/mcl_armor/mod.conf +++ b/mods/ITEMS/mcl_armor/mod.conf @@ -1,5 +1,5 @@ name = mcl_armor author = stu description = Adds craftable armor that is visible to other players. -depends = mcl_core, mcl_player, mcl_enchanting +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 95f763eab..b3a943f46 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 a5626aacc..a613eef89 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 index 1b4205344..4e17ee341 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d 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 index 828cd942c..b0494efbf 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend and b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend1 b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend1 deleted file mode 100644 index 1a13f1c92..000000000 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend1 and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index 9dba0773c..48fdb381f 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -25,6 +25,8 @@ mcl_player.player_register_model("mcl_armor_character.b3d", { 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}, }, }) @@ -55,6 +57,8 @@ mcl_player.player_register_model("mcl_armor_character_female.b3d", { 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}, }, }) diff --git a/mods/ITEMS/mcl_armor/register.lua b/mods/ITEMS/mcl_armor/register.lua index de17fd20d..1f9ce7b02 100644 --- a/mods/ITEMS/mcl_armor/register.lua +++ b/mods/ITEMS/mcl_armor/register.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_armor") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_armor.register_set({ name = "leather", 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 index dc452d413..ef1f9fa87 100644 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_gold.png and b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_gold.png differ diff --git a/mods/ITEMS/mcl_armor_stand/init.lua b/mods/ITEMS/mcl_armor_stand/init.lua index 870d567fc..d6080b8f8 100644 --- a/mods/ITEMS/mcl_armor_stand/init.lua +++ b/mods/ITEMS/mcl_armor_stand/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_armor_stand") +local S = minetest.get_translator(minetest.get_current_modname()) -- Spawn a stand entity local function spawn_stand_entity(pos, node) 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.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_banners/init.lua b/mods/ITEMS/mcl_banners/init.lua index 63ad0c0b8..cc0e02e66 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() @@ -83,8 +88,12 @@ 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 @@ -93,11 +102,11 @@ 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 @@ -116,7 +125,7 @@ local on_dig_banner = function(pos, node, digger) 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 @@ -136,15 +145,15 @@ local on_destruct_banner = function(pos, hanging) 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] @@ -166,15 +175,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") @@ -187,10 +196,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 @@ -198,7 +207,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 @@ -542,7 +551,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 @@ -568,7 +577,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 = { @@ -579,14 +588,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 @@ -599,7 +608,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 @@ -619,7 +628,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 @@ -630,7 +639,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 @@ -638,7 +647,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.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/patterncraft.lua b/mods/ITEMS/mcl_banners/patterncraft.lua index 516624301..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"), @@ -259,7 +255,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do 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 "" @@ -296,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 @@ -398,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") diff --git a/mods/ITEMS/mcl_barrels/init.lua b/mods/ITEMS/mcl_barrels/init.lua new file mode 100644 index 000000000..09b16eee3 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/init.lua @@ -0,0 +1,204 @@ +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 +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}) + 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.es.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.es.tr new file mode 100644 index 000000000..e1fa1b603 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.es.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.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.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.ru.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ru.tr new file mode 100644 index 000000000..e1fa1b603 --- /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.= +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/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/textures/mcl_barrels_barrel_bottom.png b/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_bottom.png new file mode 100755 index 000000000..9c5788061 Binary files /dev/null and b/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_bottom.png differ diff --git a/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_side.png b/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_side.png new file mode 100755 index 000000000..8a01cc4a9 Binary files /dev/null and b/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_side.png differ diff --git a/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_top.png b/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_top.png new file mode 100755 index 000000000..8af5a5c90 Binary files /dev/null and b/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_top.png differ diff --git a/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_top_open.png b/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_top_open.png new file mode 100755 index 000000000..1d3a02be1 Binary files /dev/null and b/mods/ITEMS/mcl_barrels/textures/mcl_barrels_barrel_top_open.png differ diff --git a/mods/ITEMS/mcl_beds/README.txt b/mods/ITEMS/mcl_beds/README.txt index cda6ebd92..34b493702 100644 --- a/mods/ITEMS/mcl_beds/README.txt +++ b/mods/ITEMS/mcl_beds/README.txt @@ -12,15 +12,7 @@ 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. \ No newline at end of file diff --git a/mods/ITEMS/mcl_beds/api.lua b/mods/ITEMS/mcl_beds/api.lua index ee59bc34b..86cc079fe 100644 --- a/mods/ITEMS/mcl_beds/api.lua +++ b/mods/ITEMS/mcl_beds/api.lua @@ -1,4 +1,4 @@ -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 @@ -248,7 +248,7 @@ function mcl_beds.register_bed(name, def) 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, diff --git a/mods/ITEMS/mcl_beds/beds.lua b/mods/ITEMS/mcl_beds/beds.lua index 8f41c7a3f..5043c85d2 100644 --- a/mods/ITEMS/mcl_beds/beds.lua +++ b/mods/ITEMS/mcl_beds/beds.lua @@ -1,4 +1,4 @@ -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 = { diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index fd156757b..b8478fc1f 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -1,11 +1,12 @@ -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") @@ -13,39 +14,34 @@ local worlds_mod = minetest.get_modpath("mcl_worlds") 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 pairs(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 @@ -105,7 +101,7 @@ local function lay_down(player, pos, bed_pos, state, skip) -- The exceptions above apply. -- Zombie pigmen only prevent sleep while they are hostle. for _, obj in pairs(minetest.get_objects_inside_radius(bed_pos, 8)) do - if obj ~= nil and not obj:is_player() then + if obj and not obj:is_player() then local ent = obj:get_luaentity() local mobname = ent.name local def = minetest.registered_entities[mobname] @@ -122,7 +118,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 @@ -157,7 +153,7 @@ 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 @@ -197,7 +193,7 @@ 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")).."]" @@ -220,7 +216,13 @@ 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 end @@ -273,7 +275,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") @@ -329,7 +331,7 @@ function mcl_beds.on_rightclick(pos, player, is_top) 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) @@ -348,7 +350,6 @@ function mcl_beds.on_rightclick(pos, player, is_top) end end - -- Callbacks minetest.register_on_joinplayer(function(player) local meta = player:get_meta() diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr index 16592115e..eb6967941 100644 --- a/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr @@ -37,5 +37,6 @@ 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 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.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..5525bd91b 100644 --- a/mods/ITEMS/mcl_beds/locale/template.txt +++ b/mods/ITEMS/mcl_beds/locale/template.txt @@ -37,5 +37,6 @@ 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= diff --git a/mods/ITEMS/mcl_books/init.lua b/mods/ITEMS/mcl_books/init.lua index b7bd20d9a..e549ef6f3 100644 --- a/mods/ITEMS/mcl_books/init.lua +++ b/mods/ITEMS/mcl_books/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_books") +local S = minetest.get_translator(minetest.get_current_modname()) local max_text_length = 4500 -- TODO: Increase to 12800 when scroll bar was added to written book local max_title_length = 64 @@ -21,16 +21,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 +56,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) @@ -71,11 +71,11 @@ local make_description = function(title, author, generation) 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 +96,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) @@ -347,11 +347,11 @@ minetest.register_node("mcl_books:bookshelf", { }) 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.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.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_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index a56b2e7cf..cda8dcc6d 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -1,4 +1,6 @@ -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 math = math local vector = vector @@ -43,7 +45,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)) @@ -73,33 +75,32 @@ local ARROW_ENTITY={ _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, @@ -111,14 +112,13 @@ local damage_particles = function(pos, is_critical) end end -ARROW_ENTITY.on_step = function(self, dtime) +function ARROW_ENTITY.on_step(self, dtime) mcl_burning.tick(self.object, dtime, self) 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 @@ -202,7 +202,7 @@ ARROW_ENTITY.on_step = function(self, dtime) -- Arrows can only damage players and mobs if obj:is_player() then ok = true - elseif obj:get_luaentity() ~= nil then + elseif obj:get_luaentity() then if (obj:get_luaentity()._cmi_is_mob or obj:get_luaentity()._hittable_by_projectile) then ok = true end @@ -222,7 +222,7 @@ ARROW_ENTITY.on_step = function(self, dtime) -- 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() @@ -248,50 +248,59 @@ 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 self._in_player == false then + if not self._in_player 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 + 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 - local placement - self._placement = math.random(1, 2) - if self._placement == 1 then - placement = "front" + 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 - placement = "back" + self._blocked = true + self.object:set_velocity(vector.multiply(self.object:get_velocity(), -0.25)) 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, {x=self._x_position,y=self._y_position,z=random_arrow_positions('z', placement)}, {x=0,y=self._rotation_station + self._y_rotation,z=self._z_rotation}) minetest.after(150, function() self.object:remove() end) @@ -301,7 +310,7 @@ ARROW_ENTITY.on_step = function(self, dtime) if is_player then - if self._shooter and self._shooter:is_player() and self._in_player == false 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 @@ -318,13 +327,15 @@ ARROW_ENTITY.on_step = function(self, dtime) end end end - if self._in_player == false then + 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) - self.object:remove() + if self._piercing == 0 then + self.object:remove() + end end return end @@ -342,9 +353,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))) @@ -372,8 +383,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) @@ -381,6 +392,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) @@ -418,18 +434,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, @@ -437,6 +453,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 @@ -451,9 +468,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 - self._in_player = false local data = minetest.deserialize(staticdata) if data then self._stuck = data.stuck @@ -486,23 +502,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 f752142c2..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 @@ -66,7 +66,7 @@ mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damag 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 @@ -75,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 @@ -89,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") @@ -162,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 @@ -182,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 @@ -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..b211f6b39 --- /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("Bows are ranged weapons to shoot arrows at your foes.").."\n".. +S("The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead."), + _doc_items_usagehelp = S("To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot."), + _doc_items_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("Corssbow"), + _tt_help = S("Launches arrows"), + _doc_items_longdesc = S("Corssbow 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 corssbow, 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}, + _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/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.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.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/mod.conf b/mods/ITEMS/mcl_bows/mod.conf index 79ae42436..7b174826a 100644 --- a/mods/ITEMS/mcl_bows/mod.conf +++ b/mods/ITEMS/mcl_bows/mod.conf @@ -1,6 +1,6 @@ name = mcl_bows author = Arcelmi description = This mod adds bows and arrows for MineClone 2. -depends = controls, mcl_particles, mcl_enchanting, mcl_init +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_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..2c1d30dcd --- /dev/null +++ b/mods/ITEMS/mcl_bows/rocket.lua @@ -0,0 +1,698 @@ +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) + mcl_explosions.explode(self.object:get_pos(), 3, {}) + local objects = minetest.get_objects_inside_radius(self.object:get_pos(), 8) + for _,obj in pairs(objects) do + if obj:is_player() then + mcl_util.deal_damage(obj, damagemulitplier - vector.distance(self.object:get_pos(), obj:get_pos()), {type = "explosion"}) + elseif obj:get_luaentity()._cmi_is_mob then + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damagemulitplier - vector.distance(self.object:get_pos(), 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") + +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) + + 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 + for k, obj in pairs(objs) do + local ok = false + -- Arrows can only damage players and mobs + if obj:is_player() then + ok = true + elseif obj:get_luaentity() then + if (obj:get_luaentity()._cmi_is_mob or obj:get_luaentity()._hittable_by_projectile) then + ok = true + 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 + 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._cmi_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_overlay.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png index a043eb37e..ee628e29d 100644 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png and b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow.png new file mode 100644 index 000000000..b688dab94 Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_0.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_0.png new file mode 100644 index 000000000..41daad6d8 Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_0.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_1.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_1.png new file mode 100644 index 000000000..3769f2967 Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_1.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_2.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_2.png new file mode 100644 index 000000000..b1bb50feb Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_2.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_3.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_3.png new file mode 100644 index 000000000..8a8f1b03f Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_crossbow_3.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_blue.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_blue.png new file mode 100644 index 000000000..608dbe0d0 Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_blue.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_green.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_green.png new file mode 100644 index 000000000..acd74d6d1 Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_green.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_red.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_red.png new file mode 100644 index 000000000..4d7355c57 Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_red.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_white.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_white.png new file mode 100644 index 000000000..1860ee53c Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_white.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_yellow.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_yellow.png new file mode 100644 index 000000000..c2b745def Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_firework_yellow.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_rocket.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_rocket.png new file mode 100644 index 000000000..800185ce0 Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_rocket.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_rocket_particle.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_rocket_particle.png new file mode 100644 index 000000000..12a894c72 Binary files /dev/null and b/mods/ITEMS/mcl_bows/textures/mcl_bows_rocket_particle.png differ diff --git a/mods/ITEMS/mcl_brewing/init.lua b/mods/ITEMS/mcl_brewing/init.lua index 1724a982d..38f81fa36 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,8 +56,8 @@ 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]" @@ -325,7 +325,7 @@ local tiles = { "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) @@ -335,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 = "" @@ -352,18 +352,18 @@ 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]] -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) @@ -493,7 +493,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() @@ -503,7 +502,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 @@ -511,10 +509,10 @@ 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, @@ -567,7 +565,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() @@ -577,7 +574,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 @@ -585,10 +581,10 @@ 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, @@ -605,7 +601,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 @@ -637,7 +632,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() @@ -647,7 +641,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 @@ -655,10 +648,10 @@ 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, @@ -675,7 +668,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 @@ -717,7 +709,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() @@ -727,7 +718,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 @@ -735,10 +725,10 @@ 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, @@ -755,7 +745,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 @@ -793,7 +782,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() @@ -803,7 +791,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 @@ -811,10 +798,10 @@ 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, @@ -831,7 +818,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 @@ -869,7 +855,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() @@ -879,7 +864,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 @@ -887,10 +871,10 @@ 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, @@ -907,7 +891,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 @@ -952,7 +935,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() @@ -962,7 +944,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 @@ -970,7 +951,6 @@ minetest.register_node("mcl_brewing:stand_111", { return end end, - on_timer = brewing_stand_timer, on_rotate = on_rotate, }) 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.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 2c27c979e..0f6217f09 100644 --- a/mods/ITEMS/mcl_brewing/mod.conf +++ b/mods/ITEMS/mcl_brewing/mod.conf @@ -1,4 +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_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md index 53f7d3698..94ec48de5 100644 --- a/mods/ITEMS/mcl_buckets/API.md +++ b/mods/ITEMS/mcl_buckets/API.md @@ -9,13 +9,46 @@ Accept folowing params: * 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) +* 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) which can returns false to avoid placing the liquid. Placer is object/player who is placing the liquid, can be nil. +* extra_check(pos, placer): (optional) function(pos) * groups: optional list of item groups -This function can be called from any mod (which depends on this one) \ No newline at end of file + +**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.txt b/mods/ITEMS/mcl_buckets/README.md similarity index 67% rename from mods/ITEMS/mcl_buckets/README.txt rename to mods/ITEMS/mcl_buckets/README.md index 06862d589..b783cc133 100644 --- a/mods/ITEMS/mcl_buckets/README.txt +++ b/mods/ITEMS/mcl_buckets/README.md @@ -1,9 +1,12 @@ -Bucket mod. -Originally taken from Minetest Game, adapted for MineClone 2. +# 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 -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 diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index fd07006b7..ff0b866da 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -3,6 +3,7 @@ local modname = minetest.get_current_modname() local S = minetest.get_translator(modname) local modpath = minetest.get_modpath(modname) +-- 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") @@ -11,161 +12,353 @@ 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") +-- Localize some functions for faster access +local vector = vector +local math = math +local string = string + +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 + if mod_mcl_core then minetest.register_craft({ - output = 'mcl_buckets:bucket_empty 1', + output = "mcl_buckets:bucket_empty 1", 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", ""}, + }, }) end -mcl_buckets = {} -mcl_buckets.liquids = {} +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) + local fullness = registered_nodes[itemstring].liquid_range sound_place(itemstring, pos) - minetest.add_node(pos, {name=itemstring, param2=fullness}) + add_node(pos, {name=itemstring, param2=fullness}) end +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 bucket_raycast(user) + --local pos = user:get_pos() + local pos = user:get_pos() + --local pos = vector.add(user:get_pos(), user:get_bone_position("Head_Control")) + pos.y = pos.y + user:get_properties().eye_height + local look_dir = user:get_look_dir() + look_dir = vector.multiply(look_dir, 5) + local pos2 = vector.add(pos, look_dir) + + local ray = raycast(pos, pos2, false, true) + if ray then + for pointed_thing in ray do + if pointed_thing and pointable_sources[get_node(pointed_thing.above).name] then + --minetest.chat_send_all("found!") + return {under=pointed_thing.under,above=pointed_thing.above} + end + end + end + return nil +end + +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 on_place_bucket(itemstack, user, pointed_thing, def) + -- Must be pointing to node + if 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 undernode = get_node(pointed_thing.under) + local abovenode = get_node(pointed_thing.above) + + if registered_nodes[undernode.name] and registered_nodes[undernode.name].buildable_to or get_item_group(undernode.name, "cauldron") == 1 then + local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.under, user) + if result then + local node_place = get_node_place(def.source_place, pointed_thing.under) + local pns = user:get_player_name() + + -- Check protection + if is_protected(pointed_thing.under, pns) then + record_protection_violation(pointed_thing.under, pns) + return itemstack + end + + -- Place liquid + place_liquid(pointed_thing.under, 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) + elseif registered_nodes[abovenode.name] and registered_nodes[abovenode.name].buildable_to or get_item_group(abovenode.name, "cauldron") == 1 then + local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.above, user) + if result then + local node_place = get_node_place(def.source_place, pointed_thing.above) + local pns = user:get_player_name() + + -- Check protection + if is_protected(pointed_thing.above, pns) then + record_protection_violation(pointed_thing.above, pns) + return itemstack + end + + -- Place liquid + place_liquid(pointed_thing.above, 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) + else + return itemstack + end +end + + +local function on_place_bucket_empty(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 new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing) + if new_stack then + return new_stack + end + + local node = get_node(pointed_thing.under) + local nn = node.name + + local new_bucket + local liquid_node = bucket_raycast(user) + if liquid_node then + if is_protected(liquid_node.above, user:get_player_name()) then + record_protection_violation(liquid_node.above, user:get_player_name()) + end + local liquid_name = get_node(liquid_node.above).name + if liquid_name then + local liquid_def = mcl_buckets.liquids[liquid_name] + if liquid_def then + --minetest.chat_send_all("test") + -- 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(liquid_node.above, {name="air"}) + sound_take(nn, liquid_node.above) + + if mod_doc and doc.entry_exists("nodes", liquid_name) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", liquid_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]!", liquid_name)) + end + end + return itemstack + else + -- FIXME: replace this ugly code by cauldrons API + if nn == "mcl_cauldrons:cauldron_3" then + -- Take water out of full cauldron + set_node(pointed_thing.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", pointed_thing.under) + elseif nn == "mcl_cauldrons:cauldron_3r" then + -- Take river water out of full cauldron + set_node(pointed_thing.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", pointed_thing.under) + end + if new_bucket then + return give_bucket(new_bucket, itemstack, user) + end + end + return itemstack +end + +controls.register_on_press(function(player, key) + if key ~= "RMB" then + return + end + + local wielded_item = player:get_wielded_item() + local itemname = wielded_item:get_name() + local def = mcl_buckets.buckets[itemname] + + if itemname == "mcl_buckets:bucket_empty" then + local pointed_thing = mcl_util.get_pointed_thing(player, true) + + if not pointed_thing then + return + end + wielded_item = on_place_bucket_empty(wielded_item, player, pointed_thing) + elseif def then + local pointed_thing = mcl_util.get_pointed_thing(player, false) + + if not pointed_thing then + return + end + wielded_item = on_place_bucket(wielded_item, player, pointed_thing, def) + end + + player:set_wielded_item(wielded_item) +end) + function mcl_buckets.register_liquid(def) - for i=1, #def.source_take do - mcl_buckets.liquids[def.source_take[i]] = { + for _,source in ipairs(def.source_take) do + mcl_buckets.liquids[source] = { source_place = def.source_place, - source_take = def.source_take[i], + source_take = source, on_take = def.on_take, - itemname = def.itemname, + bucketname = def.bucketname, } + pointable_sources[source] = true if type(def.source_place) == "string" then - mcl_buckets.liquids[def.source_place] = mcl_buckets.liquids[def.source_take[i]] + mcl_buckets.liquids[def.source_place] = mcl_buckets.liquids[source] end end - if def.itemname ~= nil then - minetest.register_craftitem(def.itemname, { - 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, - 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 - local nodedef = minetest.registered_nodes[nn] - -- Call on_rightclick if the pointed node defines it - if user and not user:get_player_control().sneak then - if nodedef and nodedef.on_rightclick then - return nodedef.on_rightclick(place_pos, node, user, itemstack) or itemstack - end - end - - local node_place - if type(def.source_place) == "function" then - node_place = def.source_place(place_pos) - else - node_place = def.source_place - end - -- Check if pointing to a buildable node - --local item = itemstack:get_name() - - if def.extra_check and def.extra_check(place_pos, user) == true and nodedef and nodedef.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 or dropnode.name == "mcl_portals:portal" - - --if def.extra_check and def.extra_check(droppos, nil) == false then - -- Fail placement of liquid - if def.extra_check and def.extra_check(droppos, nil) == true and buildable then - -- buildable; replace the node - local node_place - if type(def.source_place) == "function" then - node_place = def.source_place(droppos) - else - node_place = def.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, + _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", { @@ -173,106 +366,29 @@ 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, + --liquids_pointable = true, inventory_image = "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}) - if liquiddef.on_take then - liquiddef.on_take(user) - end - 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, _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 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.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/mod.conf b/mods/ITEMS/mcl_buckets/mod.conf index 5a78e70ad..ba945b033 100644 --- a/mods/ITEMS/mcl_buckets/mod.conf +++ b/mods/ITEMS/mcl_buckets/mod.conf @@ -1,6 +1,6 @@ name = mcl_buckets author = Kahrl description = -depends = mcl_worlds +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 index 5e46b6ce0..1a7c8fe14 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -3,7 +3,7 @@ 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 sound_place = function(itemname, pos) +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) @@ -34,7 +34,7 @@ if mod_mcl_core then awards.unlock(user:get_player_name(), "mcl:hotStuff") end end, - itemname = "mcl_buckets:bucket_lava", + bucketname = "mcl_buckets:bucket_lava", inventory_image = "bucket_lava.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."), @@ -46,22 +46,13 @@ if mod_mcl_core then mcl_buckets.register_liquid({ source_place = "mcl_core:water_source", source_take = {"mcl_core:water_source"}, - itemname = "mcl_buckets:bucket_water", + bucketname = "mcl_buckets:bucket_water", inventory_image = "bucket_water.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) - -- 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 @@ -70,13 +61,13 @@ if mod_mcl_core then minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"}) end sound_place("mcl_core:water_source", pos) - return false + return false, true -- 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 + return false, true end end end, @@ -89,22 +80,13 @@ if mod_mclx_core then mcl_buckets.register_liquid({ source_place = "mclx_core:river_water_source", source_take = {"mclx_core:river_water_source"}, - itemname = "mcl_buckets:bucket_river_water", + bucketname = "mcl_buckets:bucket_river_water", inventory_image = "bucket_river_water.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) - -- 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 @@ -113,13 +95,13 @@ if mod_mclx_core then minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"}) end sound_place("mcl_core:water_source", pos) - return false + return false, true 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 + return false, true end end end, diff --git a/mods/ITEMS/mcl_cake/init.lua b/mods/ITEMS/mcl_cake/init.lua index aeb706287..f3a69f413 100644 --- a/mods/ITEMS/mcl_cake/init.lua +++ b/mods/ITEMS/mcl_cake/init.lua @@ -5,7 +5,7 @@ local CAKE_HUNGER_POINTS = 2 -local S = minetest.get_translator("mcl_cake") +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} @@ -20,9 +20,9 @@ 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'}, + {"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"}, @@ -52,8 +52,11 @@ minetest.register_node("mcl_cake:cake", { 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 = '', + 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() @@ -104,7 +107,7 @@ local register_slice = function(level, nodebox, desc) -- 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) + minetest.check_for_falling(pos) end end end @@ -125,8 +128,12 @@ local register_slice = function(level, nodebox, desc) 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 = '', + 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(), 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.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_cauldrons/init.lua b/mods/ITEMS/mcl_cauldrons/init.lua index 62c45170c..55866f5cc 100644 --- a/mods/ITEMS/mcl_cauldrons/init.lua +++ b/mods/ITEMS/mcl_cauldrons/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_cauldron") +local S = minetest.get_translator(minetest.get_current_modname()) -- Cauldron mod, adds cauldrons. 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..58826d9ab --- /dev/null +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pl.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_cauldron +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.zh_TW.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr new file mode 100644 index 000000000..ea3b97c41 --- /dev/null +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_cauldron +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_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index b92ed4c01..35712dfd1 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_chests") +local S = minetest.get_translator(minetest.get_current_modname()) local mod_doc = minetest.get_modpath("doc") -- Chest Entity @@ -47,7 +47,7 @@ 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("close") @@ -158,8 +158,8 @@ 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) @@ -171,7 +171,7 @@ local open_chests = {} 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 @@ -181,7 +181,7 @@ local player_chest_open = function(player, pos, node_name, textures, param2, dou 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) @@ -190,7 +190,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) @@ -203,7 +203,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 @@ -230,7 +230,7 @@ local chest_update_after_close = function(pos) 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 @@ -245,569 +245,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.obj", + 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 = {"mcl_chests_blank.png"}, + 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, - 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, -}) + 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"}, - 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") + 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"}, + 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"}, - 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") - 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"}, - 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 + 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"}, + 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") - 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.") @@ -944,23 +931,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 }) @@ -1006,7 +993,7 @@ 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.5, 0.375, 0.4375}, }, _chest_entity_textures = {"mcl_chests_ender.png"}, _chest_entity_sound = "mcl_chests_enderchest", @@ -1053,12 +1040,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() + + if not minetest.find_node_near(player:get_pos(), def and def.range or ItemStack():get_definition().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"}, } }) @@ -1108,14 +1109,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 @@ -1133,7 +1134,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 @@ -1314,17 +1315,17 @@ 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"}, } }) @@ -1411,10 +1412,10 @@ minetest.register_lbm({ 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) + 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, + end, }) 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/template.txt b/mods/ITEMS/mcl_chests/locale/template.txt index 1d947184b..d680c24c9 100644 --- a/mods/ITEMS/mcl_chests/locale/template.txt +++ b/mods/ITEMS/mcl_chests/locale/template.txt @@ -24,7 +24,7 @@ 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.= -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.= +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= diff --git a/mods/ITEMS/mcl_clock/init.lua b/mods/ITEMS/mcl_clock/init.lua index 0eb83ee80..65b32b91e 100644 --- a/mods/ITEMS/mcl_clock/init.lua +++ b/mods/ITEMS/mcl_clock/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_clock") +local S = minetest.get_translator(minetest.get_current_modname()) --[[ mcl_clock, renew of the renew of the mcl_clock mod @@ -41,7 +41,7 @@ function mcl_clock.get_clock_frame() return tostring(t) end -local doc_mod = minetest.get_modpath("doc") ~= nil +local doc_mod = minetest.get_modpath("doc") -- Register items function mcl_clock.register_item(name, image, creative, frame) @@ -125,9 +125,9 @@ 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", ""} } }) 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.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_cocoas/init.lua b/mods/ITEMS/mcl_cocoas/init.lua index f19f85154..60ea9e573 100644 --- a/mods/ITEMS/mcl_cocoas/init.lua +++ b/mods/ITEMS/mcl_cocoas/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_cocoas") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_cocoas = {} 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..bfd0d707e --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pl.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_cocoas +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.zh_TW.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr new file mode 100644 index 000000000..d71e2b11b --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_cocoas +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_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.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_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 31944fa88..458ee8fdb 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_compass") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_compass = {} @@ -72,7 +72,7 @@ for frame = 0, compass_frames-1 do table.insert(images, "mcl_compass_compass_"..s..".png") end -local doc_mod = minetest.get_modpath("doc") ~= nil +local doc_mod = minetest.get_modpath("doc") local stereotype_frame = 18 for i,img in ipairs(images) do @@ -108,11 +108,11 @@ for i,img in ipairs(images) do 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", ""} } }) 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..2a9533652 --- /dev/null +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.pl.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_compass +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. +Compass=Kompas +Points to the world origin=Wskazuje na początek świata 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..b4a812659 --- /dev/null +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.zh_TW.tr @@ -0,0 +1,4 @@ +# 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=指向世界原點 diff --git a/mods/ITEMS/mcl_composters/init.lua b/mods/ITEMS/mcl_composters/init.lua new file mode 100644 index 000000000..56422d8b5 --- /dev/null +++ b/mods/ITEMS/mcl_composters/init.lua @@ -0,0 +1,276 @@ +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() + 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)) + -- TODO: play some sounds + -- update composter block + if level < 7 then + level = level + 1 + else + level = "ready" + end + swap_node(pos, {name = "mcl_composters:composter_" .. level}) + -- 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? + -- TODO: play some sounds + 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 (wtf dye?! is this how they make white cocoa) + add_item(pos, "mcl_dye:white") + -- 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/template.txt b/mods/ITEMS/mcl_composters/locale/template.txt new file mode 100644 index 000000000..c5f9bb858 --- /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_composters/textures/mcl_composter_bottom.png b/mods/ITEMS/mcl_composters/textures/mcl_composter_bottom.png new file mode 100644 index 000000000..cfed3a8a5 Binary files /dev/null and b/mods/ITEMS/mcl_composters/textures/mcl_composter_bottom.png differ diff --git a/mods/ITEMS/mcl_composters/textures/mcl_composter_compost.png b/mods/ITEMS/mcl_composters/textures/mcl_composter_compost.png new file mode 100644 index 000000000..afda87c71 Binary files /dev/null and b/mods/ITEMS/mcl_composters/textures/mcl_composter_compost.png differ diff --git a/mods/ITEMS/mcl_composters/textures/mcl_composter_ready.png b/mods/ITEMS/mcl_composters/textures/mcl_composter_ready.png new file mode 100644 index 000000000..7caf79f96 Binary files /dev/null and b/mods/ITEMS/mcl_composters/textures/mcl_composter_ready.png differ diff --git a/mods/ITEMS/mcl_composters/textures/mcl_composter_side.png b/mods/ITEMS/mcl_composters/textures/mcl_composter_side.png new file mode 100644 index 000000000..c9e5a6fe3 Binary files /dev/null and b/mods/ITEMS/mcl_composters/textures/mcl_composter_side.png differ diff --git a/mods/ITEMS/mcl_composters/textures/mcl_composter_top.png b/mods/ITEMS/mcl_composters/textures/mcl_composter_top.png new file mode 100644 index 000000000..fc6e202d3 Binary files /dev/null and b/mods/ITEMS/mcl_composters/textures/mcl_composter_top.png differ diff --git a/mods/ITEMS/mcl_core/crafting.lua b/mods/ITEMS/mcl_core/crafting.lua index cec26e747..3ff2b142c 100644 --- a/mods/ITEMS/mcl_core/crafting.lua +++ b/mods/ITEMS/mcl_core/crafting.lua @@ -30,96 +30,96 @@ for _, p in pairs(planks) do end minetest.register_craft({ - type = 'shapeless', - output = 'mcl_core:mossycobble', - recipe = { 'mcl_core:cobble', 'mcl_core:vine' }, + 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' }, + type = "shapeless", + output = "mcl_core:stonebrickmossy", + recipe = { "mcl_core:stonebrick", "mcl_core:vine" }, }) minetest.register_craft({ - output = 'mcl_core:coarse_dirt 4', + output = "mcl_core:coarse_dirt 4", recipe = { - {'mcl_core:dirt', 'mcl_core:gravel'}, - {'mcl_core:gravel', 'mcl_core:dirt'}, + {"mcl_core:dirt", "mcl_core:gravel"}, + {"mcl_core:gravel", "mcl_core:dirt"}, } }) minetest.register_craft({ - output = 'mcl_core:coarse_dirt 4', + output = "mcl_core:coarse_dirt 4", recipe = { - {'mcl_core:gravel', 'mcl_core:dirt'}, - {'mcl_core:dirt', 'mcl_core:gravel'}, + {"mcl_core:gravel", "mcl_core:dirt"}, + {"mcl_core:dirt", "mcl_core:gravel"}, } }) minetest.register_craft({ - output = 'mcl_core:sandstonesmooth 4', + output = "mcl_core:sandstonesmooth 4", recipe = { - {'mcl_core:sandstone','mcl_core:sandstone'}, - {'mcl_core:sandstone','mcl_core:sandstone'}, + {"mcl_core:sandstone","mcl_core:sandstone"}, + {"mcl_core:sandstone","mcl_core:sandstone"}, } }) minetest.register_craft({ - output = 'mcl_core:redsandstonesmooth 4', + output = "mcl_core:redsandstonesmooth 4", recipe = { - {'mcl_core:redsandstone','mcl_core:redsandstone'}, - {'mcl_core:redsandstone','mcl_core:redsandstone'}, + {"mcl_core:redsandstone","mcl_core:redsandstone"}, + {"mcl_core:redsandstone","mcl_core:redsandstone"}, } }) minetest.register_craft({ - output = 'mcl_core:granite_smooth 4', + 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"}, } }) @@ -140,60 +140,60 @@ minetest.register_craft({ }) 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"}, } }) @@ -227,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 = "mobs_mc: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 = "mobs_mc: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_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"}, } }) minetest.register_craft({ - output = 'mcl_dye:blue 9', + output = "mcl_dye:blue 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"}, } }) @@ -347,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"}, } }) @@ -368,17 +368,17 @@ 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"}, } }) diff --git a/mods/ITEMS/mcl_core/craftitems.lua b/mods/ITEMS/mcl_core/craftitems.lua index 886535473..fc84c50f5 100644 --- a/mods/ITEMS/mcl_core/craftitems.lua +++ b/mods/ITEMS/mcl_core/craftitems.lua @@ -1,6 +1,6 @@ -- mods/default/craftitems.lua -local S = minetest.get_translator("mcl_core") +local S = minetest.get_translator(minetest.get_current_modname()) -- -- Crafting items @@ -93,7 +93,7 @@ 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 }, @@ -139,7 +139,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, }) diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index f66240b94..6cb727d51 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 @@ -174,11 +179,12 @@ minetest.register_abm({ 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,18 +196,32 @@ minetest.register_abm({ end, }) --- Make cactus destroy items minetest.register_abm({ - label = "Cactus destroy items", + 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 - 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, 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.remove_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, }) @@ -247,7 +267,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 @@ -457,12 +477,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 @@ -473,16 +493,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 @@ -596,7 +616,7 @@ end 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 @@ -607,13 +627,13 @@ function mcl_core.generate_huge_spruce_tree(pos) 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) end @@ -631,15 +651,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 @@ -739,8 +758,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 @@ -749,16 +767,14 @@ 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 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) +function mcl_core.get_grass_palette_index(pos) local biome_data = minetest.get_biome_data(pos) local index = 0 if biome_data then @@ -769,7 +785,12 @@ function mcl_core.get_grass_block_type(pos) index = reg_biome._mcl_palette_index end end - return {name="mcl_core:dirt_with_grass", param2=index} + return index +end + +-- Return appropriate grass block node for pos +function mcl_core.get_grass_block_type(pos) + return {name = "mcl_core:dirt_with_grass", param2 = mcl_core.get_grass_palette_index(pos)} end ------------------------------ @@ -821,7 +842,7 @@ minetest.register_abm({ -- 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 @@ -1240,7 +1261,7 @@ 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 @@ -1313,7 +1334,7 @@ minetest.register_abm({ 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 @@ -1335,9 +1356,8 @@ mcl_core.leafdecay_enable_cache = true 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) + --local finds_per_second = 5000 + mcl_core.leafdecay_trunk_find_allow_accumulator = math.floor(dtime * 5000) end) minetest.register_abm({ @@ -1403,7 +1423,7 @@ minetest.register_abm({ -- Remove node minetest.remove_node(p0) leafdecay_particles(p0, n0) - core.check_for_falling(p0) + minetest.check_for_falling(p0) -- Kill depending vines immediately to skip the vines decay delay local surround = { @@ -1420,7 +1440,7 @@ minetest.register_abm({ 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) + minetest.check_for_falling(spos) end end end @@ -1444,7 +1464,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 }) diff --git a/mods/ITEMS/mcl_core/init.lua b/mods/ITEMS/mcl_core/init.lua index 897382e01..c345d057b 100644 --- a/mods/ITEMS/mcl_core/init.lua +++ b/mods/ITEMS/mcl_core/init.lua @@ -17,7 +17,7 @@ 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 3d90dd5ae..b064cebbe 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr @@ -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 @@ -221,17 +221,23 @@ Sugar canes are a plant which has some uses in crafting. Sugar canes will slowly 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 an birch tree.=Der entrindete Stamm einer Birke. -The stripped trunk of an dark oak tree.=Der entrindete Stamm einer Schwarzeiche. -The stripped trunk of an jungle tree.=Der entrindete Stamm eines Dschungelbaums. +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 an spruce tree.=Der entrindete Stamm einer Fichte. +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. +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. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr index 1e1029c0f..1937babd3 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr @@ -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 diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index 86bc489cd..64aadd6db 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Emeraude Emerald Ore=Minerai d'Emeraude 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 @@ -109,7 +109,7 @@ 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. -Granite=Granite +Granite=Granit 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. @@ -165,7 +165,7 @@ 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 Granite=Granit 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. 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..68dfbd3d0 --- /dev/null +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr @@ -0,0 +1,277 @@ +# 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 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.=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 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.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index f93db7c2c..2d5b5462c 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -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=Текущая лава 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..177341846 --- /dev/null +++ b/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr @@ -0,0 +1,257 @@ +# 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 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.=煤炭磚作為煤炭的省位存儲方式,作為熔爐燃料非常有用。一個煤炭磚的燃燒時間相當於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 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 31320c1c7..19d156711 100644 --- a/mods/ITEMS/mcl_core/locale/template.txt +++ b/mods/ITEMS/mcl_core/locale/template.txt @@ -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= @@ -221,17 +221,23 @@ Sugar canes are a plant which has some uses in crafting. Sugar canes will slowly 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 an birch tree.= -The stripped trunk of an dark oak tree.= -The stripped trunk of an jungle 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 an spruce 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.= diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index 9baa6c33e..b4edc5045 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -1,4 +1,4 @@ -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 @@ -16,7 +16,7 @@ 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, } @@ -28,7 +28,7 @@ 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, @@ -48,7 +48,7 @@ minetest.register_node("mcl_core:stone_with_coal", { is_ground_content = true, stack_max = 64, groups = {pickaxey=1, building_block=1, material_stone=1, xp=1}, - drop = 'mcl_core:coal_lump', + drop = "mcl_core:coal_lump", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, @@ -63,7 +63,7 @@ minetest.register_node("mcl_core:stone_with_iron", { is_ground_content = true, stack_max = 64, groups = {pickaxey=3, building_block=1, material_stone=1}, - drop = 'mcl_core:stone_with_iron', + drop = "mcl_core:stone_with_iron", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, @@ -179,11 +179,11 @@ minetest.register_node("mcl_core:stone_with_lapis", { 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_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"}}, } }, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -365,11 +365,16 @@ minetest.register_node("mcl_core:dirt_with_grass", { overlay_tiles = {"mcl_core_grass_block_top.png", "", {name="mcl_core_grass_block_side_overlay.png", tileable_vertical=false}}, palette = "mcl_core_palette_grass.png", palette_index = 0, - color = "#55aa60", + color = "#8EB971", 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 + }, + drop = "mcl_core:dirt", sounds = mcl_sounds.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.1}, }), @@ -422,7 +427,7 @@ minetest.register_node("mcl_core:mycelium", { 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', + drop = "mcl_core:dirt", sounds = mcl_sounds.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.1}, }), @@ -442,7 +447,7 @@ minetest.register_node("mcl_core:podzol", { 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', + drop = "mcl_core:dirt", sounds = mcl_sounds.node_sound_dirt_defaults(), on_construct = mcl_core.on_snowable_construct, _mcl_snowed = "mcl_core:podzol_snow", @@ -487,8 +492,8 @@ 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({ @@ -501,15 +506,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", @@ -652,7 +657,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, @@ -683,7 +688,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, @@ -955,7 +960,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 @@ -1041,7 +1046,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 diff --git a/mods/ITEMS/mcl_core/nodes_cactuscane.lua b/mods/ITEMS/mcl_core/nodes_cactuscane.lua index 4ec005170..62d5cc2b5 100644 --- a/mods/ITEMS/mcl_core/nodes_cactuscane.lua +++ b/mods/ITEMS/mcl_core/nodes_cactuscane.lua @@ -1,6 +1,6 @@ -- 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"), @@ -12,7 +12,10 @@ minetest.register_node("mcl_core:cactus", { 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, @@ -53,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", @@ -76,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 + }, 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) @@ -114,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_core.get_grass_palette_index(pos) + 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 ad861b4f2..1a6780618 100644 --- a/mods/ITEMS/mcl_core/nodes_climb.lua +++ b/mods/ITEMS/mcl_core/nodes_climb.lua @@ -1,5 +1,5 @@ -- Climbable nodes -local S = minetest.get_translator("mcl_core") +local S = minetest.get_translator(minetest.get_current_modname()) local function rotate_climbable(pos, node, user, mode) if mode == screwdriver.ROTATE_FACE then @@ -104,7 +104,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 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), drop = "", _mcl_shears_drop = true, diff --git a/mods/ITEMS/mcl_core/nodes_glass.lua b/mods/ITEMS/mcl_core/nodes_glass.lua index 8c12d8b93..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}, @@ -39,10 +40,11 @@ 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 = minetest.features.use_texture_alpha_string_modes and "blend" or true, stack_max = 64, @@ -56,11 +58,11 @@ function mcl_core.add_stained_glass(desc, recipeitem, colorgroup, color) }) 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 42276685e..0e0f71a11 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -1,7 +1,6 @@ -- 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 vector = vector local math = math @@ -16,13 +15,6 @@ if minetest.features.use_texture_alpha_string_modes then USE_TEXTURE_ALPHA = "blend" end -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."), -} - minetest.register_node("mcl_core:water_flowing", { description = S("Flowing Water"), _doc_items_create_entry = false, @@ -148,7 +140,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, @@ -203,7 +194,6 @@ 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, fire_damage=1}, diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua index a8188350a..67669a861 100644 --- a/mods/ITEMS/mcl_core/nodes_misc.lua +++ b/mods/ITEMS/mcl_core/nodes_misc.lua @@ -1,11 +1,13 @@ -- 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}} minetest.register_node("mcl_core:bone_block", { @@ -52,7 +54,7 @@ minetest.register_node("mcl_core:slimeblock", { }, _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) @@ -172,7 +174,7 @@ minetest.register_node("mcl_core:barrier", { 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 diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index a72935f05..e4903958e 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -1,14 +1,15 @@ -- Tree nodes: Wood, Wooden Planks, Sapling, Leaves, Stripped Wood -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 -- Register tree trunk (wood) and bark -local function register_tree_trunk(subname, description_trunk, description_bark, longdesc, tile_inner, tile_bark, stripped_varient) +local function register_tree_trunk(subname, description_trunk, description_bark, longdesc, tile_inner, tile_bark, stripped_variant) minetest.register_node("mcl_core:"..subname, { description = description_trunk, _doc_items_longdesc = longdesc, @@ -22,7 +23,7 @@ local function register_tree_trunk(subname, description_trunk, description_bark, on_rotate = on_rotate, _mcl_blast_resistance = 2, _mcl_hardness = 2, - _mcl_stripped_varient = stripped_varient, + _mcl_stripped_variant = stripped_variant, }) minetest.register_node("mcl_core:"..subname.."_bark", { @@ -38,7 +39,7 @@ local function register_tree_trunk(subname, description_trunk, description_bark, on_rotate = on_rotate, _mcl_blast_resistance = 2, _mcl_hardness = 2, - _mcl_stripped_varient = stripped_varient.."_bark", + _mcl_stripped_variant = stripped_variant.."_bark", }) minetest.register_craft({ @@ -51,7 +52,7 @@ local function register_tree_trunk(subname, description_trunk, description_bark, end -- Register stripped trunk and stripped wood -local register_stripped_trunk = function(subname, description_stripped_trunk, description_stripped_bark, longdesc, tile_stripped_inner, tile_stripped_bark) +local function register_stripped_trunk(subname, description_stripped_trunk, description_stripped_bark, longdesc, longdesc_wood, tile_stripped_inner, tile_stripped_bark) minetest.register_node("mcl_core:"..subname, { description = description_stripped_trunk, _doc_items_longdesc = longdesc, @@ -60,7 +61,7 @@ local register_stripped_trunk = function(subname, description_stripped_trunk, de 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}, + 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, @@ -69,12 +70,12 @@ local register_stripped_trunk = function(subname, description_stripped_trunk, de minetest.register_node("mcl_core:"..subname.."_bark", { description = description_stripped_bark, - _doc_items_longdesc = S("This is a decorative block."), + _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}, + 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, @@ -151,17 +152,10 @@ local function register_leaves(subname, description, longdesc, tiles, sapling, d paramtype = "light", stack_max = 64, groups = { - handy=1, - hoey=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 + handy = 1, hoey = 1, shearsy = 1, swordy = 1, dig_by_piston = 1, + leaves = 1, leafdecay = leafdecay_distance, deco_block = 1, + flammable = 2, fire_encouragement = 30, fire_flammability = 60, + compostability = 30 }, drop = get_drops(0), _mcl_shears_drop = true, @@ -193,7 +187,11 @@ local function register_sapling(subname, description, longdesc, tt_help, texture 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) @@ -222,13 +220,12 @@ register_tree_trunk("sprucetree", S("Spruce Wood"), S("Spruce Bark"), S("The tru 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") 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_stripped_trunk("stripped_oak", S("Stripped Oak Log"), S("Stripped Oak Wood"), S("The stripped trunk of an oak tree."), "mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_side.png") -register_stripped_trunk("stripped_acacia", S("Stripped Acacia Log"), S("Stripped Acacia Wood"), S("The stripped trunk of an acacia tree."), "mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_side.png") -register_stripped_trunk("stripped_dark_oak", S("Stripped Dark Oak Log"), S("Stripped Dark Oak Wood"), S("The stripped trunk of an dark oak tree."), "mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_side.png") -register_stripped_trunk("stripped_birch", S("Stripped Birch Log"), S("Stripped Birch Wood"), S("The stripped trunk of an birch tree."), "mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_side.png") -register_stripped_trunk("stripped_spruce", S("Stripped Spruce Log"), S("Stripped Spruce Wood"), S("The stripped trunk of an spruce tree."), "mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_side.png") -register_stripped_trunk("stripped_jungle", S("Stripped Jungle Log"), S("Stripped Jungle Wood"), S("The stripped trunk of an jungle tree."),"mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_side.png") - +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") +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") +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") +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") +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") +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") 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"}) @@ -275,4 +272,4 @@ register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from -- Node aliases minetest.register_alias("default:acacia_tree", "mcl_core:acaciatree") -minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") \ No newline at end of file +minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") diff --git a/mods/ITEMS/mcl_core/textures/default_glass_detail.png b/mods/ITEMS/mcl_core/textures/default_glass_detail.png new file mode 100644 index 000000000..6205f84a5 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/default_glass_detail.png 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/mcl_core_glass_black_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_black_detail.png new file mode 100644 index 000000000..9dac71149 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_black_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_blue_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_blue_detail.png new file mode 100644 index 000000000..13d0e83b2 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_blue_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_brown_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_brown_detail.png new file mode 100644 index 000000000..d342045b1 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_brown_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_cyan_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_cyan_detail.png new file mode 100644 index 000000000..6b907f54d Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_cyan_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_gray_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_gray_detail.png new file mode 100644 index 000000000..4dbc15680 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_gray_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_green_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_green_detail.png new file mode 100644 index 000000000..03b9943f1 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_green_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_light_blue_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_light_blue_detail.png new file mode 100644 index 000000000..842441a2c Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_light_blue_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_lime_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_lime_detail.png new file mode 100644 index 000000000..8b80407d3 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_lime_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_magenta_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_magenta_detail.png new file mode 100644 index 000000000..cd2d23458 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_magenta_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_orange_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_orange_detail.png new file mode 100644 index 000000000..930992769 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_orange_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_pink_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_pink_detail.png new file mode 100644 index 000000000..d06f90f6b Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_pink_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_purple_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_purple_detail.png new file mode 100644 index 000000000..a5685731f Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_purple_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_red_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_red_detail.png new file mode 100644 index 000000000..587fbdbdd Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_red_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_silver_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_silver_detail.png new file mode 100644 index 000000000..49d444b80 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_silver_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_white_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_white_detail.png new file mode 100644 index 000000000..e7e0db92d Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_white_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_yellow_detail.png b/mods/ITEMS/mcl_core/textures/mcl_core_glass_yellow_detail.png new file mode 100644 index 000000000..b3fc7c893 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_glass_yellow_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_papyrus.png b/mods/ITEMS/mcl_core/textures/mcl_core_papyrus.png new file mode 100644 index 000000000..c928402f9 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_papyrus.png differ diff --git a/mods/ITEMS/mcl_crafting_table/init.lua b/mods/ITEMS/mcl_crafting_table/init.lua index cbf1cff34..eae503eeb 100644 --- a/mods/ITEMS/mcl_crafting_table/init.lua +++ b/mods/ITEMS/mcl_crafting_table/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_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 @@ -6,6 +6,7 @@ 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) @@ -30,7 +31,6 @@ function mcl_crafting_table.show_crafting_form(player) ) end -local show_crafting_form = mcl_crafting_table.show_crafting_form --cache function for better performances minetest.register_node("mcl_crafting_table:crafting_table", { description = S("Crafting Table"), _tt_help = S("3×3 crafting grid"), @@ -43,7 +43,9 @@ minetest.register_node("mcl_crafting_table:crafting_table", { paramtype2 = "facedir", groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1}, on_rightclick = function(pos, node, player, itemstack) - show_crafting_form(player) + 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, 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.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_doors/api_doors.lua b/mods/ITEMS/mcl_doors/api_doors.lua index 909bb47e4..7d00c4c69 100644 --- a/mods/ITEMS/mcl_doors/api_doors.lua +++ b/mods/ITEMS/mcl_doors/api_doors.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_doors") +local S = minetest.get_translator(minetest.get_current_modname()) local minetest_get_meta = minetest.get_meta -- This helper function calls on_place_node callbacks. diff --git a/mods/ITEMS/mcl_doors/api_trapdoors.lua b/mods/ITEMS/mcl_doors/api_trapdoors.lua index 3999ad0bf..3d2a8e891 100644 --- a/mods/ITEMS/mcl_doors/api_trapdoors.lua +++ b/mods/ITEMS/mcl_doors/api_trapdoors.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_doors") +local S = minetest.get_translator(minetest.get_current_modname()) -- Wrapper around mintest.pointed_thing_to_face_pos. local function get_fpos(placer, pointed_thing) 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.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/register.lua b/mods/ITEMS/mcl_doors/register.lua index 2ffd4b245..c998f6538 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 ]] @@ -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_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/init.lua b/mods/ITEMS/mcl_dye/init.lua index 863abd3d2..727a78460 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -7,13 +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()) + +local math = math +local string = string -- Other mods can use these for looping through available colors mcl_dye.basecolors = {"white", "grey", "black", "red", "yellow", "green", "cyan", "blue", "magenta"} @@ -75,7 +78,7 @@ dyelocal.dyes = { {"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}}, + {"brown", "mcl_dye_brown", S("Cocoa Beans"), {dye=1, craftitem=1, basecolor_brown=1, excolor_orange=1, unicolor_dark_orange=1, compostability = 65}}, {"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}}, @@ -94,7 +97,7 @@ for d=1, #dyelocal.dyes do 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) +function mcl_dye.unicolor_to_dye(unicolor_group) local color = dyelocal.unicolor_to_dye_id[unicolor_group] if color then return "mcl_dye:" .. color @@ -125,8 +128,35 @@ for _, row in ipairs(dyelocal.dyes) do end -- Bone Meal +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) -- Bone meal currently spawns all flowers found in the plains. local flowers_table_plains = { "mcl_flowers:dandelion", @@ -162,12 +192,21 @@ 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) 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 @@ -190,7 +229,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 +255,72 @@ 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 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) @@ -306,6 +358,7 @@ mcl_dye.apply_bone_meal = function(pointed_thing) end 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) @@ -337,7 +390,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,7 +403,7 @@ 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 @@ -508,5 +561,3 @@ minetest.register_craft({ output = "mcl_dye:white 3", recipe = {{"mcl_mobitems:bone"}}, }) - - 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..d16edb5b0 --- /dev/null +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr @@ -0,0 +1,27 @@ +# textdomain: mcl_dye +Bone Meal=Mączka kostna +Light Grey Dye=Jasnoszara farba +Grey Dye=Szara farba +Ink Sac=Torbiel z atramentem +Purple Dye=Fioletowa farba +Lapis Lazuli=Lazuryt +Light Blue Dye=Jasnoniebieska farba +Cyan Dye=Błękitna farba +Cactus Green=Kaktusowa zieleń +Lime Dye=Jasnozielona farba +Dandelion Yellow=Mleczowy żółty +Cocoa Beans=Ziarna kakaowe +Orange Dye=Pomarańczowa farba +Rose Red=Różany czerwony +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.zh_TW.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr new file mode 100644 index 000000000..23d2face2 --- /dev/null +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr @@ -0,0 +1,25 @@ +# textdomain: mcl_dye +Bone Meal=骨粉 +Light Grey Dye=淺灰色染料 +Grey Dye=灰色染料 +Ink Sac=墨囊 +Purple Dye=紫色染料 +Lapis Lazuli=青金石 +Light Blue Dye=淺藍色染料 +Cyan Dye=青色染料 +Cactus Green=仙人掌綠 +Lime Dye=淺綠色染料 +Dandelion Yellow=蒲公英黃 +Cocoa Beans=可可豆 +Orange Dye=橙色染料 +Rose Red=玫瑰紅 +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_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 84327e3f6..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 @@ -97,8 +97,9 @@ mcl_enchanting.enchantments.efficiency = { weight = 10, description = S("Increases mining speed."), curse = false, - on_enchant = function(itemstack, level) - mcl_enchanting.update_groupcaps(itemstack) + on_enchant = function() + -- Updating digging speed is handled by update_groupcaps which + -- is called from load_enchantments. end, requires_tool = false, treasure = false, @@ -379,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}, @@ -396,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}, @@ -415,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 = { @@ -456,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}, @@ -472,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 = { @@ -628,8 +673,8 @@ mcl_enchanting.enchantments.unbreaking = { tool_capabilities.punch_attack_uses = tool_capabilities.punch_attack_uses * (1 + level) itemstack:get_meta():set_tool_capabilities(tool_capabilities) - -- Unbreaking for groupcaps is handled in this function. - mcl_enchanting.update_groupcaps(itemstack) + -- 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 d2db2281a..f505c055e 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) @@ -14,10 +14,11 @@ end function mcl_enchanting.unload_enchantments(itemstack) local itemdef = itemstack:get_definition() - if itemdef.tool_capabilities then - itemstack:get_meta():set_tool_capabilities(nil) - end 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", "") @@ -33,6 +34,7 @@ function mcl_enchanting.load_enchantments(itemstack, enchantments) enchantment_def.on_enchant(itemstack, level) end end + mcl_enchanting.update_groupcaps(itemstack) end tt.reload_itemstack_description(itemstack) end @@ -72,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) @@ -123,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 @@ -132,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) @@ -270,8 +276,14 @@ 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._mcl_armor_texture = new_def._mcl_armor_texture and new_def._mcl_armor_texture .. mcl_enchanting.overlay - new_def._mcl_armor_preview = new_def._mcl_armor_preview and new_def._mcl_armor_preview .. mcl_enchanting.overlay + + if new_def._mcl_armor_texture and not type(new_def._mcl_armor_texture) == "function" then + new_def._mcl_armor_texture = new_def._mcl_armor_texture .. mcl_enchanting.overlay + end + if new_def._mcl_armor_preview and not type(new_def._mcl_armor_preview) == "function" then + new_def._mcl_armor_preview = new_def._mcl_armor_preview .. mcl_enchanting.overlay + end + new_def._mcl_enchanting_enchanted_tool = new_name new_def.after_use = get_after_use_callback(itemdef) local register_list = register_item_list @@ -289,115 +301,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 _, _, _, 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, pr) - 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, level - if pr then - index = pr:next(1,#list) - else - index = math.random(#list) - end - local enchantment = list[index] - local enchantment_def = mcl_enchanting.enchantments[enchantment] - if pr then - level = pr:next(1, enchantment_def.max_level) - else - level = math.random(enchantment_def.max_level) - end - mcl_enchanting.enchant(stack, enchantment, level) + return stack end @@ -436,7 +458,7 @@ 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 + if (not mcl_enchanting.can_enchant_freshly(itemstack:get_name())) or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then return {false, false, false} end local itemname = itemstack:get_name() @@ -493,7 +515,7 @@ 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) @@ -543,11 +565,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) diff --git a/mods/ITEMS/mcl_enchanting/groupcaps.lua b/mods/ITEMS/mcl_enchanting/groupcaps.lua index a445b73f2..2a8372772 100644 --- a/mods/ITEMS/mcl_enchanting/groupcaps.lua +++ b/mods/ITEMS/mcl_enchanting/groupcaps.lua @@ -2,10 +2,7 @@ local groupcaps_cache = {} -- Compute a hash value. function compute_hash(value) - -- minetest.get_password_hash is quite fast, even if it uses a - -- cryptographic hashing function (SHA-1). It is written in C++ and it - -- is probably hard to write a faster hashing function in Lua. - return string.sub(minetest.get_password_hash("ryvnf", minetest.serialize(value)), 1, 8) + 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 @@ -46,7 +43,7 @@ end -- the tool needs to be updated. function mcl_enchanting.update_groupcaps(itemstack) local name = itemstack:get_name() - if not minetest.registered_tools[name].tool_capabilities then + if not minetest.registered_tools[name] or not minetest.registered_tools[name].tool_capabilities then return end diff --git a/mods/ITEMS/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua index 06f9b0f75..9f9fbd271 100644 --- a/mods/ITEMS/mcl_enchanting/init.lua +++ b/mods/ITEMS/mcl_enchanting/init.lua @@ -1,5 +1,6 @@ -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 @@ -151,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) @@ -182,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, 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 index e1178e782..985499964 100644 --- a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr @@ -7,7 +7,7 @@ Blast Protection=Protection contre les explosions Reduces explosion damage and knockback.=Réduit les dégâts d'explosion et de recul. 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 Binding=Malédiction du lien éterne +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. Curse of Vanishing=Malédiction de disparition Item destroyed on death.=Objet détruit à la mort. 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/template.txt b/mods/ITEMS/mcl_enchanting/locale/template.txt index 08fa82097..1f540d6d3 100644 --- a/mods/ITEMS/mcl_enchanting/locale/template.txt +++ b/mods/ITEMS/mcl_enchanting/locale/template.txt @@ -1,100 +1,129 @@ # 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= -Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.= -Curse of Vanishing= -Item destroyed on death.= -Depth Strider= -Increases underwater movement speed.= -Efficiency= -Increases mining speed.= -Feather Falling= -Reduces fall damage.= -Fire Aspect= -Sets target on fire.= -Fire Protection= -Reduces fire damage.= -Flame= -Arrows set target on fire.= -Fortune= -Increases certain block drops.= -Frost Walker= -Turns water beneath the player into frosted ice and prevents the damage from magma blocks.= -Impaling= -Trident deals additional damage to ocean mobs.= -Infinity= -Shooting consumes no regular arrows.= -Knockback= -Increases knockback.= -Looting= -Increases mob loot.= -Loyalty= -Trident returns after being thrown. Higher levels reduce return time.= -Luck of the Sea= -Increases rate of good loot (enchanting books, etc.)= -Lure= -Decreases time until rod catches something.= -Mending= -Repair the item while gaining XP orbs.= -Multishot= -Shoot 3 arrows at the cost of one.= -Piercing= + + +### enchantments.lua ### + Arrows passes through multiple objects.= -Power= -Increases arrow damage.= -Projectile Protection= -Reduces projectile damage.= -Protection= -Reduces most types of damage by 4% for each level.= -Punch= -Increases arrow knockback.= -Quick Charge= +Arrows set target on fire.= +Bane of Arthropods= +Channeling= + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.= + +Curse of Vanishing= Decreases crossbow charging time.= -Respiration= +Decreases time until rod catches something.= +Depth Strider= +Efficiency= Extends underwater breathing time.= -Riptide= -Trident launches player with itself when thrown. Works only in water or rain.= -Sharpness= -Increases damage.= -Silk Touch= -Mined blocks drop themselves.= -Smite= +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.= -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 damage.= Increases item durability.= -Inventory= -@1 Lapis Lazuli= +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= -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.= + +### init.lua ### + '@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.= + []= +@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= -Enchant= + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.= + +Enchanting succeded.= +Forcefully enchant an item= + +Place a tool, armor, weapon or book into the top left slot, and then place 1-3 Lapis Lazuli in the slot to the right.= + +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= diff --git a/mods/ITEMS/mcl_end/building.lua b/mods/ITEMS/mcl_end/building.lua index 94fd26434..3c8f7f66c 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 diff --git a/mods/ITEMS/mcl_end/chorus_plant.lua b/mods/ITEMS/mcl_end/chorus_plant.lua index 0e35ff286..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 --- @@ -32,7 +35,7 @@ local no_detach = {} 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 @@ -450,7 +453,7 @@ function mcl_end.grow_chorus_plant_step(pos, node, pr) end --- ABM --- -local seed = minetest.get_mapgen_params().seed +local seed = minetest.get_mapgen_setting("seed") local pr = PseudoRandom(seed) minetest.register_abm({ label = "Chorus plant growth", @@ -471,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/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index a188be383..b7c80c55a 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_end") +local S = minetest.get_translator(minetest.get_current_modname()) local vector = vector diff --git a/mods/ITEMS/mcl_end/eye_of_ender.lua b/mods/ITEMS/mcl_end/eye_of_ender.lua index afac9ebfc..ea3d70aba 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, 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/textures/mcl_end_crystal_beam.png b/mods/ITEMS/mcl_end/textures/mcl_end_crystal_beam.png index 1259a5d0e..a671de7ac 100644 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_crystal_beam.png and b/mods/ITEMS/mcl_end/textures/mcl_end_crystal_beam.png differ diff --git a/mods/ITEMS/mcl_farming/beetroot.lua b/mods/ITEMS/mcl_farming/beetroot.lua index 7caf5103e..21096042b 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) @@ -133,7 +133,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, }) diff --git a/mods/ITEMS/mcl_farming/carrots.lua b/mods/ITEMS/mcl_farming/carrots.lua index 4599d39ee..1c3ebcdfa 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 @@ -63,10 +63,10 @@ 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 = { @@ -86,12 +86,12 @@ 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 + if new then return new else return minetest.do_item_eat(3, nil, itemstack, placer, pointed_thing) @@ -112,9 +112,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/hoes.lua b/mods/ITEMS/mcl_farming/hoes.lua index db470b999..28ad938f4 100644 --- a/mods/ITEMS/mcl_farming/hoes.lua +++ b/mods/ITEMS/mcl_farming/hoes.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_farming") +local S = minetest.get_translator(minetest.get_current_modname()) local function create_soil(pos, inv) if pos == nil then 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/melon.lua b/mods/ITEMS/mcl_farming/melon.lua index 38b4c713c..6bbc507ec 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, + 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/potatoes.lua b/mods/ITEMS/mcl_farming/potatoes.lua index a7f5a7084..04a971de8 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 @@ -67,11 +67,11 @@ 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 = { @@ -91,13 +91,13 @@ 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}, _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 + if new then return new else return minetest.do_item_eat(1, nil, itemstack, placer, pointed_thing) @@ -112,7 +112,7 @@ 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, }) diff --git a/mods/ITEMS/mcl_farming/pumpkin.lua b/mods/ITEMS/mcl_farming/pumpkin.lua index 86ddf707b..a38f11862 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,7 +99,10 @@ 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, + enderman_takable = 1, compostability = 65 + }, sounds = mcl_sounds.node_sound_wood_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 1, @@ -120,8 +124,54 @@ pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:enderman" pumpkin_face_base_def._mcl_armor_element = "head" pumpkin_face_base_def._mcl_armor_texture = "mcl_farming_pumpkin_face.png" pumpkin_face_base_def._mcl_armor_preview = "mcl_farming_pumpkin_face_preview.png" + if minetest.get_modpath("mcl_armor") then + 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 @@ -183,7 +233,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, }) diff --git a/mods/ITEMS/mcl_farming/shared_functions.lua b/mods/ITEMS/mcl_farming/shared_functions.lua index 025894a11..e942415f5 100644 --- a/mods/ITEMS/mcl_farming/shared_functions.lua +++ b/mods/ITEMS/mcl_farming/shared_functions.lua @@ -1,11 +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 @@ -206,7 +210,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s -- 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 @@ -232,7 +236,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s -- Register gourd if not gourd_def.after_dig_node then - gourd_def.after_dig_node = function(blockpos, oldnode, oldmetadata, user) + function gourd_def.after_dig_node(blockpos, oldnode, oldmetadata, user) -- Disconnect any connected stems, turning them back to normal stems for n=1, #neighbors do local offset = neighbors[n] @@ -247,7 +251,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s 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 local stempos = vector.add(blockpos, neighbors[n]) @@ -295,7 +299,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s 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 diff --git a/mods/ITEMS/mcl_farming/soil.lua b/mods/ITEMS/mcl_farming/soil.lua index f7a7bbbfb..8b31d888f 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"}, @@ -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 diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_hud.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_hud.png new file mode 100644 index 000000000..48f47253b Binary files /dev/null and b/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_hud.png differ diff --git a/mods/ITEMS/mcl_farming/wheat.lua b/mods/ITEMS/mcl_farming/wheat.lua index d986e5be3..a254ed36c 100644 --- a/mods/ITEMS/mcl_farming/wheat.lua +++ b/mods/ITEMS/mcl_farming/wheat.lua @@ -1,4 +1,4 @@ -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” @@ -9,7 +9,7 @@ minetest.register_craftitem("mcl_farming: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. ]]), - groups = { craftitem=1 }, + 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") @@ -85,10 +85,10 @@ 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, @@ -104,20 +104,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_dye:brown", "mcl_farming:wheat_item"}, } }) @@ -125,7 +125,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), @@ -136,13 +136,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 @@ -156,8 +156,11 @@ minetest.register_node("mcl_farming:hay_block", { stack_max = 64, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {handy=1, hoey=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, @@ -165,18 +168,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/init.lua b/mods/ITEMS/mcl_fences/init.lua index ddd85d470..243cc2219 100644 --- a/mods/ITEMS/mcl_fences/init.lua +++ b/mods/ITEMS/mcl_fences/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_fences") +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} @@ -237,7 +237,7 @@ function mcl_fences.register_fence_gate(id, fence_gate_name, texture, groups, ha 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) +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 @@ -272,17 +272,17 @@ for w=1, #woods do 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', + output = "mcl_fences:"..id.." 3", recipe = { - {wood[6], 'mcl_core:stick', wood[6]}, - {wood[6], 'mcl_core:stick', wood[6]}, + {wood[6], "mcl_core:stick", wood[6]}, + {wood[6], "mcl_core:stick", wood[6]}, } }) minetest.register_craft({ - output = 'mcl_fences:'..id_gate, + output = "mcl_fences:"..id_gate, recipe = { - {'mcl_core:stick', wood[6], 'mcl_core:stick'}, - {'mcl_core:stick', wood[6], 'mcl_core:stick'}, + {"mcl_core:stick", wood[6], "mcl_core:stick"}, + {"mcl_core:stick", wood[6], "mcl_core:stick"}, } }) end @@ -292,7 +292,7 @@ end 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', + 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"}, 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_fire/fire_charge.lua b/mods/ITEMS/mcl_fire/fire_charge.lua index 69e536790..4d18e44ed 100644 --- a/mods/ITEMS/mcl_fire/fire_charge.lua +++ b/mods/ITEMS/mcl_fire/fire_charge.lua @@ -1,4 +1,4 @@ -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 @@ -14,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 = 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 @@ -29,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 @@ -59,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 5aa02aec1..39a4ce882 100644 --- a/mods/ITEMS/mcl_fire/flint_and_steel.lua +++ b/mods/ITEMS/mcl_fire/flint_and_steel.lua @@ -1,4 +1,4 @@ -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 @@ -14,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 = 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() @@ -76,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 f1a95fec6..79b46a701 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -1,10 +1,10 @@ -- Global namespace for functions mcl_fire = {} -local modpath = minetest.get_modpath(minetest.get_current_modname()) -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) local has_mcl_portals = minetest.get_modpath("mcl_portals") @@ -24,29 +24,33 @@ local get_connected_players = minetest.get_connected_players local vector = vector local math = math --- 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 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 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, @@ -86,18 +90,7 @@ 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) +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 @@ -124,7 +117,6 @@ 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) @@ -132,82 +124,6 @@ minetest.register_node("mcl_fire:fire", { minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) end end, - on_timer = function(pos) - local node = 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 = 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 = get_node({x=pos.x, y=pos.z-1, z=pos.z}) - local below_is_flammable = get_item_group(below.name, "flammable") > 0 - -- Extinguish fire - if (not fire_enabled) and (math.random(1,3) == 1) then - remove_node(pos) - return - end - if age == 15 and not below_is_flammable then - remove_node(pos) - return - elseif age > 3 and #flammables == 0 and not below_is_flammable and math.random(1,4) == 1 then - 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 - set_node(pos, node) - end - -- Restart timer - fire_timer(pos) - return - end - -- Spawn fire to nearby flammable nodes - local is_next_to_flammable = 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 = 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 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 = 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 = get_node(nodes[r]).name - local ndef = minetest.registered_nodes[nn] - local fgroup = 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 - 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 @@ -224,7 +140,6 @@ minetest.register_node("mcl_fire:fire", { mcl_portals.light_nether_portal(pos) end - fire_timer(pos) mcl_particles.spawn_smoke(pos, "fire", smoke_pdef) end, on_destruct = function(pos) @@ -255,7 +170,6 @@ 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) @@ -263,29 +177,8 @@ minetest.register_node("mcl_fire:eternal_fire", { 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 = 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 find_node_near(airs[r], 1, {"group:flammable"}) then - local node = 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 has_mcl_portals then --Calling directly minetest.get_modpath consumes 4x more compute time mcl_portals.light_nether_portal(pos) end @@ -409,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 @@ -424,27 +336,13 @@ minetest.register_abm({ chance = 1, catch_up = false, action = function(pos, node, active_object_count, active_object_count_wider) - remove_node(pos) + minetest.remove_node(pos) minetest.sound_play("fire_extinguish_flame", {pos = pos, max_hear_distance = 16, gain = 0.15}, true) 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 = get_node_or_nil(npos) - if node and node.name and 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 @@ -455,67 +353,88 @@ if not fire_enabled then interval = 10, chance = 10, catch_up = false, - action = remove_node, + action = minetest.remove_node, }) else -- Fire enabled - -- Set fire to air nodes + -- Fire Spread + minetest.register_abm({ + label = "Ignite flame", + nodenames ={"mcl_fire:fire","mcl_fire:eternal_fire"}, + interval = 7, + chance = 12, + catch_up = false, + action = function(pos) + local p = get_ignitable(pos) + if p then + spawn_fire(p) + shuffle_table(adjacents) + end + end + }) + + --lava fire spread minetest.register_abm({ label = "Ignite fire by lava", - nodenames = {"group:lava"}, - neighbors = {"air"}, + nodenames = {"mcl_core:lava_source","mcl_nether:nether_lava_source"}, + neighbors = {"air","group:flammable"}, interval = 7, chance = 3, 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 = 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 = get_node(target) - if not node or node.name ~= "air" then - return - end - 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 = 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" - }) + 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. 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 da94d9278..4a1d52ee2 100644 --- a/mods/ITEMS/mcl_fire/mod.conf +++ b/mods/ITEMS/mcl_fire/mod.conf @@ -1,3 +1,3 @@ name = mcl_fire -depends = mcl_core, mcl_worlds, mcl_sounds, mcl_particles +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_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.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/register.lua b/mods/ITEMS/mcl_fireworks/register.lua index c441254cb..23066b663 100644 --- a/mods/ITEMS/mcl_fireworks/register.lua +++ b/mods/ITEMS/mcl_fireworks/register.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_fireworks") +local S = minetest.get_translator(minetest.get_current_modname()) local tt_help = S("Flight Duration:") local description = S("Firework Rocket") diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index 567e96e96..788e591dc 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -1,8 +1,6 @@ --Fishing Rod, Bobber, and Flying Bobber mechanics and Bobber artwork by Rootyjr. -local S = minetest.get_translator("mcl_fishing") - -local math = math +local S = minetest.get_translator(minetest.get_current_modname()) local bobber_ENTITY={ physical = false, @@ -33,141 +31,153 @@ local fish = function(itemstack, player, pointed_thing) end end - local pos = player:get_pos() + local pos = player:get_pos() - local objs = minetest.get_objects_inside_radius(pos, 125) - local ent - local noent = false + local objs = minetest.get_objects_inside_radius(pos, 125) + local num = 0 + local ent = nil + local noent = true - local durability = 65 - local unbreaking = mcl_enchanting.get_enchantment(itemstack, "unbreaking") - if unbreaking > 0 then - durability = durability * (unbreaking + 1) - end + local durability = 65 + local unbreaking = mcl_enchanting.get_enchantment(itemstack, "unbreaking") + if unbreaking > 0 then + durability = durability * (unbreaking + 1) + end - --Check for bobber if so handle. - for n = 1, #objs do - ent = objs[n]:get_luaentity() - if ent then - if ent.player and ent.objtype=="fishing" then - if (player:get_player_name() == ent.player) then - if ent._dive == true then - local items - 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} - local junk_values = {10, 8.1, 6.1, 4.2} - local luck_of_the_sea = math.min(mcl_enchanting.get_enchantment(itemstack, "luck_of_the_sea"), 3) - local index = luck_of_the_sea + 1 - local fish_value = fish_values[index] - local junk_value = junk_values[index] + fish_value - if r <= fish_value then - -- Fish - items = mcl_loot.get_loot({ - items = { - { itemstring = "mcl_fishing:fish_raw", weight = 60 }, - { itemstring = "mcl_fishing:salmon_raw", weight = 25 }, - { itemstring = "mcl_fishing:clownfish_raw", weight = 2 }, - { itemstring = "mcl_fishing:pufferfish_raw", weight = 13 }, - } - }, pr) - elseif r <= junk_value then - -- Junk - items = mcl_loot.get_loot({ - items = { - { itemstring = "mcl_core:bowl", weight = 10 }, - { itemstring = "mcl_fishing:fishing_rod", weight = 2, wear_min = 6554, wear_max = 65535 }, -- 10%-100% damage - { itemstring = "mcl_mobitems:leather", weight = 10 }, - { itemstring = "mcl_armor:boots_leather", weight = 10, wear_min = 6554, wear_max = 65535 }, -- 10%-100% damage - { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, - { itemstring = "mcl_core:stick", weight = 5 }, - { 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:string", weight = 10 }, -- TODO: Tripwire Hook - } - }, 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_mobs:nametag", }, - { itemstring = "mcl_mobitems:saddle", }, - { itemstring = "mcl_flowers:waterlily", }, - } - }, pr) - end - local item - if #items >= 1 then - item = ItemStack(items[1]) - else - item = ItemStack() - end - local inv = player:get_inventory() - if inv:room_for_item("main", item) then - inv:add_item("main", item) - else - minetest.add_item(pos, item) - end - if mcl_experience.throw_experience then - mcl_experience.throw_experience(pos, math.random(1,6)) - end + --Check for bobber if so handle. + for n = 1, #objs do + ent = objs[n]:get_luaentity() + if ent then + if ent.player and ent.objtype=="fishing" then + if (player:get_player_name() == ent.player) then + noent = false + if ent._dive == true then + local itemname + local items + local itemcount = 1 + 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} + local junk_values = {10, 8.1, 6.1, 4.2} + local luck_of_the_sea = math.min(mcl_enchanting.get_enchantment(itemstack, "luck_of_the_sea"), 3) + local index = luck_of_the_sea + 1 + local fish_value = fish_values[index] + local junk_value = junk_values[index] + fish_value + if r <= fish_value then + -- Fish + items = mcl_loot.get_loot({ + items = { + { itemstring = "mcl_fishing:fish_raw", weight = 60 }, + { 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) + elseif r <= junk_value then + -- Junk + items = mcl_loot.get_loot({ + items = { + { itemstring = "mcl_core:bowl", weight = 10 }, + { itemstring = "mcl_fishing:fishing_rod", weight = 2, wear_min = 6554, wear_max = 65535 }, -- 10%-100% damage + { itemstring = "mcl_mobitems:leather", weight = 10 }, + { itemstring = "mcl_armor:boots_leather", weight = 10, wear_min = 6554, wear_max = 65535 }, -- 10%-100% damage + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, + { itemstring = "mcl_core:stick", weight = 5 }, + { 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:string", weight = 10 }, -- TODO: Tripwire Hook + }, + stacks_min = 1, + stacks_max = 1, + }, pr) + else + -- Treasure + items = mcl_loot.get_loot({ + items = { + { 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", }, + }, + stacks_min = 1, + stacks_max = 1, + }, pr) + end + local item + if #items >= 1 then + item = ItemStack(items[1]) + else + item = ItemStack() + end + local inv = player:get_inventory() + if inv:room_for_item("main", item) then + inv:add_item("main", item) + else + minetest.add_item(pos, item) + end + if mcl_experience.throw_xp then + mcl_experience.throw_xp(pos, math.random(1,6)) + end - if not minetest.is_creative_enabled(player:get_player_name()) then - local idef = itemstack:get_definition() - itemstack:add_wear(65535/durability) -- 65 uses - if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then - minetest.sound_play(idef.sound.breaks, {pos=player:get_pos(), gain=0.5}, true) + if not minetest.is_creative_enabled(player:get_player_name()) then + local idef = itemstack:get_definition() + itemstack:add_wear(65535/durability) -- 65 uses + if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then + minetest.sound_play(idef.sound.breaks, {pos=player:get_pos(), gain=0.5}, true) + end end end - end - --Check if object is on land. - local epos = ent.object:get_pos() - epos.y = math.floor(epos.y) - local node = minetest.get_node(epos) - local def = minetest.registered_nodes[node.name] - if def.walkable then - if not minetest.is_creative_enabled(player:get_player_name()) then - local idef = itemstack:get_definition() - itemstack:add_wear((65535/durability)*2) -- if so and not creative then wear double like in MC. - if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then - minetest.sound_play(idef.sound.breaks, {pos=player:get_pos(), gain=0.5}, true) + --Check if object is on land. + local epos = ent.object:get_pos() + epos.y = math.floor(epos.y) + local node = minetest.get_node(epos) + local def = minetest.registered_nodes[node.name] + if def.walkable then + if not minetest.is_creative_enabled(player:get_player_name()) then + local idef = itemstack:get_definition() + itemstack:add_wear((65535/durability)*2) -- if so and not creative then wear double like in MC. + if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then + minetest.sound_play(idef.sound.breaks, {pos=player:get_pos(), gain=0.5}, true) + end end end + --Destroy bobber. + ent.object:remove() + return itemstack end - --Destroy bobber. - ent.object:remove() - noent = false - break end end end - end - --Check for flying bobber. - for n = 1, #objs do - ent = objs[n]:get_luaentity() - if ent then - if ent._thrower and ent.objtype=="fishing" then - if player:get_player_name() == ent._thrower then - noent = false - break + --Check for flying bobber. + for n = 1, #objs do + ent = objs[n]:get_luaentity() + if ent then + if ent._thrower and ent.objtype=="fishing" then + if player:get_player_name() == ent._thrower then + noent = false + break + end end end end - end - --If no bobber or flying_bobber exists then throw bobber. - if noent then - local playerpos = player:get_pos() - local dir = player:get_look_dir() - 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 - return itemstack + --If no bobber or flying_bobber exists then throw bobber. + if noent == true then + local playerpos = player:get_pos() + local dir = player:get_look_dir() + 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 -- Movement function of bobber @@ -190,7 +200,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() @@ -331,11 +341,13 @@ minetest.register_entity("mcl_fishing:flying_bobber_entity", flying_bobber_ENTIT mcl_throwing.register_throwable_object("mcl_fishing:flying_bobber", "mcl_fishing:flying_bobber_entity", 5) -local function remove_bobber(player) +-- If player leaves area, remove bobber. +minetest.register_on_leaveplayer(function(player) local objs = minetest.get_objects_inside_radius(player:get_pos(), 250) - + local ent = nil + local noent = true for n = 1, #objs do - local ent = objs[n]:get_luaentity() + ent = objs[n]:get_luaentity() if ent then if ent.player and ent.objtype=="fishing" then ent.object:remove() @@ -344,13 +356,26 @@ local function remove_bobber(player) end end end -end - --- If player leaves area, remove bobber. -minetest.register_on_leaveplayer(remove_bobber) +end) -- If player dies, remove bobber. -minetest.register_on_dieplayer(remove_bobber) +minetest.register_on_dieplayer(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 + if ent.player and ent.objtype=="fishing" then + ent.object:remove() + elseif ent._thrower and ent.objtype=="fishing" then + ent.object:remove() + end + end + end +end) -- Fishing Rod minetest.register_tool("mcl_fishing:fishing_rod", { @@ -373,17 +398,17 @@ minetest.register_tool("mcl_fishing:fishing_rod", { 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({ 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_flowerpots/init.lua b/mods/ITEMS/mcl_flowerpots/init.lua index 21d4c04e6..578553b31 100644 --- a/mods/ITEMS/mcl_flowerpots/init.lua +++ b/mods/ITEMS/mcl_flowerpots/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_flowerpots") +local S = minetest.get_translator(minetest.get_current_modname()) local has_doc = minetest.get_modpath("doc") mcl_flowerpots = {} @@ -49,11 +49,11 @@ minetest.register_node("mcl_flowerpots:flower_pot", { }) minetest.register_craft({ - output = 'mcl_flowerpots:flower_pot', + output = "mcl_flowerpots:flower_pot", recipe = { - {'mcl_core:brick', '', 'mcl_core:brick'}, - {'', 'mcl_core:brick', ''}, - {'', '', ''}, + {"mcl_core:brick", "", "mcl_core:brick"}, + {"", "mcl_core:brick", ""}, + {"", "", ""}, } }) 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_flowers/init.lua b/mods/ITEMS/mcl_flowers/init.lua index d07a125cb..d5112a36d 100644 --- a/mods/ITEMS/mcl_flowers/init.lua +++ b/mods/ITEMS/mcl_flowers/init.lua @@ -1,7 +1,9 @@ -local S = minetest.get_translator("mcl_flowers") -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil +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") local has_mcl_flowerpots = minetest.get_modpath("mcl_flowerpots") -local modpath = minetest.get_modpath("mcl_flowers") mcl_flowers = {} mcl_flowers.registered_simple_flowers = {} @@ -58,7 +60,7 @@ 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] = { + mcl_flowers.registered_simple_flowers[newname] = { name=name, desc=def.desc, image=def.image, @@ -78,7 +80,13 @@ function mcl_flowers.register_simple_flower(name, def) walkable = false, stack_max = 64, drop = def.drop, - 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}, + 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, @@ -101,10 +109,10 @@ 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 = { @@ -141,7 +149,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 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), drop = wheat_seed_drop, _mcl_shears_drop = true, @@ -165,6 +178,7 @@ 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) @@ -185,7 +199,15 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im 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} + 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 + } + if name == "double_grass" then + bottom_groups.compostability = 50 + end if is_flower then bottom_groups.flower = 1 bottom_groups.place_flowerlike = 1 @@ -408,7 +430,10 @@ minetest.register_node("mcl_flowers:waterlily", { 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 = { @@ -458,7 +483,6 @@ minetest.register_node("mcl_flowers:waterlily", { end end end - return itemstack end, on_rotate = on_rotate, @@ -469,29 +493,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" } - - 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.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/register.lua b/mods/ITEMS/mcl_flowers/register.lua index 9b65caebf..b45f3e1ee 100644 --- a/mods/ITEMS/mcl_flowers/register.lua +++ b/mods/ITEMS/mcl_flowers/register.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_flowers") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_flowers.register_simple_flower("poppy", { desc = S("Poppy"), diff --git a/mods/ITEMS/mcl_furnaces/init.lua b/mods/ITEMS/mcl_furnaces/init.lua index af2a60952..9f836d161 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 @@ -217,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 @@ -239,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 @@ -461,7 +461,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 @@ -471,16 +471,16 @@ 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) 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_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index 4bcee2279..78356de71 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_heads") +local S = minetest.get_translator(minetest.get_current_modname()) local mod_doc = minetest.get_modpath("doc") local mod_screwdriver = minetest.get_modpath("screwdriver") 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_hoppers/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index eaff8f83d..87831490f 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -1,18 +1,18 @@ -local S = minetest.get_translator("mcl_hoppers") +local S = minetest.get_translator(minetest.get_current_modname()) --[[ 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;]".. + "list[context;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[context;main]".. "listring[current_player;main]" -- Downwards hopper (base definition) @@ -61,7 +61,7 @@ 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 @@ -71,7 +71,7 @@ local def_hopper = { 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() @@ -343,14 +343,14 @@ minetest.register_abm({ local abovenode = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}) 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 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" then + 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. @@ -397,7 +397,7 @@ minetest.register_abm({ -- 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 @@ -442,7 +442,7 @@ 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 @@ -454,7 +454,7 @@ minetest.register_abm({ 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 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_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua index fbd4d545a..d46a393b8 100644 --- a/mods/ITEMS/mcl_itemframes/init.lua +++ b/mods/ITEMS/mcl_itemframes/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_itemframes") +local S = minetest.get_translator(minetest.get_current_modname()) local VISUAL_SIZE = 0.3 @@ -13,8 +13,8 @@ minetest.register_entity("mcl_itemframes:item",{ _scale = 1, on_activate = function(self, staticdata) - if staticdata ~= nil and staticdata ~= "" then - local data = staticdata:split(';') + 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] @@ -25,7 +25,7 @@ minetest.register_entity("mcl_itemframes:item",{ end end end - if self._texture ~= nil then + if self._texture then self.object:set_properties({ textures={self._texture}, visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale}, @@ -33,10 +33,10 @@ minetest.register_entity("mcl_itemframes:item",{ 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 + 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 @@ -44,7 +44,7 @@ minetest.register_entity("mcl_itemframes:item",{ end, _update_texture = function(self) - if self._texture ~= nil then + if self._texture then self.object:set_properties({ textures={self._texture}, visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale}, @@ -299,11 +299,11 @@ minetest.register_node("mcl_itemframes:item_frame",{ }) 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"}, } }) 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..8de889471 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr @@ -0,0 +1,5 @@ +# 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 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_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index 249603b58..6c51a6c94 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -1,4 +1,7 @@ -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 = {} @@ -20,8 +23,8 @@ function mcl_jukebox.register_record(title, author, identifier, image, sound) 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(mcl_colors.AQUA, S("Music Disc")) .. "\n" .. - core.colorize(mcl_colors.GRAY, S("@1—@2", author, title)), + 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, @@ -45,7 +48,7 @@ local function now_playing(player, name) end local id - if hud ~= nil then + if hud then id = hud player:hud_change(id, "text", text) else @@ -67,7 +70,7 @@ local function now_playing(player, name) 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 @@ -82,19 +85,21 @@ 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 name = itemstack:get_name() +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 @@ -134,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 @@ -145,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 @@ -204,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 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_lanterns/init.lua b/mods/ITEMS/mcl_lanterns/init.lua new file mode 100644 index 000000000..65faa5e8c --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/init.lua @@ -0,0 +1,284 @@ +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" +} + +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" +} + +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") \ No newline at end of file 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/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..efdd1ed98 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/register.lua @@ -0,0 +1,26 @@ +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"}, + }, +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_chain.png b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_chain.png new file mode 100644 index 000000000..01725114a Binary files /dev/null and b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_chain.png differ diff --git a/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_chain_inv.png b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_chain_inv.png new file mode 100644 index 000000000..a8c89dab4 Binary files /dev/null and b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_chain_inv.png differ diff --git a/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_lantern.png b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_lantern.png new file mode 100644 index 000000000..f9936e0fb Binary files /dev/null and b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_lantern.png differ diff --git a/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_lantern_inv.png b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_lantern_inv.png new file mode 100644 index 000000000..8bdc8095f Binary files /dev/null and b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_lantern_inv.png differ diff --git a/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_soul_lantern.png b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_soul_lantern.png new file mode 100644 index 000000000..6e20058ea Binary files /dev/null and b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_soul_lantern.png differ diff --git a/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_soul_lantern_inv.png b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_soul_lantern_inv.png new file mode 100644 index 000000000..55624c749 Binary files /dev/null and b/mods/ITEMS/mcl_lanterns/textures/mcl_lanterns_soul_lantern_inv.png differ diff --git a/mods/ITEMS/mcl_maps/colors.json b/mods/ITEMS/mcl_maps/colors.json index 0aa23f0fc..cd3504252 100644 --- a/mods/ITEMS/mcl_maps/colors.json +++ b/mods/ITEMS/mcl_maps/colors.json @@ -1 +1 @@ -{"player.png": [123, 74, 62], "player_back.png": [114, 68, 56], "mcl_skins_player_dummy.png": [125, 125, 125], "mcl_skins_player_1.png": [103, 100, 86], "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": [98, 50, 98], "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": [50, 50, 249], "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_parrot_green.png": [47, 208, 62], "mobs_mc_llama_decor_magenta.png": [249, 50, 249], "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_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": [176, 171, 163], "mobs_mc_villager_priest.png": [100, 64, 74], "mobs_mc_villager_smith.png": [76, 76, 63], "mobs_mc_horse_armor_gold.png": [143, 110, 59], "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": [81, 80, 67], "mobs_mc_spawn_icon_horse_skeleton.png": [245, 204, 202], "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_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": [104, 168, 194], "mobs_mc_zombie_priest.png": [120, 104, 110], "mobs_mc_llama_decor_black.png": [50, 50, 50], "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": [98, 98, 98], "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_horse_armor_iron.png": [134, 123, 118], "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_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_trading_formspec_bg.png": [157, 157, 157], "mobs_mc_llama_chest.png": [70, 53, 36], "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": [50, 98, 50], "mobs_mc_cow.png": [94, 68, 55], "mobs_mc_llama_decor_brown.png": [101, 75, 60], "mobs_mc_villager_butcher.png": [82, 83, 71], "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], "mcl_totems_totem.png": [185, 139, 52], "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_horse_armor_diamond.png": [78, 110, 129], "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": [249, 249, 249], "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": [185, 185, 185], "mobs_mc_llama_decor_cyan.png": [18, 249, 249], "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_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": [50, 249, 50], "mobs_mc_llama_brown.png": [136, 97, 52], "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": [249, 50, 50], "mobs_mc_enderman.png": [3, 10, 10], "mobs_mc_mooshroom_brown.png": [93, 50, 28], "mobs_mc_llama_decor_pink.png": [249, 161, 175], "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_spit.png": [221, 218, 246], "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": [249, 249, 50], "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": [249, 131, 50], "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_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_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], "mobs_mc_gameconfig_enderman_cactus_background.png": [44, 71, 27], "mcl_paintings_paintings.png": [104, 99, 89], "mcl_paintings_painting.png": [139, 133, 119], "mcl_particles_lava.png": [250, 150, 64], "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_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_smoke.png": [174, 174, 174], "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], "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_experience_bottle.png": [136, 174, 169], "experience_bar_background.png": [49, 46, 45], "experience_orb.png": [93, 174, 0], "experience_bar.png": [74, 102, 70], "mcl_bossbars_empty.png": [255, 255, 255], "mcl_bossbars.png": [76, 68, 75], "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_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], "mcl_fireworks_rocket.png": [155, 84, 71], "mcl_bows_arrow_inv.png": [144, 129, 121], "mcl_bows_arrow_overlay.png": [193, 191, 186], "mcl_bows_bow_1.png": [112, 95, 79], "mcl_bows_bow_0.png": [111, 94, 79], "mcl_bows_bow_2.png": [115, 98, 82], "mcl_bows_bow.png": [114, 95, 78], "mcl_bows_arrow.png": [133, 116, 108], "mcl_bows_arrow_front.png": [178, 175, 168], "mcl_bows_arrow_back.png": [218, 216, 213], "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_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_chicken_raw.png": [217, 178, 149], "mcl_mobitems_ghast_tear.png": [148, 160, 166], "mcl_mobitems_porkchop_raw.png": [160, 72, 69], "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], "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_pumpkin_face_preview.png": [166, 81, 38], "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_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": [251, 251, 251], "mcl_end_end_rod_side.png": [242, 202, 177], "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], "mcl_compass_compass_02.png": [116, 107, 104], "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], "mcl_compass_compass_26.png": [117, 107, 104], "mcl_compass_compass_25.png": [117, 107, 105], "mcl_compass_compass_24.png": [117, 107, 105], "mcl_compass_compass_17.png": [115, 106, 104], "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], "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], "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_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_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], "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], "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_sapling_spruce.png": [55, 72, 53], "mcl_core_stripped_acacia_top.png": [149, 92, 58], "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], "default_water_source_animated.png": [37, 98, 129], "mcl_core_glass_yellow.png": [228, 228, 50], "default_acacia_sapling.png": [109, 92, 59], "mcl_core_stripped_acacia_side.png": [155, 96, 61], "mcl_core_sandstone_carved.png": [199, 152, 119], "mcl_core_glass_blue.png": [50, 75, 178], "mcl_core_red_sandstone_normal.png": [198, 120, 104], "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_papyrus.png": [82, 114, 57], "default_dry_grass.png": [100, 94, 54], "mcl_core_stripped_dark_oak_top.png": [91, 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": [163, 130, 104], "default_clay.png": [124, 124, 124], "mcl_core_stripped_jungle_side.png": [140, 98, 76], "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": [119, 94, 71], "mcl_core_glass_cyan.png": [75, 126, 153], "mcl_core_cactus_side.png": [88, 110, 56], "default_ladder.png": [83, 64, 50], "default_dry_grass_side.png": [91, 93, 52], "mcl_core_stripped_jungle_top.png": [143, 101, 78], "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_stripped_spruce_top.png": [111, 81, 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": [104, 78, 63], "default_coal_lump.png": [41, 39, 41], "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": [139, 108, 78], "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_stripped_dark_oak_side.png": [86, 73, 63], "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], "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": [157, 126, 102], "mcl_core_grass_path_top.png": [125, 101, 50], "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_chestplate_chain_preview.png": [124, 98, 90], "mcl_armor_inv_helmet_gold.png": [178, 134, 51], "mcl_armor_leggings_chain.png": [64, 66, 69], "mcl_armor_helmet_chain_preview.png": [154, 150, 143], "mcl_armor_chestplate_diamond_preview.png": [102, 140, 160], "mcl_armor_inv_boots_iron.png": [134, 129, 124], "mcl_armor_boots_gold_preview.png": [178, 133, 42], "mcl_armor_leggings_diamond_preview.png": [80, 118, 138], "mcl_armor_inv_chestplate_chain.png": [128, 105, 96], "mcl_armor_helmet_diamond_preview.png": [101, 134, 152], "mcl_armor_boots_leather_preview.png": [129, 119, 101], "mcl_armor_inv_chestplate_gold.png": [171, 128, 55], "mcl_armor_inv_helmet_diamond.png": [109, 130, 142], "mcl_armor_leggings_leather_preview.png": [141, 134, 114], "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_chestplate_iron_preview.png": [143, 134, 123], "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_leggings_gold_preview.png": [185, 156, 108], "mcl_armor_chestplate_gold.png": [157, 117, 55], "mcl_armor_inv_helmet_chain.png": [140, 137, 132], "mcl_armor_boots_chain_preview.png": [78, 78, 79], "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_leggings_iron_preview.png": [127, 122, 117], "mcl_armor_inv_boots_gold.png": [187, 142, 46], "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_gold_preview.png": [181, 138, 54], "mcl_armor_boots_iron_preview.png": [118, 113, 108], "mcl_armor_helmet_iron.png": [153, 149, 144], "mcl_armor_inv_boots_leather.png": [130, 121, 103], "mcl_armor_leggings_chain_preview.png": [54, 56, 61], "mcl_armor_helmet_iron_preview.png": [143, 138, 132], "mcl_armor_helmet_leather_preview.png": [119, 109, 91], "mcl_armor_chestplate_leather_preview.png": [144, 138, 118], "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_gold_preview.png": [169, 127, 56], "mcl_armor_chestplate_chain.png": [119, 98, 93], "mcl_armor_boots_gold.png": [160, 118, 42], "mcl_armor_boots_diamond_preview.png": [89, 141, 169], "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_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], "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], "3d_armor_stand_item.png": [134, 114, 98], "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], "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], "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], "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], "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], "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], "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], "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], "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], "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], "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_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_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_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_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_chest_bottom.png": [118, 91, 70], "default_chest_top.png": [88, 73, 61], "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_skeleton_preview.png": [128, 127, 127], "mcl_heads_steve_preview.png": [117, 83, 66], "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_zombie_preview.png": [66, 103, 68], "mcl_heads_creeper_preview.png": [88, 110, 65], "mcl_heads_wither_skeleton.png": [50, 50, 50], "mcl_heads_wither_skeleton_preview.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], "bucket_lava.png": [166, 127, 113], "bucket_river_water.png": [139, 152, 155], "bucket_water.png": [139, 147, 155], "bucket.png": [147, 143, 139], "mcl_anvils_anvil_top_damaged_1.png": [48, 48, 48], "mcl_anvils_anvil_top_damaged_2.png": [46, 46, 46], "mcl_anvils_anvil_top_damaged_0.png": [50, 50, 50], "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_map_filled.png": [213, 176, 148], "mcl_maps_map_empty.png": [217, 187, 157], "mcl_maps_map_filled_markings.png": [183, 183, 183], "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_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_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_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]} \ No newline at end of file +{"player.png": [123, 74, 62], "player_back.png": [114, 68, 56], "mcl_skins_player_dummy.png": [125, 125, 125], "mcl_skins_player_1.png": [103, 100, 86], "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": [98, 50, 98], "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": [50, 50, 249], "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_parrot_green.png": [47, 208, 62], "mobs_mc_llama_decor_magenta.png": [249, 50, 249], "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_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": [176, 171, 163], "mobs_mc_villager_priest.png": [100, 64, 74], "mobs_mc_villager_smith.png": [76, 76, 63], "mobs_mc_horse_armor_gold.png": [143, 110, 59], "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": [81, 80, 67], "mobs_mc_spawn_icon_horse_skeleton.png": [245, 204, 202], "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_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": [104, 168, 194], "mobs_mc_zombie_priest.png": [120, 104, 110], "mobs_mc_llama_decor_black.png": [50, 50, 50], "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": [98, 98, 98], "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_horse_armor_iron.png": [134, 123, 118], "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_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_trading_formspec_bg.png": [157, 157, 157], "mobs_mc_llama_chest.png": [70, 53, 36], "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": [50, 98, 50], "mobs_mc_cow.png": [94, 68, 55], "mobs_mc_llama_decor_brown.png": [101, 75, 60], "mobs_mc_villager_butcher.png": [82, 83, 71], "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], "mcl_totems_totem.png": [185, 139, 52], "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_horse_armor_diamond.png": [78, 110, 129], "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": [249, 249, 249], "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": [185, 185, 185], "mobs_mc_llama_decor_cyan.png": [18, 249, 249], "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_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": [50, 249, 50], "mobs_mc_llama_brown.png": [136, 97, 52], "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": [249, 50, 50], "mobs_mc_enderman.png": [3, 10, 10], "mobs_mc_mooshroom_brown.png": [93, 50, 28], "mobs_mc_llama_decor_pink.png": [249, 161, 175], "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_spit.png": [221, 218, 246], "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": [249, 249, 50], "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": [249, 131, 50], "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_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_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], "mobs_mc_gameconfig_enderman_cactus_background.png": [44, 71, 27], "mcl_paintings_paintings.png": [104, 99, 89], "mcl_paintings_painting.png": [139, 133, 119], "mcl_particles_lava.png": [250, 150, 64], "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_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_smoke.png": [174, 174, 174], "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], "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_experience_bottle.png": [136, 174, 169], "experience_bar_background.png": [49, 46, 45], "experience_orb.png": [93, 174, 0], "experience_bar.png": [74, 102, 70], "mcl_bossbars_empty.png": [255, 255, 255], "mcl_bossbars.png": [76, 68, 75], "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_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], "mcl_fireworks_rocket.png": [155, 84, 71], "mcl_bows_arrow_inv.png": [144, 129, 121], "mcl_bows_arrow_overlay.png": [193, 191, 186], "mcl_bows_bow_1.png": [112, 95, 79], "mcl_bows_bow_0.png": [111, 94, 79], "mcl_bows_bow_2.png": [115, 98, 82], "mcl_bows_bow.png": [114, 95, 78], "mcl_bows_arrow.png": [133, 116, 108], "mcl_bows_arrow_front.png": [178, 175, 168], "mcl_bows_arrow_back.png": [218, 216, 213], "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_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_chicken_raw.png": [217, 178, 149], "mcl_mobitems_ghast_tear.png": [148, 160, 166], "mcl_mobitems_porkchop_raw.png": [160, 72, 69], "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], "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_pumpkin_face_preview.png": [166, 81, 38], "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_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": [251, 251, 251], "mcl_end_end_rod_side.png": [242, 202, 177], "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], "mcl_compass_compass_02.png": [116, 107, 104], "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], "mcl_compass_compass_26.png": [117, 107, 104], "mcl_compass_compass_25.png": [117, 107, 105], "mcl_compass_compass_24.png": [117, 107, 105], "mcl_compass_compass_17.png": [115, 106, 104], "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], "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], "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_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_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], "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], "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_sapling_spruce.png": [55, 72, 53], "mcl_core_stripped_acacia_top.png": [149, 92, 58], "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], "default_water_source_animated.png": [37, 98, 129], "mcl_core_glass_yellow.png": [228, 228, 50], "default_acacia_sapling.png": [109, 92, 59], "mcl_core_stripped_acacia_side.png": [155, 96, 61], "mcl_core_sandstone_carved.png": [199, 152, 119], "mcl_core_glass_blue.png": [50, 75, 178], "mcl_core_red_sandstone_normal.png": [198, 120, 104], "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], "mcl_core_papyrus.png": [82, 114, 57], "default_dry_grass.png": [100, 94, 54], "mcl_core_stripped_dark_oak_top.png": [91, 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": [163, 130, 104], "default_clay.png": [124, 124, 124], "mcl_core_stripped_jungle_side.png": [140, 98, 76], "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": [119, 94, 71], "mcl_core_glass_cyan.png": [75, 126, 153], "mcl_core_cactus_side.png": [88, 110, 56], "default_ladder.png": [83, 64, 50], "default_dry_grass_side.png": [91, 93, 52], "mcl_core_stripped_jungle_top.png": [143, 101, 78], "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_stripped_spruce_top.png": [111, 81, 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": [104, 78, 63], "default_coal_lump.png": [41, 39, 41], "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": [139, 108, 78], "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_stripped_dark_oak_side.png": [86, 73, 63], "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], "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": [157, 126, 102], "mcl_core_grass_path_top.png": [125, 101, 50], "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_chestplate_chain_preview.png": [124, 98, 90], "mcl_armor_inv_helmet_gold.png": [178, 134, 51], "mcl_armor_leggings_chain.png": [64, 66, 69], "mcl_armor_helmet_chain_preview.png": [154, 150, 143], "mcl_armor_chestplate_diamond_preview.png": [102, 140, 160], "mcl_armor_inv_boots_iron.png": [134, 129, 124], "mcl_armor_boots_gold_preview.png": [178, 133, 42], "mcl_armor_leggings_diamond_preview.png": [80, 118, 138], "mcl_armor_inv_chestplate_chain.png": [128, 105, 96], "mcl_armor_helmet_diamond_preview.png": [101, 134, 152], "mcl_armor_boots_leather_preview.png": [129, 119, 101], "mcl_armor_inv_chestplate_gold.png": [171, 128, 55], "mcl_armor_inv_helmet_diamond.png": [109, 130, 142], "mcl_armor_leggings_leather_preview.png": [141, 134, 114], "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_chestplate_iron_preview.png": [143, 134, 123], "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_leggings_gold_preview.png": [185, 156, 108], "mcl_armor_chestplate_gold.png": [157, 117, 55], "mcl_armor_inv_helmet_chain.png": [140, 137, 132], "mcl_armor_boots_chain_preview.png": [78, 78, 79], "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_leggings_iron_preview.png": [127, 122, 117], "mcl_armor_inv_boots_gold.png": [187, 142, 46], "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_gold_preview.png": [181, 138, 54], "mcl_armor_boots_iron_preview.png": [118, 113, 108], "mcl_armor_helmet_iron.png": [153, 149, 144], "mcl_armor_inv_boots_leather.png": [130, 121, 103], "mcl_armor_leggings_chain_preview.png": [54, 56, 61], "mcl_armor_helmet_iron_preview.png": [143, 138, 132], "mcl_armor_helmet_leather_preview.png": [119, 109, 91], "mcl_armor_chestplate_leather_preview.png": [144, 138, 118], "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_gold_preview.png": [169, 127, 56], "mcl_armor_chestplate_chain.png": [119, 98, 93], "mcl_armor_boots_gold.png": [160, 118, 42], "mcl_armor_boots_diamond_preview.png": [89, 141, 169], "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_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], "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], "3d_armor_stand_item.png": [134, 114, 98], "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], "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], "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], "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], "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], "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], "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], "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], "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], "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], "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_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_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_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_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_chest_bottom.png": [118, 91, 70], "default_chest_top.png": [88, 73, 61], "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_skeleton_preview.png": [128, 127, 127], "mcl_heads_steve_preview.png": [117, 83, 66], "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_zombie_preview.png": [66, 103, 68], "mcl_heads_creeper_preview.png": [88, 110, 65], "mcl_heads_wither_skeleton.png": [50, 50, 50], "mcl_heads_wither_skeleton_preview.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], "bucket_lava.png": [166, 127, 113], "bucket_river_water.png": [139, 152, 155], "bucket_water.png": [139, 147, 155], "bucket.png": [147, 143, 139], "mcl_anvils_anvil_top_damaged_1.png": [48, 48, 48], "mcl_anvils_anvil_top_damaged_2.png": [46, 46, 46], "mcl_anvils_anvil_top_damaged_0.png": [50, 50, 50], "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_map_filled.png": [213, 176, 148], "mcl_maps_map_empty.png": [217, 187, 157], "mcl_maps_map_filled_markings.png": [183, 183, 183], "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_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_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_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 ccdaf6dfd..450d8fbad 100644 --- a/mods/ITEMS/mcl_maps/init.lua +++ b/mods/ITEMS/mcl_maps/init.lua @@ -1,8 +1,21 @@ mcl_maps = {} -local S = minetest.get_translator("mcl_maps") +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 modpath = minetest.get_modpath("mcl_maps") local worldpath = minetest.get_worldpath() local map_textures_path = worldpath .. "/mcl_maps/" --local last_finished_id = storage:get_int("next_id") - 1 @@ -36,8 +49,8 @@ function mcl_maps.create_map(pos) 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", minetest.pos_to_string(minp)) - meta:set_string("mcl_maps:maxp", minetest.pos_to_string(maxp)) + 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 @@ -134,11 +147,23 @@ function mcl_maps.load_map(id) local texture = "mcl_maps_map_texture_" .. id .. ".tga" if not loaded_maps[id] then - loaded_maps[id] = true - minetest.dynamic_add_media(map_textures_path .. texture, function() end) + 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 + dynamic_add_media(map_textures_path .. texture, function() end) + else + -- minetest.dynamic_add_media() never blocks + -- in Minetest 5.5, callback runs after load + dynamic_add_media(map_textures_path .. texture, function() + loaded_maps[id] = true + end) + end end - return texture + if loaded_maps[id] then + return texture + end end function mcl_maps.load_map_item(itemstack) @@ -216,14 +241,14 @@ end local old_add_item = minetest.add_item function minetest.add_item(pos, stack) stack = ItemStack(stack) - if minetest.get_item_group(stack:get_name(), "filled_map") > 0 then + 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 minetest.get_item_group(itemstring, "filled_map") > 0 then + 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 @@ -249,7 +274,7 @@ minetest.register_craft({ 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 minetest.get_item_group(stack:get_name(), "filled_map") > 0 then + if get_item_group(stack:get_name(), "filled_map") > 0 then itemstack:get_meta():from_table(stack:get_meta():to_table()) return itemstack end @@ -286,7 +311,7 @@ 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 wield = player:get_wielded_item() local texture = mcl_maps.load_map_item(wield) local hud = huds[player] @@ -306,8 +331,8 @@ minetest.register_globalstep(function(dtime) local pos = vector.round(player:get_pos()) local meta = wield:get_meta() - local minp = minetest.string_to_pos(meta:get_string("mcl_maps:minp")) - local maxp = minetest.string_to_pos(meta:get_string("mcl_maps:maxp")) + 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" diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr index 9ef7cd5c5..1808e839d 100644 --- a/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr @@ -1,5 +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 +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.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.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_mobitems/init.lua b/mods/ITEMS/mcl_mobitems/init.lua index 1b7929722..a7b04d3d4 100644 --- a/mods/ITEMS/mcl_mobitems/init.lua +++ b/mods/ITEMS/mcl_mobitems/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_mobitems") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_craftitem("mcl_mobitems:rotten_flesh", { description = S("Rotten Flesh"), @@ -135,7 +135,7 @@ minetest.register_craftitem("mcl_mobitems:cooked_rabbit", { }) -- Reset food poisoning and status effects -local drink_milk = function(itemstack, player, pointed_thing) +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 @@ -426,7 +426,7 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'mcl_mobitems:slimeball 9', + output = "mcl_mobitems:slimeball 9", recipe = {{"mcl_core:slimeblock"}}, }) diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr index eee31278b..d31632345 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr @@ -27,7 +27,7 @@ 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 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..dd78a692f --- /dev/null +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr @@ -0,0 +1,96 @@ +# 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. + +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_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index bd9d0c53a..0795fb611 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_mobspawners") +local S = minetest.get_translator(minetest.get_current_modname()) local math = math local table = table @@ -22,7 +22,7 @@ end local function find_doll(pos) 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 @@ -136,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) @@ -317,7 +317,7 @@ minetest.register_node("mcl_mobspawners:spawner", { if obj then obj:remove() end - mcl_experience.throw_experience(pos, math.random(15, 43)) + mcl_experience.throw_xp(pos, math.random(15, 43)) end, on_punch = function(pos) @@ -387,4 +387,3 @@ minetest.register_lbm({ respawn_doll(pos) end, }) - 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_monster_eggs/init.lua b/mods/ITEMS/mcl_monster_eggs/init.lua index dd986d127..59ab72876 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,7 +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 = '', + 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.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_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.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/small.lua b/mods/ITEMS/mcl_mushrooms/small.lua index 52c64928f..f6fbd2909 100644 --- a/mods/ITEMS/mcl_mushrooms/small.lua +++ b/mods/ITEMS/mcl_mushrooms/small.lua @@ -1,4 +1,4 @@ -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}) @@ -38,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 = { @@ -62,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", @@ -87,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_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 0a0e2b183..b474065a5 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -1,6 +1,6 @@ -local S = minetest.get_translator("mcl_nether") +local S = minetest.get_translator(minetest.get_current_modname()) -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 @@ -16,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", @@ -43,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, @@ -53,13 +53,14 @@ minetest.register_node("mcl_nether:quartz_ore", { -- 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) @@ -105,7 +106,8 @@ minetest.register_node("mcl_nether:magma", { sounds = mcl_sounds.node_sound_stone_defaults(), -- From walkover mod on_walk_over = function(loc, nodeiamon, player) - if player and player:get_player_control().sneak or 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 @@ -172,7 +174,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, hoey=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1, compostability = 85}, sounds = mcl_sounds.node_sound_leaves_defaults( { footstep={name="default_dirt_footstep", gain=0.7}, @@ -265,34 +267,34 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'mcl_nether:quartz_block', + 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"}, } }) @@ -306,32 +308,32 @@ 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"}, } }) 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/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_ocean/corals.lua b/mods/ITEMS/mcl_ocean/corals.lua index 376b8a22f..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") }, diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index fb6045e78..ae273abe9 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -7,8 +7,8 @@ -- 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. -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-ify runtime functions @@ -741,7 +741,7 @@ minetest.register_craftitem("mcl_ocean:kelp", { inventory_image = "mcl_ocean_kelp_item.png", wield_image = "mcl_ocean_kelp_item.png", on_place = kelp.kelp_on_place, - groups = { deco_block = 1 }, + groups = {deco_block = 1, compostability = 30}, }) if mod_doc then @@ -756,14 +756,14 @@ 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), _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 @@ -773,7 +773,10 @@ 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, hoey = 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, 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/prismarine.lua b/mods/ITEMS/mcl_ocean/prismarine.lua index 647e87fe1..e38b3e0a6 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}}}, @@ -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 067bb39a3..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 @@ -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 bd6400a32..2f58a2812 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 = { @@ -84,7 +85,7 @@ minetest.register_craftitem("mcl_ocean:seagrass", { inventory_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", wield_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", on_place = seagrass_on_place, - groups = { deco_block = 1 }, + groups = {deco_block = 1, compostability = 30}, }) -- Seagrass nodes: seagrass on a surface node diff --git a/mods/ITEMS/mcl_portals/init.lua b/mods/ITEMS/mcl_portals/init.lua index 080051ffa..972e93473 100644 --- a/mods/ITEMS/mcl_portals/init.lua +++ b/mods/ITEMS/mcl_portals/init.lua @@ -4,13 +4,15 @@ 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(minetest.get_modpath("mcl_portals").."/portal_gateway.lua") +dofile(modpath.."/portal_gateway.lua") 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 d99344a76..610b590c6 100644 --- a/mods/ITEMS/mcl_portals/mod.conf +++ b/mods/ITEMS/mcl_portals/mod.conf @@ -1,4 +1,4 @@ name = mcl_portals description = Adds buildable portals to the Nether and End dimensions. -depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn +depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn, mcl_credits optional_depends = awards, doc diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 5b402bdc0..e4982c39b 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -1,16 +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 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 }, @@ -307,7 +309,7 @@ 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", @@ -339,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 @@ -366,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( @@ -381,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 @@ -389,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 index c738da1a4..ca15a61d5 100644 --- a/mods/ITEMS/mcl_portals/portal_gateway.lua +++ b/mods/ITEMS/mcl_portals/portal_gateway.lua @@ -1,6 +1,8 @@ -local S = minetest.get_translator("mcl_portals") +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}, @@ -24,9 +26,10 @@ local gateway_positions = { {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) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_gateway_portal.mts" - return mcl_structures.place_schematic(vector.add(pos, vector.new(-1, -2, -1)), path, "0", nil, true, nil, dest_str and function() + 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 diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index ec8e40d22..0d93e11d1 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_portals") +local S = minetest.get_translator(minetest.get_current_modname()) local SCAN_2_MAP_CHUNKS = true -- slower but helps to find more suitable places @@ -204,37 +204,57 @@ local function get_target(p) end end --- Destroy portal if pos (portal frame or portal node) got destroyed +-- 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 not node then return end - local nn, orientation = node.name, node.param2 - local obsidian = nn == OBSIDIAN - - local check_remove = function(pos, orientation) - local node = get_node(pos) - if node and (node.name == PORTAL and (orientation == nil or (node.param2 == orientation))) then - minetest.remove_node(pos) - remove_exit(pos) - 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}) + if destroying_portal then 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) + 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 - check_remove({x = pos.x, y = pos.y - 1, z = pos.z}) - check_remove({x = pos.x, y = pos.y + 1, z = pos.z}) + + 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, { @@ -286,6 +306,7 @@ minetest.register_node(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, @@ -811,7 +832,23 @@ local usagehelp = S("To open a Nether portal, place an upright frame of obsidian minetest.override_item(OBSIDIAN, { _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - after_destruct = 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: diff --git a/mods/ITEMS/mcl_potions/commands.lua b/mods/ITEMS/mcl_potions/commands.lua index ad1d65b7f..1fbf591d9 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()) -- ░█████╗░██╗░░██╗░█████╗░████████╗  ░█████╗░░█████╗░███╗░░░███╗███╗░░░███╗░█████╗░███╗░░██╗██████╗░░██████╗ -- ██╔══██╗██║░░██║██╔══██╗╚══██╔══╝  ██╔══██╗██╔══██╗████╗░████║████╗░████║██╔══██╗████╗░██║██╔══██╗██╔════╝ diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index 09b95115a..c3b034b66 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -35,13 +35,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 = 3, y = 3 }, alignment = { x = 1, y = 1 }, z_index = 100, }) diff --git a/mods/ITEMS/mcl_potions/init.lua b/mods/ITEMS/mcl_potions/init.lua index 6cfa0dc50..36f45b01a 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") @@ -143,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 @@ -271,7 +272,7 @@ minetest.register_craftitem("mcl_potions:river_water", { }) -- Hurt mobs -local water_splash = function(obj, damage) +local function water_splash(obj, damage) if not obj then return end @@ -314,9 +315,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"}, } }) @@ -428,21 +429,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 diff --git a/mods/ITEMS/mcl_potions/lingering.lua b/mods/ITEMS/mcl_potions/lingering.lua index f4f0e249d..64f846cb6 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) @@ -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_item_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.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/potions.lua b/mods/ITEMS/mcl_potions/potions.lua index b9c2aad24..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 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 diff --git a/mods/ITEMS/mcl_potions/splash.lua b/mods/ITEMS/mcl_potions/splash.lua index f986134d6..4a820e467 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 @@ -67,6 +68,9 @@ function mcl_potions.register_splash(name, descr, color, def) 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 diff --git a/mods/ITEMS/mcl_potions/tipped_arrow.lua b/mods/ITEMS/mcl_potions/tipped_arrow.lua index abeae8106..880dff956 100644 --- a/mods/ITEMS/mcl_potions/tipped_arrow.lua +++ b/mods/ITEMS/mcl_potions/tipped_arrow.lua @@ -1,4 +1,9 @@ -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 @@ -8,7 +13,7 @@ local STUCK_RECHECK_TIME = 5 local YAW_OFFSET = -math.pi/2 -local dir_to_pitch = function(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) @@ -18,12 +23,7 @@ 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 @@ -102,7 +102,7 @@ function mcl_potions.register_arrow(name, desc, color, def) physical = true, visual = "mesh", mesh = "mcl_bows_arrow.obj", - visual_size = {x=1, y=1}, + 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, @@ -121,7 +121,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}) @@ -130,7 +130,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) @@ -215,7 +215,7 @@ function mcl_potions.register_arrow(name, desc, color, def) -- Arrows can only damage players and mobs if obj ~= self._shooter and obj:is_player() then ok = true - elseif obj:get_luaentity() ~= nil then + elseif obj:get_luaentity() then if obj ~= self._shooter and obj:get_luaentity()._cmi_is_mob then ok = true end @@ -234,7 +234,7 @@ function mcl_potions.register_arrow(name, desc, color, def) 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() @@ -344,6 +344,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) @@ -386,13 +391,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, @@ -413,7 +418,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 @@ -451,20 +456,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_shields/init.lua b/mods/ITEMS/mcl_shields/init.lua new file mode 100644 index 000000000..a1be310e7 --- /dev/null +++ b/mods/ITEMS/mcl_shields/init.lua @@ -0,0 +1,515 @@ +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, + no_wieldview = 1, + offhand_item = 1, + }, + sound = {breaks = "default_tool_breaks"}, + _repair_material = "group:wood", + wield_scale = vector.new(2, 2, 2), +}) + +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"}) + 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 shield_hud[player] then + player:hud_remove(shield_hud[player]) + shield_hud[player] = nil + set_shield(player, false, 1) + set_shield(player, false, 2) + end + + 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 offhand_can_block = (wielded_item(player) == "" or not mcl_util.get_pointed_thing(player, true)) + and (minetest.get_item_group(wielded_item(player), "bow") ~= 1 and minetest.get_item_group(wielded_item(player), "crossbow") ~= 1) + + 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, + no_wieldview = 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], + }) + + 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/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_shields/textures/mcl_shield.png b/mods/ITEMS/mcl_shields/textures/mcl_shield.png new file mode 100644 index 000000000..7391636e9 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_base_nopattern.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_base_nopattern.png new file mode 100644 index 000000000..8146632bb Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_base_nopattern.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_hud.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_hud.png new file mode 100644 index 000000000..4286d3e83 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_hud.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_item_overlay.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_item_overlay.png new file mode 100644 index 000000000..3e7953609 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_item_overlay.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_base.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_base.png new file mode 100644 index 000000000..268445b36 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_base.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_border.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_border.png new file mode 100644 index 000000000..e128218e6 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_border.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_bricks.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_bricks.png new file mode 100644 index 000000000..f1ddd716b Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_bricks.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_circle.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_circle.png new file mode 100644 index 000000000..8ff66b8c8 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_circle.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_creeper.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_creeper.png new file mode 100644 index 000000000..5b30dc76b Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_creeper.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_cross.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_cross.png new file mode 100644 index 000000000..40a6624ae Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_cross.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_curly_border.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_curly_border.png new file mode 100644 index 000000000..9f8c21773 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_curly_border.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_left.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_left.png new file mode 100644 index 000000000..a04a6fdc0 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_left.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_right.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_right.png new file mode 100644 index 000000000..309f711bf Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_right.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_up_left.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_up_left.png new file mode 100644 index 000000000..c5f4399a0 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_up_left.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_up_right.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_up_right.png new file mode 100644 index 000000000..59dd957dd Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_diagonal_up_right.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_flower.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_flower.png new file mode 100644 index 000000000..fe7ca826f Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_flower.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_gradient.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_gradient.png new file mode 100644 index 000000000..29a98c704 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_gradient.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_gradient_up.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_gradient_up.png new file mode 100644 index 000000000..09effb26a Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_gradient_up.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_horizontal.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_horizontal.png new file mode 100644 index 000000000..5187803b3 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_horizontal.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_horizontal_bottom.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_horizontal_bottom.png new file mode 100644 index 000000000..515e6ddfe Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_horizontal_bottom.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_vertical.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_vertical.png new file mode 100644 index 000000000..9a56804da Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_vertical.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_vertical_right.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_vertical_right.png new file mode 100644 index 000000000..4a5af61fb Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_half_vertical_right.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_rhombus.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_rhombus.png new file mode 100644 index 000000000..13b502289 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_rhombus.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_skull.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_skull.png new file mode 100644 index 000000000..4e0c7c1f5 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_skull.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_small_stripes.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_small_stripes.png new file mode 100644 index 000000000..f125ba2fb Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_small_stripes.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_bottom_left.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_bottom_left.png new file mode 100644 index 000000000..a5c4e00c0 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_bottom_left.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_bottom_right.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_bottom_right.png new file mode 100644 index 000000000..ca2c53692 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_bottom_right.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_top_left.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_top_left.png new file mode 100644 index 000000000..2123cba15 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_top_left.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_top_right.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_top_right.png new file mode 100644 index 000000000..3f7a759a8 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_square_top_right.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_straight_cross.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_straight_cross.png new file mode 100644 index 000000000..dc861f048 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_straight_cross.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_bottom.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_bottom.png new file mode 100644 index 000000000..859ad11d1 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_bottom.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_center.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_center.png new file mode 100644 index 000000000..8d1e2404c Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_center.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_downleft.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_downleft.png new file mode 100644 index 000000000..c0a93cd4f Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_downleft.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_downright.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_downright.png new file mode 100644 index 000000000..09580857c Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_downright.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_left.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_left.png new file mode 100644 index 000000000..6e5bcb02e Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_left.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_middle.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_middle.png new file mode 100644 index 000000000..af5ebc12a Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_middle.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_right.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_right.png new file mode 100644 index 000000000..dcb911b68 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_right.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_top.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_top.png new file mode 100644 index 000000000..a1e10be46 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_stripe_top.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_thing.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_thing.png new file mode 100644 index 000000000..43b2a1d49 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_thing.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangle_bottom.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangle_bottom.png new file mode 100644 index 000000000..87d1aa95b Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangle_bottom.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangle_top.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangle_top.png new file mode 100644 index 000000000..94d652878 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangle_top.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangles_bottom.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangles_bottom.png new file mode 100644 index 000000000..3e4851abb Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangles_bottom.png differ diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangles_top.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangles_top.png new file mode 100644 index 000000000..0ae85d6d1 Binary files /dev/null and b/mods/ITEMS/mcl_shields/textures/mcl_shield_pattern_triangles_top.png differ diff --git a/mods/ITEMS/mcl_signs/init.lua b/mods/ITEMS/mcl_signs/init.lua index be9db2fee..b6bfb3fe8 100644 --- a/mods/ITEMS/mcl_signs/init.lua +++ b/mods/ITEMS/mcl_signs/init.lua @@ -1,6 +1,10 @@ -local S = minetest.get_translator("mcl_signs") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) local F = minetest.formspec_escape +local table = table + -- 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: @@ -13,7 +17,7 @@ After line 3, another info block may follow. This repeats until the end of the f 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") +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 @@ -46,7 +50,7 @@ local function round(num, idp) return math.floor(num * mult + 0.5) / mult end -local string_to_array = function(str) +local function string_to_array(str) local tab = {} for i=1,string.len(str) do table.insert(tab, string.sub(str, i,i)) @@ -54,7 +58,7 @@ local string_to_array = function(str) return tab end -local string_to_line_array = function(str) +local function string_to_line_array(str) local tab = {} local current = 1 local linechar = 1 @@ -73,7 +77,7 @@ local string_to_line_array = function(str) return tab end -local create_lines = function(text) +local function create_lines(text) local line_num = 1 local tab = {} for _, line in ipairs(string_to_line_array(text)) do @@ -86,7 +90,7 @@ local create_lines = function(text) return tab end -local generate_line = function(s, ypos) +local function generate_line(s, ypos) local i = 1 local parsed = {} local width = 0 @@ -95,10 +99,10 @@ local generate_line = function(s, ypos) while chars < LINE_LENGTH and i <= #s do local file -- Get and render character - if charmap[s:sub(i, i)] ~= nil then + 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)] ~= nil then + elseif i < #s and charmap[s:sub(i, i + 1)] then file = charmap[s:sub(i, i + 1)] i = i + 2 else @@ -108,7 +112,7 @@ local generate_line = function(s, ypos) i = i + 1 minetest.log("verbose", "[mcl_signs] Unknown symbol in '"..s.."' at "..i) end - if file ~= nil then + if file then width = width + printed_char_width table.insert(parsed, file) chars = chars + 1 @@ -125,7 +129,7 @@ local generate_line = function(s, ypos) return texture end -local generate_texture = function(lines, signnodename) +local function generate_texture(lines, signnodename) local texture = "[combine:"..SIGN_WIDTH.."x"..SIGN_WIDTH local ypos if signnodename == "mcl_signs:wall_sign" then @@ -152,6 +156,7 @@ local signtext_info_wall = { 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) @@ -187,7 +192,7 @@ end local sign_groups = {handy=1,axey=1, deco_block=1, material_wood=1, attached_node=1, dig_by_piston=1, flammable=-1} -local destruct_sign = function(pos) +local function destruct_sign(pos) local objects = minetest.get_objects_inside_radius(pos, 0.5) for _, v in ipairs(objects) do local ent = v:get_luaentity() @@ -203,7 +208,7 @@ local destruct_sign = function(pos) end end -local update_sign = function(pos, fields, sender, force_remove) +local function update_sign(pos, fields, sender, force_remove) local meta = minetest.get_meta(pos) if not meta then return @@ -256,7 +261,7 @@ local update_sign = function(pos, fields, sender, force_remove) text_entity:set_yaw(sign_info.yaw) end -local show_formspec = function(player, pos) +local function show_formspec(player, pos) minetest.show_formspec( player:get_player_name(), "mcl_signs:set_text_"..pos.x.."_"..pos.y.."_"..pos.z, @@ -518,7 +523,7 @@ minetest.register_entity("mcl_signs:text", { _signnodename = nil, -- node name of sign node to which the text belongs on_activate = function(self, staticdata) - if staticdata ~= nil and staticdata ~= "" then + if staticdata and staticdata ~= "" then local des = minetest.deserialize(staticdata) if des then self._signnodename = des._signnodename @@ -545,11 +550,11 @@ minetest.register_craft({ if minetest.get_modpath("mcl_core") then minetest.register_craft({ - output = 'mcl_signs:wall_sign 3', + output = "mcl_signs:wall_sign 3", recipe = { - {'group:wood', 'group:wood', 'group:wood'}, - {'group:wood', 'group:wood', 'group:wood'}, - {'', 'mcl_core:stick', ''}, + {"group:wood", "group:wood", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + {"", "mcl_core:stick", ""}, } }) end 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..bf3bbf3c8 --- /dev/null +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.pl.tr @@ -0,0 +1,9 @@ +# 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.=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. +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ć 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..62994bc3d --- /dev/null +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.zh_TW.tr @@ -0,0 +1,9 @@ +# 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個字符;超過這些限制的文字就會丟失。不是所有的字符都被支持。文字一旦寫完就不能更改;你必須打破並重新放置標誌。 +Enter sign text:=輸入告示牌文字: +Maximum line length: 15=每行最多可以寫15個字符 +Maximum lines: 4=最多可以寫4行文字 +Done=確認 +Can be written=可以寫字 diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index 147db6cc5..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 @@ -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 @@ -115,16 +115,22 @@ function place_wet_sponge(itemstack, placer, pointed_thing) 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 = 0, 25 do - minetest.add_particle({ - pos = {x = pos.x + math.random(-1, 1)*math.random()/2, y = pos.y + 0.6, z = pos.z + math.random(-1, 1)*math.random()/2}, - velocity = {x = 0, y = math.random(), z = 0}, - acceleration = {x=0, y=0, z=0}, - expirationtime = math.random(), + + 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, - size = math.random(2, 5), - texture = "mcl_particles_sponge"..math.random(1, 5)..".png", + texture = "mcl_particles_sponge" .. n .. ".png", }) end if not minetest.is_creative_enabled(name) then 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_stairs/api.lua b/mods/ITEMS/mcl_stairs/api.lua index cca54226f..34afb018e 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 @@ -155,7 +155,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 +165,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}, @@ -297,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 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/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..4892122f6 100644 --- a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.fr.tr +++ b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.fr.tr @@ -30,9 +30,9 @@ 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 +Granite Stairs=Escalier en Granit +Granite Slab=Dalle en Granit +Double Granite Slab=Double Dalle en Granit Diorite Stairs=Escalier en Diorite Diorite Slab=Dalle en Diorite Double Diorite Slab=Double Dalle en Diorite 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/register.lua b/mods/ITEMS/mcl_stairs/register.lua index 565f5409b..5de380585 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") }, diff --git a/mods/ITEMS/mcl_throwing/init.lua b/mods/ITEMS/mcl_throwing/init.lua index 2d57744d0..c468946dd 100644 --- a/mods/ITEMS/mcl_throwing/init.lua +++ b/mods/ITEMS/mcl_throwing/init.lua @@ -37,7 +37,7 @@ end -- Throw item function mcl_throwing.get_player_throw_function(entity_name, velocity) - local func = function(item, player, pointed_thing) + local function func(item, player, pointed_thing) local playerpos = player:get_pos() local dir = player:get_look_dir() mcl_throwing.throw(item, {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, velocity, player:get_player_name()) 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 60d3e31a7..18248e76f 100644 --- a/mods/ITEMS/mcl_throwing/mod.conf +++ b/mods/ITEMS/mcl_throwing/mod.conf @@ -1,3 +1,3 @@ name = mcl_throwing depends = mcl_colors -optional_depends = mcl_core, mcl_mobitems, doc +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 index c2af9717f..8683eea0a 100644 --- a/mods/ITEMS/mcl_throwing/register.lua +++ b/mods/ITEMS/mcl_throwing/register.lua @@ -1,5 +1,10 @@ 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, @@ -15,6 +20,7 @@ local snowball_ENTITY={ _lastpos={}, } + local egg_ENTITY={ physical = false, timer=0, @@ -29,6 +35,7 @@ local egg_ENTITY={ _lastpos={}, } + -- Ender pearl entity local pearl_ENTITY={ physical = false, @@ -45,7 +52,7 @@ local pearl_ENTITY={ _thrower = nil, -- Player ObjectRef of the player who threw the ender pearl } -local check_object_hit = function(self, pos, dmg) +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() @@ -70,7 +77,7 @@ local check_object_hit = function(self, pos, dmg) return false end -local snowball_particles = function(pos, vel) +local function snowball_particles(pos, vel) local vel = vector.normalize(vector.multiply(vel, -1)) minetest.add_particlespawner({ amount = 20, @@ -93,50 +100,50 @@ local snowball_particles = function(pos, vel) end -- Snowball on_step()--> called when snowball is moving. -local snowball_on_step = function(self, dtime) - self.timer=self.timer+dtime +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 egg_on_step = function(self, dtime) - self.timer=self.timer+dtime +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~=nil then + 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) -- Turn given object into a child - local make_child= function(object) + local function make_child(object) local ent = object:get_luaentity() object:set_properties({ visual_size = { x = ent.base_size.x/2, y = ent.base_size.y/2 }, @@ -170,6 +177,9 @@ local egg_on_step = function(self, dtime) 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 @@ -185,8 +195,8 @@ local egg_on_step = function(self, dtime) end -- Movement function of ender pearl -local pearl_on_step = function(self, dtime) - self.timer=self.timer+dtime +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) @@ -274,6 +284,9 @@ local pearl_on_step = function(self, dtime) 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 diff --git a/mods/ITEMS/mcl_tnt/init.lua b/mods/ITEMS/mcl_tnt/init.lua index 40455f8d0..bf7b52385 100644 --- a/mods/ITEMS/mcl_tnt/init.lua +++ b/mods/ITEMS/mcl_tnt/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_tnt") +local S = minetest.get_translator(minetest.get_current_modname()) local tnt_griefing = minetest.settings:get_bool("mcl_tnt_griefing", true) local function spawn_tnt(pos, entname) @@ -9,7 +9,8 @@ local function spawn_tnt(pos, entname) end tnt = {} -tnt.ignite = function(pos) + +function tnt.ignite(pos) minetest.remove_node(pos) local e = spawn_tnt(pos, "mcl_tnt:tnt") minetest.check_for_falling(pos) @@ -18,7 +19,7 @@ end -- Add smoke particle of entity at pos. -- Intended to be called every step -tnt.smoke_step = function(pos) +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), @@ -189,9 +190,9 @@ 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.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_tools/crafting.lua b/mods/ITEMS/mcl_tools/crafting.lua index 00d378d7c..636cb6660 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', ''}, + {"mcl_core:cobble", "mcl_core:cobble", "mcl_core: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'}, + {"mcl_core: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'}, + {"mcl_core:cobble", "mcl_core:cobble"}, + {"mcl_core: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', ''}, + {"mcl_core:cobble", "mcl_core:cobble"}, + {"mcl_core:stick", "mcl_core: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'}, + {"mcl_core:cobble"}, + {"mcl_core: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/init.lua b/mods/ITEMS/mcl_tools/init.lua index 809a49279..1d68a0973 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 @@ -175,7 +177,7 @@ minetest.register_tool("mcl_tools:pick_diamond", { }, }) -local make_grass_path = function(itemstack, placer, pointed_thing) +local function make_grass_path(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 @@ -213,7 +215,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 @@ -352,7 +354,7 @@ minetest.register_tool("mcl_tools:shovel_diamond", { }) -- Axes -local make_stripped_trunk = function(itemstack, placer, pointed_thing) +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) @@ -366,10 +368,10 @@ local make_stripped_trunk = function(itemstack, placer, pointed_thing) return itemstack end - if noddef._mcl_stripped_varient == nil then + if noddef._mcl_stripped_variant == nil then return itemstack else - minetest.swap_node(pointed_thing.under, {name=noddef._mcl_stripped_varient, param2=node.param2}) + minetest.swap_node(pointed_thing.under, {name=noddef._mcl_stripped_variant, param2=node.param2}) if not minetest.is_creative_enabled(placer:get_player_name()) then -- Add wear (as if digging a axey node) local toolname = itemstack:get_name() @@ -610,5 +612,5 @@ minetest.register_tool("mcl_tools:shears", { }) -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.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_torches/api.lua b/mods/ITEMS/mcl_torches/api.lua index c98bda3d9..dab508795 100644 --- a/mods/ITEMS/mcl_torches/api.lua +++ b/mods/ITEMS/mcl_torches/api.lua @@ -9,7 +9,7 @@ local smoke_pdef = { maxrelpos = { x = 1/16, y = 0.06, z = 1/16 }, } -local spawn_flames_floor = function(pos) +local function spawn_flames_floor(pos) -- Flames mcl_particles.add_node_particlespawner(pos, { amount = 8, @@ -29,7 +29,7 @@ local spawn_flames_floor = function(pos) mcl_particles.spawn_smoke(pos, "torch", smoke_pdef) end -local spawn_flames_wall = function(pos) +local function spawn_flames_wall(pos) --local minrelpos, maxrelpos local node = minetest.get_node(pos) local dir = minetest.wallmounted_to_dir(node.param2) @@ -72,7 +72,7 @@ local spawn_flames_wall = function(pos) mcl_particles.spawn_smoke(pos, "torch", smoke_pdef) end -local remove_flames = function(pos) +local function remove_flames(pos) mcl_particles.delete_node_particlespawners(pos) end diff --git a/mods/ITEMS/mcl_torches/init.lua b/mods/ITEMS/mcl_torches/init.lua index 1102731c1..6b6ebcae9 100644 --- a/mods/ITEMS/mcl_torches/init.lua +++ b/mods/ITEMS/mcl_torches/init.lua @@ -1,6 +1,6 @@ mcl_torches = {} -local modpath = minetest.get_modpath("mcl_torches") +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.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/register.lua b/mods/ITEMS/mcl_torches/register.lua index 4218889d9..f8c34e6b5 100644 --- a/mods/ITEMS/mcl_torches/register.lua +++ b/mods/ITEMS/mcl_torches/register.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_torches") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_torches.register_torch({ name = "torch", diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index 499d7362d..7a45ea58f 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -4,17 +4,27 @@ minetest.register_on_leaveplayer(function(player) hud_totem[player] = nil end) +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() 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() == "mobs_mc: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() == "mobs_mc:totem" then local ppos = obj: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 + for n = 1, #mobs_mc.misc.totem_fail_nodes do if pnname == mobs_mc.misc.totem_fail_nodes[n] then return end @@ -26,20 +36,50 @@ mcl_damage.register_modifier(function(obj, damage, reason) if not minetest.is_creative_enabled(obj:get_player_name()) then wield:take_item() - obj:set_wielded_item(wield) + 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 -- Effects - minetest.sound_play({name = "mcl_totems_totem", gain=1}, {pos=ppos, max_hear_distance=16}, true) + 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 }, + position = {x = 0.5, y = 1}, + scale = {x = 17, y = 17}, + offset = {x = 0, y = -178}, z_index = 100, }) minetest.after(3, function() diff --git a/mods/ITEMS/mcl_walls/init.lua b/mods/ITEMS/mcl_walls/init.lua index de1b1760f..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,7 +153,7 @@ 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", @@ -180,7 +182,7 @@ 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, @@ -206,7 +208,7 @@ 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, @@ -247,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}, @@ -267,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..445c8f7b3 100644 --- a/mods/ITEMS/mcl_walls/locale/mcl_walls.fr.tr +++ b/mods/ITEMS/mcl_walls/locale/mcl_walls.fr.tr @@ -3,7 +3,7 @@ A piece of wall. It cannot be jumped over with a simple jump. When multiple of t Cobblestone Wall=Muret de Pierres Mossy Cobblestone Wall=Muret de Pierres Moussu Andesite Wall=Muret d'Andésite -Granite Wall=Muret de Granite +Granite Wall=Muret de Granit Diorite Wall=Muret de Diorite Brick Wall=Muret en Brique Sandstone Wall=Muret de Grès 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/register.lua b/mods/ITEMS/mcl_walls/register.lua index 0ccefd62f..483af493e 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"}) 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.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/mclx_core/init.lua b/mods/ITEMS/mclx_core/init.lua index bc17e0075..4bb40184a 100644 --- a/mods/ITEMS/mclx_core/init.lua +++ b/mods/ITEMS/mclx_core/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mclx_core") +local S = minetest.get_translator(minetest.get_current_modname()) -- Liquids: 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_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.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_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.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/screwdriver/init.lua b/mods/ITEMS/screwdriver/init.lua index 942bccf38..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 diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.pl.tr b/mods/ITEMS/screwdriver/locale/screwdriver.pl.tr new file mode 100644 index 000000000..b9adac135 --- /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.zh_TW.tr b/mods/ITEMS/screwdriver/locale/screwdriver.zh_TW.tr new file mode 100644 index 000000000..f29a4bf33 --- /dev/null +++ b/mods/ITEMS/screwdriver/locale/screwdriver.zh_TW.tr @@ -0,0 +1,2 @@ +#textdomain: screwdriver +Screwdriver=螺絲刀 diff --git a/mods/ITEMS/xpanes/init.lua b/mods/ITEMS/xpanes/init.lua index 472b3efdf..fe67934a1 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) 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/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 9108b75c1..a04822439 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -6,8 +6,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) +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") + -- 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 jungle_bush_schematic = mod_mcl_core.."/schematics/mcl_core_jungle_bush_oak_leaves.mts" local deco_id_chorus_plant @@ -1492,7 +1496,7 @@ local function register_dimension_biomes() heat_point = 100, humidity_point = 0, _mcl_biome_type = "hot", - _mcl_palette_index = 19, + _mcl_palette_index = 17, }) --[[ THE END ]] @@ -2307,7 +2311,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", }) @@ -2328,7 +2332,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_small.mts", + schematic = mod_mcl_structures.."/schematics/mcl_structures_ice_spike_small.mts", rotation = "random", flags = "place_center_x, place_center_z", }) @@ -2351,7 +2355,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", }) @@ -2371,7 +2375,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", }) @@ -2392,7 +2396,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", }) @@ -2411,7 +2415,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", }) @@ -2430,7 +2434,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", }) @@ -2450,7 +2454,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", }) @@ -2469,7 +2473,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", }) @@ -2488,7 +2492,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", }) @@ -2508,7 +2512,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", }) @@ -2520,7 +2524,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", }) @@ -2532,7 +2536,7 @@ 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", }) @@ -2554,7 +2558,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", }) @@ -2575,7 +2579,7 @@ 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", }) @@ -2592,7 +2596,7 @@ local function register_decorations() 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", }) @@ -2604,7 +2608,7 @@ local function register_decorations() 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", }) @@ -2619,7 +2623,7 @@ local function register_decorations() 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", }) @@ -2631,7 +2635,7 @@ local function register_decorations() biomes = {"JungleEdge", "JungleEdgeM"}, 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", }) @@ -2644,7 +2648,7 @@ local function register_decorations() biomes = {"JungleM"}, 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", }) @@ -2669,7 +2673,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 @@ -2723,7 +2727,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", }) @@ -2743,7 +2747,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", }) @@ -2763,7 +2767,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_spruce_5.mts", + schematic = mod_mcl_core.."/schematics/mcl_core_spruce_5.mts", flags = "place_center_x, place_center_z", }) @@ -2777,7 +2781,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", }) @@ -2799,7 +2803,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({ @@ -2817,7 +2821,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", }) @@ -2836,7 +2840,7 @@ 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", }) @@ -2856,7 +2860,7 @@ 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", }) @@ -2878,7 +2882,7 @@ local function register_decorations() 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", }) @@ -2890,7 +2894,7 @@ local function register_decorations() 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", }) @@ -2903,7 +2907,7 @@ local function register_decorations() 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", }) @@ -2915,7 +2919,7 @@ local function register_decorations() 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", }) @@ -2929,7 +2933,7 @@ local function register_decorations() 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", }) @@ -2941,7 +2945,7 @@ local function register_decorations() 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", }) @@ -2954,7 +2958,7 @@ local function register_decorations() 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", }) @@ -2966,7 +2970,7 @@ local function register_decorations() 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", }) @@ -2987,7 +2991,7 @@ 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", }) @@ -3007,7 +3011,7 @@ 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", }) diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index 58e23b12e..f809b18e4 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -63,6 +63,67 @@ local surround_vectors = { { x=0, y=0, z=1 }, } +local loottable = +{ + { + stacks_min = 1, + stacks_max = 3, + items = { + { itemstring = "mcl_mobs:nametag", weight = 20 }, + { 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_core:apple_gold", weight = 15 }, + { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mobs_mc:gold_horse_armor", weight = 10 }, + { itemstring = "mobs_mc:diamond_horse_armor", weight = 5 }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2 }, + } + }, + { + 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 }, + { 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 }, + { 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 }, + { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, + }, + }, + { + 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 }, + }, + } +} + +-- 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 @@ -73,10 +134,15 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- 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 - if not registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable - or not registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end - end end end + 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 -- Check for air openings (2 stacked air at ground level) in wall positions local openings_counter = 0 @@ -226,7 +292,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) -- 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 - if registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then + 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 @@ -310,66 +377,6 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) set_node(pos, {name="mcl_chests:chest", param2=facedir}) local meta = get_meta(pos) - - local loottable = - { - { - stacks_min = 1, - stacks_max = 3, - items = { - { itemstring = "mcl_mobs:nametag", weight = 20 }, - { 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_core:apple_gold", weight = 15 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}, pr), weight = 10 }, - { itemstring = "mobs_mc:gold_horse_armor", weight = 10 }, - { itemstring = "mobs_mc:diamond_horse_armor", weight = 5 }, - { itemstring = "mcl_core:apple_gold_enchanted", weight = 2 }, - } - }, - { - 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 }, - { 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 }, - { 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 }, - { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, - }, - }, - { - 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 }, - }, - } - } - - -- 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 - 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 diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index b3db122e6..259cee88b 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -64,6 +64,7 @@ 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_void = minetest.get_content_id("mcl_core:void") @@ -1599,7 +1600,7 @@ local function generate_tree_decorations(minp, maxp, seed, data, param2_data, ar if dir < 5 and data[p_pos] == c_air - and l ~= nil and l > 12 then + and l and l > 12 then local c = pr:next(1, 3) if c == 1 then data[p_pos] = c_cocoa_1 @@ -1736,7 +1737,7 @@ local function generate_underground_mushrooms(minp, maxp, seed) 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 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 @@ -1799,7 +1800,7 @@ local function generate_nether_decorations(minp, maxp, seed) -- 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 + 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"}) @@ -1869,7 +1870,7 @@ minetest.register_on_generated(function(minp, maxp, blockseed) mcl_vars.add_chunk(minp) end) -minetest.register_on_generated=function(node_function) +function minetest.register_on_generated(node_function) mcl_mapgen_core.register_generator("mod_"..tostring(#registered_generators+1), nil, node_function) end @@ -1890,11 +1891,9 @@ function mcl_mapgen_core.register_generator(id, lvm_function, node_function, pri } registered_generators[id] = new_record - table.sort( - registered_generators, - function(a, b) - return (a.i < b.i) or ((a.i == b.i) and (a.vf ~= nil) and (b.vf == nil)) - end) + 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) @@ -2097,7 +2096,22 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) lvm_used = true end end - + + -- Set param2 (=color) of sugar cane + nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:reeds"}) + 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 then + data2[p_pos] = biome._mcl_palette_index + lvm_used = true + end + end + end end -- Nether block fixes: @@ -2181,15 +2195,16 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) lvm_used = true end + return lvm_used, shadow +end + +local function basic_node(minp, maxp, blockseed) if mg_name ~= "singlenode" then -- Generate special decorations generate_underground_mushrooms(minp, maxp, blockseed) generate_nether_decorations(minp, maxp, blockseed) - generate_structures(minp, maxp, blockseed, biomemap) + generate_structures(minp, maxp, blockseed, minetest.get_mapgen_object("biomemap")) end - - return lvm_used, shadow end -mcl_mapgen_core.register_generator("main", basic, nil, 1, true) - +mcl_mapgen_core.register_generator("main", basic, basic_node, 1, true) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index dfb7da24b..f596147f0 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -36,17 +36,17 @@ function mcl_structures.place_schematic(pos, schematic, rotation, replacements, 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)) + 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) end end function mcl_structures.get_struct(file) - local localfile = minetest.get_modpath("mcl_structures").."/schematics/"..file + local localfile = modpath.."/schematics/"..file local file, errorload = io.open(localfile, "rb") - if errorload ~= nil then - minetest.log("error", '[mcl_structures] Could not open this struct: ' .. localfile) + if errorload then + minetest.log("error", "[mcl_structures] Could not open this struct: "..localfile) return nil end @@ -179,7 +179,7 @@ function mcl_structures.generate_igloo(pos, rotation, pr) 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 + if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then bpos.y = tpos.y-y+1 break end @@ -187,8 +187,6 @@ function mcl_structures.generate_igloo(pos, rotation, pr) 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 }) @@ -199,6 +197,10 @@ function mcl_structures.generate_igloo(pos, rotation, pr) end -- Place basement mcl_structures.generate_igloo_basement(bpos, rotation, 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 @@ -290,17 +292,17 @@ local function hut_placement_callback(p1, p2, size, orientation, pr) end function mcl_structures.generate_witch_hut(pos, rotation, pr) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_witch_hut.mts" + local path = modpath.."/schematics/mcl_structures_witch_hut.mts" mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, hut_placement_callback, pr) end function mcl_structures.generate_ice_spike_small(pos, rotation) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_small.mts" + local path = modpath.."/schematics/mcl_structures_ice_spike_small.mts" return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0 end function mcl_structures.generate_ice_spike_large(pos, rotation) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_large.mts" + local path = modpath.."/schematics/mcl_structures_ice_spike_large.mts" return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0 end @@ -318,22 +320,22 @@ function mcl_structures.generate_fossil(pos, rotation, pr) "mcl_structures_fossil_spine_4.mts", -- 8×5×13 } local r = pr:next(1, #fossils) - local path = minetest.get_modpath("mcl_structures").."/schematics/"..fossils[r] + local path = modpath.."/schematics/"..fossils[r] return mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true) end function mcl_structures.generate_end_exit_portal(pos, rot) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" + local path = modpath.."/schematics/mcl_structures_end_exit_portal.mts" return mcl_structures.place_schematic(pos, path, rot or "0", {["mcl_portals:portal_end"] = "air"}, true) end function mcl_structures.generate_end_exit_portal_open(pos, rot) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" + local path = modpath.."/schematics/mcl_structures_end_exit_portal.mts" return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) end function mcl_structures.generate_end_gateway_portal(pos, rot) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_gateway_portal.mts" + local path = modpath.."/schematics/mcl_structures_end_gateway_portal.mts" return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) end @@ -367,7 +369,7 @@ local function shrine_placement_callback(p1, p2, size, rotation, pr) end -- 50% stonebrick (no change necessary) end - if bricktype ~= nil then + if bricktype then minetest.set_node(bricks[b], { name = bricktype }) end end @@ -420,7 +422,7 @@ function mcl_structures.generate_end_portal_shrine(pos, rotation, pr) --local size = {x=13, y=8, z=13} local newpos = { x = pos.x - offset.x, y = pos.y, z = pos.z - offset.z } - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" + local path = modpath.."/schematics/mcl_structures_end_portal_room_simple.mts" mcl_structures.place_schematic(newpos, path, rotation or "0", nil, true, nil, shrine_placement_callback, pr) end @@ -452,7 +454,9 @@ local function temple_placement_callback(p1, p2, size, rotation, pr) { 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"}, pr), weight = 20, }, + { 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 }, @@ -500,7 +504,7 @@ end function mcl_structures.generate_desert_temple(pos, rotation, pr) -- No Generating for the temple ... Why using it ? No Change - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_desert_temple.mts" + local path = modpath.."/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 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_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 3f4490bf9..c014bb07a 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -93,10 +93,6 @@ function settlements.create_site_plan(maxp, minp, pr) -- go build settlement around center if not center_surface then return false 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 @@ -187,10 +183,10 @@ local function construct_node(p1, p2, name) end return nodes end - minetest.log("warning","[mcl_villages] No on_construct defined for node name " .. name) + 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) + minetest.log("warning", "[mcl_villages] Attempt to 'construct' inexistant nodes: " .. name) end local function init_nodes(p1, p2, size, rotation, pr) construct_node(p1, p2, "mcl_itemframes:item_frame") diff --git a/mods/MAPGEN/mcl_villages/const.lua b/mods/MAPGEN/mcl_villages/const.lua index eb7806209..65f43f344 100644 --- a/mods/MAPGEN/mcl_villages/const.lua +++ b/mods/MAPGEN/mcl_villages/const.lua @@ -65,11 +65,6 @@ settlements.schematic_table = { {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 -- diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index ccc3f585d..a899b3234 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,7 +10,6 @@ dofile(settlements.modpath.."/paths.lua") -- -- load settlements on server -- -settlements_in_world = settlements.load() settlements.grundstellungen() @@ -37,7 +36,7 @@ minetest.register_node("mcl_villages:stonebrickcarved", { -- -- register inhabitants -- -if minetest.get_modpath("mobs_mc") ~= nil then +if minetest.get_modpath("mobs_mc") then mobs:register_spawn("mobs_mc:villager", --name {"mcl_core:stonebrickcarved"}, --nodes 15, --max_light diff --git a/mods/MAPGEN/mcl_villages/utils.lua b/mods/MAPGEN/mcl_villages/utils.lua index 993de11c4..22453a8ab 100644 --- a/mods/MAPGEN/mcl_villages/utils.lua +++ b/mods/MAPGEN/mcl_villages/utils.lua @@ -88,29 +88,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) diff --git a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua index 168ecf535..de4b18119 100644 --- a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua +++ b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua @@ -66,7 +66,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"}, pr), 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 }, diff --git a/mods/MAPGEN/tsm_railcorridors/init.lua b/mods/MAPGEN/tsm_railcorridors/init.lua index d7a074a00..451406167 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 @@ -151,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 @@ -175,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 @@ -189,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 @@ -197,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 @@ -208,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 @@ -250,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 @@ -274,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 @@ -395,7 +398,7 @@ local function RecheckCartHack(params) local cart_id = params[2] -- Find cart for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do - if obj ~= nil and obj:get_luaentity().name == cart_id then + 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)) @@ -426,7 +429,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 @@ -520,12 +523,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) diff --git a/mods/MISC/findbiome/init.lua b/mods/MISC/findbiome/init.lua index 5f55da493..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")) 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/mcl_commands/alias.lua b/mods/MISC/mcl_commands/alias.lua index 2989b7b37..5c9ee9f3c 100644 --- a/mods/MISC/mcl_commands/alias.lua +++ b/mods/MISC/mcl_commands/alias.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_commands") +local S = minetest.get_translator(minetest.get_current_modname()) local function register_chatcommand_alias(alias, cmd) local def = minetest.chatcommands[cmd] diff --git a/mods/MISC/mcl_commands/kill.lua b/mods/MISC/mcl_commands/kill.lua index 85754a0ec..becd42917 100644 --- a/mods/MISC/mcl_commands/kill.lua +++ b/mods/MISC/mcl_commands/kill.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_commands") +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 diff --git a/mods/MISC/mcl_commands/list.lua b/mods/MISC/mcl_commands/list.lua index 0257e2837..5661454b4 100644 --- a/mods/MISC/mcl_commands/list.lua +++ b/mods/MISC/mcl_commands/list.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_commands") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_chatcommand("list", { description = S("Show who is logged on"), 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.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/say.lua b/mods/MISC/mcl_commands/say.lua index 2b01a7e93..9fd53c174 100644 --- a/mods/MISC/mcl_commands/say.lua +++ b/mods/MISC/mcl_commands/say.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_commands") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_privilege("announce", { description = S("Can use /say"), diff --git a/mods/MISC/mcl_commands/seed.lua b/mods/MISC/mcl_commands/seed.lua index da5f6a303..6a99d53cb 100644 --- a/mods/MISC/mcl_commands/seed.lua +++ b/mods/MISC/mcl_commands/seed.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_commands") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_chatcommand("seed", { description = S("Displays the world seed"), diff --git a/mods/MISC/mcl_commands/setblock.lua b/mods/MISC/mcl_commands/setblock.lua index dc834e1e8..95acdd35d 100644 --- a/mods/MISC/mcl_commands/setblock.lua +++ b/mods/MISC/mcl_commands/setblock.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_commands") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_chatcommand("setblock", { params = S(",, "), diff --git a/mods/MISC/mcl_commands/sound.lua b/mods/MISC/mcl_commands/sound.lua index 06225271d..5833676f3 100644 --- a/mods/MISC/mcl_commands/sound.lua +++ b/mods/MISC/mcl_commands/sound.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_commands") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_chatcommand("playsound",{ params = S(" "), --TODO:add source diff --git a/mods/MISC/mcl_commands/summon.lua b/mods/MISC/mcl_commands/summon.lua index eb6066ff8..69da0a66c 100644 --- a/mods/MISC/mcl_commands/summon.lua +++ b/mods/MISC/mcl_commands/summon.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_commands") +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"]) diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index 00670db1c..dc3aa0f69 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.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.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_temp_helper_recipes/init.lua b/mods/MISC/mcl_temp_helper_recipes/init.lua index ff9f541f3..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"}, }) @@ -35,40 +35,6 @@ minetest.register_craft({ }, }) -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" }, - } -}) - -- Make red sand, red sandstone and more craftable in v6 -- NOTE: When you change these, also update mcl_craftguide for the "v6" icon in -- the craft guide! diff --git a/mods/MISC/mcl_wip/init.lua b/mods/MISC/mcl_wip/init.lua index 0eb56dd84..54fd81c1d 100644 --- a/mods/MISC/mcl_wip/init.lua +++ b/mods/MISC/mcl_wip/init.lua @@ -1,6 +1,6 @@ --- 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()) mcl_wip = {} mcl_wip.registered_wip_items = {} 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/PLAYER/mcl_death_drop/init.lua b/mods/PLAYER/mcl_death_drop/init.lua index fca566a37..665393ca5 100644 --- a/mods/PLAYER/mcl_death_drop/init.lua +++ b/mods/PLAYER/mcl_death_drop/init.lua @@ -1,16 +1,19 @@ 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}) + 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) @@ -30,7 +33,7 @@ minetest.register_on_dieplayer(function(player) end local listname = mcl_death_drop.registered_dropped_lists[l].listname local drop = mcl_death_drop.registered_dropped_lists[l].drop - if inv ~= nil then + if inv then for i, stack in ipairs(inv:get_list(listname)) do local x = random(0, 9)/3 local z = random(0, 9)/3 diff --git a/mods/PLAYER/mcl_hunger/api.lua b/mods/PLAYER/mcl_hunger/api.lua index 4fea9b04e..20937023a 100644 --- a/mods/PLAYER/mcl_hunger/api.lua +++ b/mods/PLAYER/mcl_hunger/api.lua @@ -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 diff --git a/mods/PLAYER/mcl_hunger/hunger.lua b/mods/PLAYER/mcl_hunger/hunger.lua index cf422dbf0..d9a6fd5fe 100644 --- a/mods/PLAYER/mcl_hunger/hunger.lua +++ b/mods/PLAYER/mcl_hunger/hunger.lua @@ -1,8 +1,7 @@ ---local S = minetest.get_translator("mcl_hunger") +--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) -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 @@ -122,7 +121,7 @@ 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 @@ -153,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 d212e631a..21c1e0860 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -1,4 +1,7 @@ -local S = minetest.get_translator("mcl_hunger") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local S = minetest.get_translator(modname) mcl_hunger = {} @@ -36,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 @@ -88,8 +91,8 @@ end -- register saturation hudbar 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" }, 1, 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" }, 1, 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) @@ -131,47 +134,46 @@ 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.25 then - if main_timer > mcl_hunger.HUD_TICK then main_timer = 0 end - for _,player in pairs(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.25 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) + 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 + + if food_level >= 18 then -- slow regenration + 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, 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 - mcl_util.deal_damage(player, 1, {type = "starve"}) - end + 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 >= 6 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, mcl_hunger.get_exhaustion(player)) + end end - end - end - if timer > 0.25 then - timer = 0 - timerMult = timerMult + 2 - 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.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_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 6cf2f0014..0dfe53976 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -9,7 +9,8 @@ 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") or controls.LMB then + if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") and not string.find(get_wielded_item_name, "mcl_bows:crossbow") and + not mcl_shields.wielding_shield(player, 1) and not mcl_shields.wielding_shield(player, 2) or controls.LMB then return true else return false @@ -188,7 +189,9 @@ 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 head_in_water = minetest.get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 @@ -204,6 +207,8 @@ minetest.register_globalstep(function(dtime) 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 @@ -212,6 +217,10 @@ minetest.register_globalstep(function(dtime) player_set_animation(player, "swim_walk_mine", animation_speed_mod) elseif not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_walk", animation_speed_mod) + elseif no_arm_moving and controls.RMB and controls.sneak or string.find(wielded_itemname, "mcl_bows:crossbow_") and controls.sneak then + 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 diff --git a/mods/PLAYER/mcl_player/mod.conf b/mods/PLAYER/mcl_player/mod.conf index 97ccce8e6..7cc5d14fa 100644 --- a/mods/PLAYER/mcl_player/mod.conf +++ b/mods/PLAYER/mcl_player/mod.conf @@ -1,3 +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_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index ceaef6346..1784b2e11 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -35,8 +35,8 @@ local function player_collision(player) for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do - if object and (object:is_player() - or (object:get_luaentity()._cmi_is_mob == true and object ~= player)) then + local ent = object:get_luaentity() + if (object:is_player() or (ent and ent._cmi_is_mob and object ~= player)) then local pos2 = object:get_pos() local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} @@ -51,6 +51,15 @@ local function player_collision(player) 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 @@ -111,6 +120,101 @@ end local node_stand, node_stand_below, node_head, node_feet +-- This following part is 2 wrapper functions for player: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) + +local function set_properties_conditional(player,props) + local changed,p=props_changed(props,player:get_properties()) + if changed then + player:set_properties(p) + end +end + +local function set_bone_position_conditional(player,b,p,r) --bone,position,rotation + local oldp,oldr=player:get_bone_position(b) + if vector.equals(vector.round(oldp),vector.round(p)) and vector.equals(vector.round(oldr),vector.round(r)) then + return + end + player:set_bone_position(b,p,r) +end + + + minetest.register_globalstep(function(dtime) time = time + dtime @@ -118,6 +222,7 @@ minetest.register_globalstep(function(dtime) for _,player in pairs(get_connected_players()) do --[[ + _ _ _ __ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___ / _` | '_ \| | '_ ` _ \ / _` | __| |/ _ \| '_ \/ __| @@ -163,12 +268,6 @@ minetest.register_globalstep(function(dtime) and (fly_node == "air" or fly_node == "ignore") if elytra.active then - if player_velocity.x < (player_velocity_old.x - 10) or player_velocity.x > (player_velocity_old.x + 10) and fly_node ~= "ignore" then - mcl_util.deal_damage(player, math.abs(player_velocity_old.x) * 0.2, {type = "fly_into_wall"}) - end - if player_velocity.z < (player_velocity_old.z - 10) or player_velocity.z > (player_velocity_old.z + 10) and fly_node ~= "ignore" then - mcl_util.deal_damage(player, math.abs(player_velocity_old.z) * 0.2, {type = "fly_into_wall"}) - end mcl_player.player_set_animation(player, "fly") if player_velocity.y < -1.5 then player:add_velocity({x=0, y=0.17, z=0}) @@ -189,22 +288,15 @@ minetest.register_globalstep(function(dtime) if vector.length(player_velocity) < 40 then local add_velocity = player.add_velocity or player.add_player_velocity add_velocity(player, vector.multiply(player:get_look_dir(), 4)) - minetest.add_particlespawner({ - amount = 1, - time = 0.1, - minpos = fly_pos, - maxpos = fly_pos, - 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.3, - maxexptime = 0.5, - minsize = 1, - maxsize = 2.5, + add_particle({ + pos = fly_pos, + velocity = {x = 0, y = 0, z = 0}, + acceleration = {x = 0, y = 0, z = 0}, + expirationtime = math.random(0.3, 0.5), + size = math.random(1, 2), collisiondetection = false, vertical = false, - texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", + texture = "mcl_particles_bonemeal.png^[colorize:#bc7a57:127", glow = 5, }) end @@ -215,65 +307,82 @@ minetest.register_globalstep(function(dtime) end if wielded_def and wielded_def._mcl_toollike_wield then - player:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) + set_bone_position_conditional(player,"Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) elseif string.find(wielded:get_name(), "mcl_bows:bow") then - player:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) + set_bone_position_conditional(player,"Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then + set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(64,90,0)) + elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then + set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(90,90,0)) else - player:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) + set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) end player_velocity_old = player:get_velocity() or player:get_player_velocity() - -- controls right and left arms pitch when shooting a bow - if string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB and not control.LMB and not control.up and not control.down and not control.left and not control.right then - player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) - player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) + + -- controls right and left arms pitch when shooting a bow or blocking + if mcl_shields.is_blocking(player) == 2 then + set_bone_position_conditional(player, "Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0), vector.new(20, -20, 0)) + elseif mcl_shields.is_blocking(player) == 1 then + set_bone_position_conditional(player, "Arm_Left_Pitch_Control", vector.new(3, 5.785, 0), vector.new(20, 20, 0)) + elseif string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then + set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) + set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) + -- controls right and left arms pitch when holing a loaded crossbow + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then + set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) + set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) + -- controls right and left arms pitch when loading a crossbow + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then + set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(45,-20,25)) + set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(55,20,-45)) -- when punching elseif control.LMB and not parent then - player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0)) - player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) + set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0)) + set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) -- when holding an item. elseif wielded:get_name() ~= "" then - player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(20,0,0)) - player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) + set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(20,0,0)) + set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) -- resets arms pitch else - player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) - player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) + set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0)) + set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) end if elytra.active then -- set head pitch and yaw when flying - player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) + set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) -- sets eye height, and nametag color accordingly - player:set_properties({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 }}) + set_properties_conditional(player,{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 }}) -- control body bone when flying - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) + set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) elseif parent then local parent_yaw = degrees(parent:get_yaw()) - player:set_properties({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 }}) - player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)) - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) + set_properties_conditional(player,{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 }}) + set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0)) + set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0,0,0)) elseif control.sneak then -- controls head pitch when sneaking - player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, player_vel_yaw - yaw)) + set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, player_vel_yaw - yaw)) -- sets eye height, and nametag color accordingly - player:set_properties({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 }}) + set_properties_conditional(player,{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 }}) -- sneaking body conrols - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) + set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), 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 - player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) + set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0)) -- sets eye height, and nametag color accordingly - player:set_properties({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 }}) + set_properties_conditional(player,{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 }}) -- control body bone when swimming - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) + set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0)) else -- sets eye height, and nametag color accordingly - player:set_properties({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 }}) + set_properties_conditional(player,{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 }}) - player:set_bone_position("Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0)) - player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) + set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0)) + set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) end -- Update jump status immediately since we need this info in real time. @@ -534,7 +643,8 @@ mcl_damage.register_modifier(function(obj, damage, reason) node = minetest.get_node(pos) end if node then - if minetest.registered_nodes[node.name].walkable 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 @@ -549,6 +659,9 @@ mcl_damage.register_modifier(function(obj, damage, reason) 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) diff --git a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.pl.tr b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.pl.tr new file mode 100644 index 000000000..67a82d95d --- /dev/null +++ b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.pl.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_playerplus +@1 suffocated to death.=@1 udusiła się na śmierć. +@1 was prickled to death by a cactus.=@1 została zakłuta na śmierć przez kaktusa. diff --git a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.zh_TW.tr b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.zh_TW.tr new file mode 100644 index 000000000..eb9e6b1db --- /dev/null +++ b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.zh_TW.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_playerplus +@1 suffocated to death.=@1 在牆壁裡窒息。 +@1 was prickled to death by a cactus.=@1 被仙人掌刺死了。 diff --git a/mods/PLAYER/mcl_playerplus/mod.conf b/mods/PLAYER/mcl_playerplus/mod.conf index 6989957d7..953ea9403 100644 --- a/mods/PLAYER/mcl_playerplus/mod.conf +++ b/mods/PLAYER/mcl_playerplus/mod.conf @@ -1,5 +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 +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/init.lua b/mods/PLAYER/mcl_skins/init.lua index fb91d74d3..6d5461a98 100644 --- a/mods/PLAYER/mcl_skins/init.lua +++ b/mods/PLAYER/mcl_skins/init.lua @@ -1,12 +1,14 @@ -- Skins for MineClone 2 +local modname = minetest.get_current_modname() + mcl_skins = { skins = {}, list = {}, previews = {}, meta = {}, has_preview = {}, - modpath = minetest.get_modpath("mcl_skins"), + modpath = minetest.get_modpath(modname), skin_count = 0, -- counter of _custom_ skins (all skins except character.png) } -local S = minetest.get_translator("mcl_skins") +local S = minetest.get_translator(modname) local has_mcl_inventory = minetest.get_modpath("mcl_inventory") -- load skin list and metadata @@ -53,7 +55,7 @@ while true do data = nil if f then - data = minetest.deserialize("return {" .. f:read('*all') .. "}") + data = minetest.deserialize("return {" .. f:read("*all") .. "}") f:close() end @@ -138,7 +140,7 @@ minetest.register_on_joinplayer(function(player) 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 + if skin_id and skin_id ~= "" then set_skin = tonumber(skin_id) -- otherwise use random skin if not set end @@ -220,7 +222,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if mcl_skins.skin_count <= 6 then -- Change skin immediately if there are not many skins mcl_skins.cycle_skin(player) - if player:get_attach() ~= nil then + if player:get_attach() then mcl_player.player_set_animation(player, "sit") end else diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.pl.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.pl.tr new file mode 100644 index 000000000..9b07cea2c --- /dev/null +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.pl.tr @@ -0,0 +1,13 @@ +# textdomain: mcl_skins +[] []=[] [] +Select player skin of yourself or another player=Wybierz skin gracza dla siebie lub innego gracza +Insufficient or wrong parameters=Niewystarczające lub złe parametry +Player @1 not online!=Gracz @1 nie jest online! +You need the “server” privilege to change the skin of other players!=Potrzebujesz uprawnienia "serwer", aby zmieniać skiny innych graczy! +Invalid skin number! Valid numbers: 0 to @1=Niepoprawny numer skina! Poprawne numery: od 0 do @1 +Your skin has been set to: @1=Twój skin został ustawiony na: @1 +Your skin has been set to: @1 (@2)=Twój skin został ustawiony na: @1 (@2) +Skin of @1 set to: @2 (@3)=Skin gracza @1 ustawiony na @2 (@3) +Select player skin:=Wybierz skin gracza: +@1 (@2)=@1 (@2) +Name: @1=Nazwa: @1 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.zh_TW.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.zh_TW.tr new file mode 100644 index 000000000..1347800ee --- /dev/null +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.zh_TW.tr @@ -0,0 +1,13 @@ +# 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的皮膚已換成:@1 +Select player skin:=選擇玩家皮膚: +@1 (@2)=@1(@2) +Name: @1=名稱:@1 diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index b8c746d1f..113a4d27f 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -1,6 +1,6 @@ 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() @@ -379,7 +379,7 @@ 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 @@ -395,7 +395,7 @@ 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 and player:is_player() then local attr = player:get_meta():get_string("mcl_beds:spawn") @@ -415,7 +415,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 @@ -443,7 +443,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 @@ -451,7 +451,7 @@ 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 + if player and player:is_player() then player:get_meta():set_string("mcl_beds:spawn", "") end minetest.chat_send_player(player:get_player_name(), S("Your spawn bed was missing or blocked.")) @@ -482,7 +482,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 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_sprint/init.lua b/mods/PLAYER/mcl_sprint/init.lua index 546a5f4f0..4c0d609c9 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 = {} @@ -53,18 +69,19 @@ local function setSprinting(playerName, sprinting) --Sets the state of a player local controls = player:get_player_control() if players[playerName] then players[playerName].sprinting = sprinting + local fov_old = players[playerName].fov + local fov_new = fov_old + local fade_time = .15 if sprinting == true or controls.RMB and string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and player:get_wielded_item():get_name() ~= "mcl_bows:bow" then if sprinting == true then - players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2) - players[playerName].fade_time = .15 + fov_new = math.min(players[playerName].fov + 0.05, 1.2) else - players[playerName].fov = .7 + fov_new = .7 players[playerName].fade_time = .3 end - player:set_fov(players[playerName].fov, true, players[playerName].fade_time) if sprinting == true then playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) end @@ -72,12 +89,15 @@ local function setSprinting(playerName, sprinting) --Sets the state of a player 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 - players[playerName].fov = math.max(players[playerName].fov - 0.05, 1.0) - player:set_fov(players[playerName].fov, true, 0.15) + 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 return false @@ -133,12 +153,12 @@ 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 players[playerName]["clientSprint"] or ctrl.aux1 and ctrl.up and not ctrl.sneak then @@ -150,22 +170,21 @@ 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 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}, @@ -192,7 +211,7 @@ 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) + if (mcl_hunger.active and get_hunger(player) <= 6) or (player:get_meta():get_string("mcl_beds:sleeping") == "true") then sprinting = false cancelClientSprinting(playerName) diff --git a/mods/PLAYER/mcl_wieldview/init.lua b/mods/PLAYER/mcl_wieldview/init.lua index fc9ebc074..ff70445e3 100644 --- a/mods/PLAYER/mcl_wieldview/init.lua +++ b/mods/PLAYER/mcl_wieldview/init.lua @@ -1,9 +1,12 @@ +local get_connected_players = minetest.get_connected_players +local get_item_group = minetest.get_item_group + mcl_wieldview = { players = {} } function mcl_wieldview.get_item_texture(itemname) - if itemname == "" then + if itemname == "" or minetest.get_item_group(itemname, "no_wieldview") ~= 0 then return end @@ -19,7 +22,7 @@ function mcl_wieldview.get_item_texture(itemname) local texture = inv_image - local transform = minetest.get_item_group(itemname, "wieldview_transform") + local transform = get_item_group(itemname, "wieldview_transform") 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 @@ -69,8 +72,9 @@ minetest.register_on_leaveplayer(function(player) end) minetest.register_globalstep(function() - for _, player in pairs(minetest.get_connected_players()) do - mcl_wieldview.update_wielded_item(player) + local players = get_connected_players() + for i = 1, #players do + mcl_wieldview.update_wielded_item(players[i]) end end) @@ -109,6 +113,10 @@ minetest.register_entity("mcl_wieldview:wieldnode", { self.object:set_properties({textures = {""}}) end + if minetest.get_item_group(itemstring, "no_wieldview") ~= 0 then + self.object:set_properties({textures = {""}}) + end + self.itemstring = itemstring end else diff --git a/settingtypes.txt b/settingtypes.txt index 78a8122b5..542711675 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] @@ -33,9 +33,12 @@ 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 @@ -153,3 +156,7 @@ fix_doubleplants (Mcimport double plant fixes) bool true # Allow players to create Minecraft-like maps. enable_real_maps (Enable Real Maps) bool true + +[Debugging] +# If enabled, this will show the itemstring of an item in the description. +mcl_item_id_debug (Item ID Debug) bool false \ No newline at end of file diff --git a/tools/Conversion_Table.csv b/tools/Conversion_Table.csv index 426712f5b..07343479d 100644 --- a/tools/Conversion_Table.csv +++ b/tools/Conversion_Table.csv @@ -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/Texture_Converter.py b/tools/Texture_Converter.py index 820fa9c08..bdf249113 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 @@ -397,20 +386,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/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..db124aaf6 --- /dev/null +++ b/tools/generate_ingame_credits.lua @@ -0,0 +1,50 @@ +#! /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", + ["Contributors"] = "0x52FF00", + ["MineClone5"] = "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)