diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..8e3084dd3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +end_of_line = lf + +[*.lua] +charset = utf8 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true +keep_one_space_between_table_and_bracket = false +spaces_around_operators = true diff --git a/.gitea/issue_template/bug.md b/.gitea/issue_template/bug.md new file mode 100644 index 000000000..be76e6395 --- /dev/null +++ b/.gitea/issue_template/bug.md @@ -0,0 +1,36 @@ +--- + +name: "Bug report" +about: "File a bug report" +labels: + +- unconfirmed +- bug + +--- + + + + +MineClone2 version: + +### What happened? +Report about the bug! Please send large log snippets as an attachement file. + +### What should happen: +Tell us what should happen! + +### Steps to reproduce +Tell us how we can reproduce the bug! diff --git a/.gitea/issue_template/feature_request.md b/.gitea/issue_template/feature_request.md new file mode 100644 index 000000000..58a7437ab --- /dev/null +++ b/.gitea/issue_template/feature_request.md @@ -0,0 +1,26 @@ +--- + +name: "Feature request" +about: "File a feature request not in Minecraft" +labels: + +- "non-Minecraft feature" +- "needs discussion" + +--- + + + +### Feature +Tell us about your requested feature not in Minecraft! + +### Why +Tell us why should we implement it! diff --git a/.gitea/issue_template/missing_feature_request.md b/.gitea/issue_template/missing_feature_request.md new file mode 100644 index 000000000..b3e275c9b --- /dev/null +++ b/.gitea/issue_template/missing_feature_request.md @@ -0,0 +1,25 @@ +--- + +name: "Missing Feature request" +about: "File a missing feature request in Minecraft but not in MineClone2" +labels: + +- "missing feature" + +--- + + + +### Current feature in Minecraft +Tell us about the feature currently in Minecraft! What is it like on Minecraft? + +### Current feature in MineClone2 +Tell us about the feature currently in MineClone2! What is different? diff --git a/.gitea/pull_request_template.md b/.gitea/pull_request_template.md new file mode 100644 index 000000000..ec7207ee4 --- /dev/null +++ b/.gitea/pull_request_template.md @@ -0,0 +1,20 @@ +--- + +name: "Pull request" +about: "Submit a pull request" +labels: + +--- + + + +Tell us about your pull request! Reference related issues, if necessary + +### Testing +Tell us how to test your changes! diff --git a/.gitignore b/.gitignore index 8228ba34a..574521980 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *.blend1 *.blend2 *.blend3 +/.idea/ diff --git a/API.md b/API.md index e73d5f8a4..f2070b8e7 100644 --- a/API.md +++ b/API.md @@ -42,7 +42,7 @@ A lot of things are possible by using one of the APIs in the mods. Note that not * Buckets: `ITEMS/mcl_buckets` * Dispenser support: `ITEMS/REDSTONE/mcl_dispensers` -## Mobs +### Mobs * Mobs: `ENTITIES/mcl_mobs` MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 8086a2f44..ffb1194aa 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -eliasfleckenstein@web.de. +ancientmariner_dev@proton.me. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5cbd6bcfc..232d577d2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ So you want to contribute to MineClone2? Wow, thank you! :-) -MineClone2 is maintained by Nicu and Fleckenstein. If you have any +MineClone2 is maintained by Nicu and Cora. If you have any problems or questions, contact us (See Links section below). You can help with MineClone2's development in many different ways, @@ -11,18 +11,9 @@ whether you're a programmer or not. ## 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. +singleplayer and multiplayer. Currently, a lot of Minecraft features +are already implemented. +Polishing existing features is always welcome. ## Links * [Mesehub](https://git.minetest.land/MineClone2/MineClone2) @@ -45,8 +36,10 @@ 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. -## How you can help as a non-programmer +Look at our wiki for some concrete guides: +https://git.minetest.land/MineClone2/MineClone2/wiki/ +## How you can help as a non-programmer As someone who does not know how to write programs in Lua or does not know how to use the Minetest API, you can still help us out a lot. For example, by opening an issue in the @@ -58,12 +51,10 @@ you can report a bug or request a feature. 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. +Try not to report bugs that have already been reported or request features +that already have been requested. This can often be ambiguous though. +If in doubt open an issue! * If you know about Minetest's inner workings, please think about whether the bug / the feature that you are reporting / requesting is actually an issue with Minetest itself, and if it is, head to the @@ -73,6 +64,9 @@ instead. an issue, feel free to ask on the Discord / Matrix server or the IRC channel. +The link to the mesehub registration page is: https://git.minetest.land/user/sign_up +(It appears to sometimes get lost on the page itsself) + ### Reporting bugs * A bug is an unintended behavior or, in the worst case, a crash. However, it is not a bug if you believe something is missing in the @@ -111,23 +105,28 @@ 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. +requests that start with a `WIP:` are not done yet and therefore could +still undergo substantial change. Testing these is still helpful however +because that is the reason developers put them up as WIP so other people +can have a look at the PR. ### Contributing assets -Due to license problems, MineClone2 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 +Due to license problems, MineClone2 cannot use Minecraft's assets, +therefore we are always looking for asset contributions. + +To contribute assets, it can be useful to learn git basics and read +the section for Programmers of this document, however this is not required. +It's also a good idea to join the Discord server (or alternatively IRC or Matrix). #### Textures -For textures we 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. +For textures we use the Pixel Perfection texture pack. For older Minecraft +features that is mostly enough but a lot of the newer textures in it are +copies or slight modifications of the original MC textures so great caution +needs to be taken when using any textures coming from Minecraft texture +packs. +If you want to make such contributions, join our Discord server. Demands +for textures will be communicated there. #### Sounds MineClone2 currently does not have a consistent way to handle sounds. @@ -251,16 +250,25 @@ of the results) * [Official Minecraft Wiki](https://minecraft.fandom.com/wiki/Minecraft_Wiki) (Include a link to the specific page you used) -### Stick to our guidelines +### Guidelines #### 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) +* Pushing to master is disabled - don't even try it. +* Every change is tracked as a PR. +* All but the tiniest changes require at least one approval from a Developer +* To update branches we use rebase not merge (so we don't end up with +excessive git bureaucracy commits in master) +* We use merge to add the commits from a PR/branch to master +* Submodules should only be used if a) upstream is highly reliable and +b) it is 100% certain that no mcl2 specific changes to the code will be +needed (this has never been the case before, hence mcl2 is submodule free so far) +* Commit messages should be descriptive and never contain mcl2 specific +issueids - there are other projects who might use commits from mcl2 and +it will confuse their issue trackers. +* Try to group your submissions best as you can: +* Try to keep your PRs small: In some cases things reasonably be can't +split up but in general multiple small PRs are better than a big one. +* Similarly multiple small commits are better than a giant one. (use git commit -p) #### Code Guidelines * Each mod must provide `mod.conf`. @@ -343,36 +351,23 @@ 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. +- If you have developer privileges you can just open a new branch in the +mcl2 repository (which is preferred). From that you create a pull request. +This way other people can review your changes and make sure they work +before they get merged. +- If you do not (yet) have developer privs you do your work on a branch +on your private repository e.g. using the "fork" function on mesehub. +- Any developer is welcome to review, test and merge PRs. A PR needs +at least one approval (by someone else than the author) but the maintainers +are usually relatively quick to react to new submissions. ### Maintainer status Maintainers carry the main responsibility for the project. #### Maintainer responsibilities - Making sure issues are addressed and pull requests are reviewed and -merged, by assigning either themselves or Developers to issues / PRs +merged. - 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) @@ -380,8 +375,8 @@ merged, by assigning either themselves or Developers to issues / PRs - Resolving conflicts and problems within the community #### Current maintainers -* Fleckenstein - responsible for gameplay review, publishing releases, -technical guidelines and issue/PR delegation +* Cora - responsible for gameplay review, publishing releases, +technical guidelines * Nicu - responsible for community related issues #### Release process diff --git a/CREDITS.md b/CREDITS.md index c1174e797..9c2930155 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -8,12 +8,13 @@ ## Maintainers +* AncientMariner * Nicu -* cora ## Previous Maintainers * Fleckenstein * jordan4ibanez +* cora ## Developers * bzoss @@ -27,6 +28,14 @@ * Code-Sploit * NO11 * kabou +* rudzik8 +* chmodsayshello +* PrairieWind +* RandomLegoBrick +* SumianVoice +* MrRar +* talamh +* Faerraven ## Contributors * Laurent Rocher @@ -60,7 +69,6 @@ * Benjamin Schötz * Doloment * Sydney Gems -* talamh * Emily2255 * Emojigit * FinishedFragment @@ -71,6 +79,23 @@ * Sven792 * aldum * Dieter44 +* Pepebotella +* MrRar +* Lazerbeak12345 +* mrminer +* Thunder1035 +* opfromthestart +* snowyu +* FaceDeer +* Faerraven / Michieal +* FossFanatic +* Herbert West +* GuyLiner +* 3raven +* anarquimico +* TheOnlyJoeEnderman +* Ranko Saotome +* Gregor Parzefall ## MineClone5 * kay27 @@ -78,10 +103,12 @@ * epCode * NO11 * j45 +* chmodsayshello * 3raven -* PrarieWind -* Gustavo1 +* PrairieWind +* Gustavo6046 / wallabra * CableGuy67 +* MrRar ## Mineclonia * erlehmann @@ -119,6 +146,7 @@ * 4Evergreen4 * jordan4ibanez * paramat +* cora ## 3D Models * 22i @@ -134,6 +162,10 @@ * yutyo * NO11 * kay27 +* MysticTempest +* RandomLegoBrick +* cora +* Faerraven / Michieal ## Translations * Wuzzy @@ -143,6 +175,11 @@ * pitchum * todoporlalibertad * Marcin Serwin +* Pepebotella +* Emojigit +* snowyu +* 3raven +* SakuraRiu ## Funders * 40W @@ -150,5 +187,7 @@ ## Special thanks * celeron55 for creating Minetest * Jordach for the jukebox music compilation from Big Freaking Dig +* wsor for working tirelessly in the shadows for the good of all of us, particularly helping with solving contentDB and copyright issues. * 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 +* Dark Reaven Music (https://soundcloud.com/dark-reaven-music) for the main menu theme (Calmed Cube), which is licensed under https://creativecommons.org/licenses/by-sa/3.0/ diff --git a/GROUPS.md b/GROUPS.md index 3c954111f..e6d878990 100644 --- a/GROUPS.md +++ b/GROUPS.md @@ -74,6 +74,8 @@ Please read to learn how digging times * `coral_species=X`: Specifies the species of a coral; equal X means equal species * `set_on_fire=X`: Sets any (not fire-resistant) mob or player on fire for X seconds when touching * `compostability=X`: Item can be used on a composter block; X (1-100) is the % chance of adding a level of compost +* `leaves=X`: Node will spotaneously decay if no tree trunk nodes remain within 6 blocks distance. +* `leaves_orphan`: See above, these nodes are in the process of decayed. #### Footnotes diff --git a/README.md b/README.md index 908769438..f69647efe 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 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.75 (in development) +Version: 0.82 (in development) ### Gameplay You start in a randomly-generated world made entirely of cubes. You can explore @@ -91,11 +91,11 @@ The MineClone2 repository is hosted at Mesehub. To contribute or report issues, ## 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 +singleplayer and multiplayer. Currently, a lot of **Minecraft Java +Edition** 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 +**Current Minecraft versions + 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. @@ -108,8 +108,7 @@ playerbase on low spec computers, optimizations are hard to investigate. This game is currently in **beta** stage. It is playable, but not yet feature-complete. Backwards-compability is not entirely guaranteed, updating your world might cause small bugs. -If you want to use the git version of MineClone2 in production, consider using the production branch. -It is updated weekly and contains relatively stable code for servers. +If you want to use the development version of MineClone2 in production, the master branch is usually relatively stable. The testing branch often features some experimental PRs and should be considered less stable. The following main features are available: @@ -124,7 +123,7 @@ The following main features are available: * Most blocks in the overworld * Water and lava * Weather -* 28 biomes +* 28 biomes + 5 Nether Biomes * The Nether, a fiery underworld in another dimension * Redstone circuits (partially) * Minecarts (partial) @@ -159,10 +158,10 @@ The following features are incomplete: * Some monsters and animals * Redstone-related things -* Special minecarts +* Some special minecarts (hopper and chest minecarts work) * A couple of non-trivial blocks and items -Bonus features (not found in Minecraft 1.12): +Bonus features (not found in Minecraft): * Built-in crafting guide which shows you crafting and smelting recipes * In-game help system containing extensive help about gameplay basics, blocks, items and more @@ -175,6 +174,9 @@ Bonus features (not found in Minecraft 1.12): * Nether Brick Fence Gate * Red Nether Brick Fence * Red Nether Brick Fence Gate +* Structure replacements - these small variants of Minecraft structures serve as replacements until we can get large structures working: + * Woodland Cabin (Mansions) + * Nether Outpost (Fortress) Technical differences from Minecraft: diff --git a/README_locale/README.fr.md b/README_locale/README.fr.md new file mode 100644 index 000000000..989b6d377 --- /dev/null +++ b/README_locale/README.fr.md @@ -0,0 +1,170 @@ +# MineClone2 +Un jeu non-officiel similaire à Minecraft pour Minetest. Forké depuis Mineclone par davedevils. Développé par de nombreuses personnes. Ni développé ou supporté par Mojang AB. + + Version: 0.79 (en dévelopment) + +### Gameplay + +Vous atterissez dans un monde fait entièrement de cubes et généré aléatoirement. Vous pouvez explorer le monde, miner et construire presque n'importe quel bloc pour créer de nouvelles structures. Vous pouvez choisir de jouer en "mode survie" dans lequel vous devez combattre des monstres et la faim et progresser lentement dans différents aspects du jeu, comme l'extraction de minerai, l'agriculture, la construction de machines et ainsi de suite. Ou alors vous pouvez jouer en "mode créatif" où vous pouvez construire à peu près n'importe quoi instantanément. + +### Résumé du Gameplay + +* Jeu de type bac-à-sable, sans objetifs +* Survie : combattre des monstres hostiles et la faim +* Creuser pour du minerai et d'autres trésors +* Magie : gagner de l'expérience et enchanter les outils +* Utiliser les blocs ramassés pour construire de magnifiques bâtiments, votre imagination est la limite +* Ramasser des fleurs (et d'autres sources de teinture) et colorez votre monde +* Trouvez des graines et commencez à cultiver +* Trouvez ou fabriquez des centaines d'objets +* Construisez un réseau ferroviaire complexe et amusez vous avec les wagonnets +* En mode créatif vous pouvez construire presque n'importe quoi gratuitement et sans limite + +## Comment jouer (démarrer rapidement) +### Commencer +* **Frappez un arbre** jusqu'à ce qu'il casse et donne du bois +* Placez le **bois dans la grille 2x2** (la "grille de fabrication" de votre menu d'inventaire) et fabriquez 4 planches de bois +* Placer les 4 planches de bois dans la grille 2x2 et **fabriquez une table d'artisanat** +* **Cliquez droit la table d'artisanat** (icone livre) pour apprendre toutes les recettes possibles +* **Fabriquez une pioche de bois** pour miner la pierre +* Différents outils minent différentes sortes de blocs. Essayez les ! +* Continuez à jouer comme vous voulez. Amusez vous ! + +### Agriculture +* Trouvez des graines +* Fabriquez une houe +* Cliquez droit la terre ou des blocs similaires avec la houe pour créer des terres agricoles +* Placer des graines sur des terres agricoles et regardez les pousser +* Récoltez les plantes une fois matûres +* Les terres agricoles proche de l'eau deviennent humides et accélèrent la croissance + +### Four +* Fabriquer un Four +* Le four permet d'obtenir plus d'objets +* L'emplacement du haut doit contienir un objet fondable (par ex : minerai de fer) +* L'emplacement du bas doit contienir un objet combustible (par ex : charbon) +* Voir le guide d'artisanat pour en apprendre plus sur les objets fondables et combustibles + +### Aide supplémentaire +Plus d'aide à propos du jeu, des blocs, objets et plus encore peuvent être trouvés dans le jeu. Vous pouvez accéder à l'aide depuis le menu inventaire. + +### Objets spéciaux +Les objets suivants sont intéressants pour le mode Créatif et pour les constructeurs de cartes d'aventure. Ils ne peuvent être obtenus dans le jeu ou dans l'inventaire créatif. + +* Barrière : `mcl_core:barrier` + +Utilisez la commande de chat `/giveme` pour les obtenir. Voir l'aide interne au jeu pour une explication. + +## Installation +Ce jeu nécessite [Minetest](http://minetest.net) pour fonctionner (version 5.4.1 ou plus). Vous devez donc installer Minetest d'abord. Seules les versions stables de Minetest sont officielement supportées. +Il n'y a pas de support de MineClone2 dans les versions développement de Minetest. + +Pour installer MineClone2 (si ce n'est pas déjà fait), déplacez ce dossier dans le dossier “games” de Minetest. Consultez l'aide de Minetest pour en apprendre plus. + +## Liens utiles +Le dépôt de MineClone2 est hébergé sur Mesehub. Pour contribuer ou rapporter des problèmes, aller là-bas. + +* Mesehub: +* Discord: +* YouTube +* IRC: +* Matrix: +* Reddit: +* Minetest forums: +* ContentDB: +* OpenCollective: + +## Objectif +* Créer un clone stable, moddable, libre et gratuit basé sur le moteur de jeu Minetest avec des fonctionalités abouties, utilisable à la fois en mode solo et multijoueur. Actuellement, beaucoup des fonctionalités de **Minecraft Java Edition** sont déjà implémentées et leur amélioration est prioritaire sur les nouvelles demandes. +* Avec une priorité moindre, implémenter les fonctionalités des versions **Minecraft + OptiFine** (OtiFine autant que supporté par le moteur Minetest). Cela signifie que les fonctionalités présentes dans les versions listées sont priorisées. +* Dans l'idéal, créer une expérience performante qui tourne bien sur des ordinateurs à basse performance. Malheureusement, en raison des mécanismes de Minecraft et des limitations du moteur Minetest ainsi que de la petite taille de la communauté de joueurs sur des ordinateurs à basse performances, les optimisations sont difficiles à explorer. + +## Statut de complétion +Ce jeu est actuellement au stade **beta**. +Il est jouable mais incomplet en fonctionalités. +La rétro-compatibilité n'est pas entièrement garantie, mettre votre monde à jour peut causer de petits bugs. +Si vous voulez utiliser la version de développement de MineClone2 en production, la branche master est habituellement relativement stable. Les branches de test fusionnent souvent des pull requests expérimentales et doivent être considérées comme moins stable. + +Les principales fonctionalités suivantes sont disponibles : + +* Outils, armes +* Armure +* Système de fabrication : grille 2x2, table d'artisanat (grille 3x3), four, incluant un guide de fabrication +* Coffres, grands coffres, coffre ender, boite de shulker +* Fours, entonnoirs +* Faim +* La plupart des monstres et animaux +* Tout les minerais de Minecraft +* La plupart des blocs de l'overworld +* Eau et lave +* Météo +* 28 biomes + 5 biomes du nether +* Le Nether, monde souterrain brûlant dans une autre dimension +* Circuits Redstone (partiel) +* Effets de Statut (partiel) +* Expérience +* Enchantement +* Brassage, potions, flèches trempées (partiel) +* Bâteaux +* Feu +* Blocs de construction : escaliers, dalles, portes, trappes, barrière, portillon, muret +* Horloge +* Boussole +* Eponge +* Bloc de slime +* Petites plantes et pousses +* Teintures +* Bannières +* Blocs de décoration : verre, verre teinté, vitres, barres de fer, terre cuites (et couleurs), têtes et plus +* Cadres d'objets +* Juke-boxes +* Livres pour écrire +* Commandes +* Villages +* L'End +* et plus ! + +Les fonctionalités suivantes sont incomplètes : + +* certains monstres et animaux +* certains composants de Redstone +* Wagonnets spéciaux +* quelques blocs et objets non-triviaux + +Fonctionalités bonus (absentes de Minecraft) : + +* Guide d'artisanat intégré au jeu qui montre les recettes d'artisanat et de cuisson +* Système d'aide intégré au jeu contenant des informations à propos des techniques de base, blocs, objets et plus +* Recettes d'artisanat temporaires. Elles existent uniquement pour rendre des objets accessibles qui ne le seraient pas autrement sauf en mode créatif. Elles seront retirées au cours de l'avancement du développement et de l'ajout de nouvelles fonctionalités. +* Pousses dans les coffres en mapgen v6 +* Entièrement moddable (grâce la puissante API lua de Minetest) +* Nouveaux blocs et objets : + * Outil de recherche, montre l'aide de ce qu'il touche + * Plus de dalles et d'escaliers + * Portillon en briques du Nether + * Barrière en briques du Nether rouges + * Portillon en briques du Nether rouges +* Structures de remplacement - ces petites variantes de structures de Minecraft servent de remplacement en attendant qu'on arrive à en faire fonctionner de plus grandes : + * Cabine dans les bois (Manoir des bois) + * Avant-poste du Nether (Forteresse) + +Différences techniques avec Minecraft : +* Limite en hauteur de 31000 blocs (bien plus grand que Minecraft) +* Taille horizontale du monde 62000×62000 blocs (bien plus petit que Minecraft mais toujours très grand) +* Toujours assez incomplet et buggé +* Des blocs, objets, ennemis et fonctionalités manquent +* Quelques objets ont des noms légèrement différents pour être plus faciles à distinguer +* Des musiques différentes pour le juke-boxe +* Des textures différentes (Pixel Perfection) +* Des sons différents (sources diverses) +* Un moteur de jeu différent (Minetest) +* Des bonus cachés différents +...et enfin MineClone2 est un logiciel libre ! + +## Autres fichiers readme + +* `LICENSE.txt`: Le texte de la license GPLv3 +* `CONTRIBUTING.md`: Information pour ceux qui veulent contribuer +* `API.md`: Pour les modders Minetest qui veulent modder ce jeu +* `LEGAL.md`: Information légale +* `CREDITS.md`: Liste des contributeurs \ No newline at end of file diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..01eb71e7f --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,19 @@ +#File to document release steps with a view to evolving into a script + +#Update CREDITS.md +#Update version in README.md (soon to be game.conf from of 0.82.0) + +lua tools/generate_ingame_credits.lua + +git add CREDITS.md +git add mods/HUD/mcl_credits/people.lua + +git add README.md +# To uncomment when applicable +#git add game.conf + +git commit -m "Pre-release update credits and set version 0.81.1" + +git tag 0.81.1 + +git push origin 0.81.1 \ No newline at end of file diff --git a/game.conf b/game.conf index db7357702..1fa1d6671 100644 --- a/game.conf +++ b/game.conf @@ -1,2 +1,4 @@ -name = MineClone 2 +title = MineClone 2 description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more. +disallowed_mapgens = v6 +version=MCL2-0.82-indev \ No newline at end of file diff --git a/menu/HeaderTemplate.png b/menu/HeaderTemplate.png new file mode 100644 index 000000000..ceddaa1f6 Binary files /dev/null and b/menu/HeaderTemplate.png differ diff --git a/menu/background.1.png b/menu/background.1.png new file mode 100644 index 000000000..07e1f6672 Binary files /dev/null and b/menu/background.1.png differ diff --git a/menu/background.10.png b/menu/background.10.png new file mode 100644 index 000000000..5f63b0ea1 Binary files /dev/null and b/menu/background.10.png differ diff --git a/menu/background.2.png b/menu/background.2.png new file mode 100644 index 000000000..3050cf411 Binary files /dev/null and b/menu/background.2.png differ diff --git a/menu/background.3.png b/menu/background.3.png new file mode 100644 index 000000000..a4d1c4358 Binary files /dev/null and b/menu/background.3.png differ diff --git a/menu/background.4.png b/menu/background.4.png new file mode 100644 index 000000000..c50332f6f Binary files /dev/null and b/menu/background.4.png differ diff --git a/menu/background.5.png b/menu/background.5.png new file mode 100644 index 000000000..1c776a88e Binary files /dev/null and b/menu/background.5.png differ diff --git a/menu/background.6.png b/menu/background.6.png new file mode 100644 index 000000000..478c65912 Binary files /dev/null and b/menu/background.6.png differ diff --git a/menu/background.7.png b/menu/background.7.png new file mode 100644 index 000000000..56c30a08b Binary files /dev/null and b/menu/background.7.png differ diff --git a/menu/background.8.png b/menu/background.8.png new file mode 100644 index 000000000..ed285700c Binary files /dev/null and b/menu/background.8.png differ diff --git a/menu/background.9.png b/menu/background.9.png new file mode 100644 index 000000000..760aaa4e5 Binary files /dev/null and b/menu/background.9.png differ diff --git a/menu/background.png b/menu/background.png new file mode 100644 index 000000000..51bfb374e Binary files /dev/null and b/menu/background.png differ diff --git a/menu/footer.png b/menu/footer.png index 9207b26d3..72f80a43c 100644 Binary files a/menu/footer.png and b/menu/footer.png differ diff --git a/menu/header.1.png b/menu/header.1.png new file mode 100644 index 000000000..5204a0d02 Binary files /dev/null and b/menu/header.1.png differ diff --git a/menu/header.2.png b/menu/header.2.png new file mode 100644 index 000000000..8b131302e Binary files /dev/null and b/menu/header.2.png differ diff --git a/menu/header.3.png b/menu/header.3.png new file mode 100644 index 000000000..dc618d7c6 Binary files /dev/null and b/menu/header.3.png differ diff --git a/menu/header.png b/menu/header.png index 11435df51..3c146f3cd 100644 Binary files a/menu/header.png and b/menu/header.png differ diff --git a/menu/overlay.1.png b/menu/overlay.1.png deleted file mode 100644 index 62790a202..000000000 Binary files a/menu/overlay.1.png and /dev/null differ diff --git a/menu/overlay.2.png b/menu/overlay.2.png deleted file mode 100644 index ad1de325a..000000000 Binary files a/menu/overlay.2.png and /dev/null differ diff --git a/menu/overlay.3.png b/menu/overlay.3.png deleted file mode 100644 index 390848476..000000000 Binary files a/menu/overlay.3.png and /dev/null differ diff --git a/menu/overlay.4.png b/menu/overlay.4.png deleted file mode 100644 index 2480f2c50..000000000 Binary files a/menu/overlay.4.png and /dev/null differ diff --git a/menu/overlay.5.png b/menu/overlay.5.png deleted file mode 100644 index 482ec23f0..000000000 Binary files a/menu/overlay.5.png and /dev/null differ diff --git a/menu/overlay.png b/menu/overlay.png deleted file mode 100644 index 5d4f51b6f..000000000 Binary files a/menu/overlay.png and /dev/null differ diff --git a/menu/theme.ogg b/menu/theme.ogg new file mode 100644 index 000000000..00644da4a Binary files /dev/null and b/menu/theme.ogg differ diff --git a/mods/CORE/mcl_attached/init.lua b/mods/CORE/mcl_attached/init.lua index c4a7a3337..2013dbde2 100644 --- a/mods/CORE/mcl_attached/init.lua +++ b/mods/CORE/mcl_attached/init.lua @@ -5,6 +5,8 @@ -- Nodes in group "supported_node" can be placed on any node that does not -- have the "airlike" drawtype. Carpets are an example of this type. +local pairs = pairs +local math = math local vector = vector local facedir_to_dir = minetest.facedir_to_dir @@ -22,15 +24,17 @@ local add_item = minetest.add_item -- We need this to do the exact same dropping node handling in our override -- minetest.check_single_for_falling() function as in the builtin function. -- +---@param p Vector local function drop_attached_node(p) local n = get_node(p) local drops = get_node_drops(n, "") local def = registered_nodes[n.name] + if def and def.preserve_metadata then local oldmeta = get_meta(p):to_table().fields -- Copy pos and node because the callback can modify them. - local pos_copy = vector.new(p) - local node_copy = {name=n.name, param1=n.param1, param2=n.param2} + local pos_copy = vector.copy(p) + local node_copy = { name = n.name, param1 = n.param1, param2 = n.param2 } local drop_stacks = {} for k, v in pairs(drops) do drop_stacks[k] = ItemStack(v) @@ -38,16 +42,18 @@ local function drop_attached_node(p) 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) + minetest.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, - } + local pos = vector.offset(p, + math.random() / 2 - 0.25, + math.random() / 2 - 0.25, + math.random() / 2 - 0.25 + ) add_item(pos, item) end end @@ -90,4 +96,3 @@ function minetest.check_single_for_falling(pos) return false end - diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 262b0cf55..773e7a43e 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -12,6 +12,7 @@ mcl_damage = { drown = {bypasses_armor = true}, starve = {bypasses_armor = true, bypasses_magic = true}, cactus = {}, + sweet_berry = {}, fall = {bypasses_armor = true}, fly_into_wall = {bypasses_armor = true}, -- unused out_of_world = {bypasses_armor = true, bypasses_magic = true, bypasses_invulnerability = true, bypasses_totem = true}, @@ -33,6 +34,8 @@ mcl_damage = { } } +local damage_enabled = minetest.settings:get_bool("enabled_damage",true) + function mcl_damage.register_modifier(func, priority) table.insert(mcl_damage.modifiers, {func = func, priority = priority or 0}) end @@ -139,6 +142,7 @@ function mcl_damage.register_type(name, def) end minetest.register_on_player_hpchange(function(player, hp_change, mt_reason) + if not damage_enabled then return 0 end if hp_change < 0 then if player:get_hp() <= 0 then return 0 @@ -149,6 +153,7 @@ minetest.register_on_player_hpchange(function(player, hp_change, mt_reason) end, true) minetest.register_on_player_hpchange(function(player, hp_change, mt_reason) + if not damage_enabled then return 0 end if player:get_hp() > 0 then mt_reason.approved = true if hp_change < 0 then @@ -161,9 +166,9 @@ minetest.register_on_dieplayer(function(player, mt_reason) if mt_reason.approved then mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason)) end + minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos()))) end) minetest.register_on_mods_loaded(function() table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end) end) - diff --git a/mods/CORE/mcl_events/API.md b/mods/CORE/mcl_events/API.md new file mode 100644 index 000000000..c94328e50 --- /dev/null +++ b/mods/CORE/mcl_events/API.md @@ -0,0 +1,27 @@ +## mcl_events +### Registering Events + `mlc_events.register_event("name",def)` + +#### Event Definition + { + stage = 0, + max_stage = 1, + percent = 100, + bars = {}, + completed = false, + cond_start = function() end, + --return table of paramtables e.g. { { player = playername, pos = position, ... } }, custom parameters will be passed to the event object/table + on_step = function(event) end, + --this function is run every game step when the event is active + on_start = function(event) end, + -- this function is run when the event starts + on_stage_begin = function(event) end, + -- this function runs when a new stage of the event starts + cond_progress = function(event) end, --return false or next stage id + --this function checks if the event should progress to the next (or any other) stage + cond_complete = function(event) end, + --return true if event finished successfully +} + +### Debugging + * /event_start -- starts the given event at the current player coordinates diff --git a/mods/CORE/mcl_events/init.lua b/mods/CORE/mcl_events/init.lua new file mode 100644 index 000000000..625076bae --- /dev/null +++ b/mods/CORE/mcl_events/init.lua @@ -0,0 +1,155 @@ +mcl_events = {} +mcl_events.registered_events = {} +local disabled_events = minetest.settings:get("mcl_disabled_events") +if disabled_events then disabled_events = disabled_events:split(",") +else disabled_events = {} end +local DBG = minetest.settings:get_bool("mcl_logging_event_api",false) +local active_events = {} + +local event_tpl = { + stage = 0, + max_stage = 1, + percent = 100, + bars = {}, + completed = false, + cond_start = function(event) end, --return table of positions + on_step = function(event) end, + on_start = function(event) end, + on_stage_begin = function(event) end, + cond_progress = function(event) end, --return next stage + cond_complete = function(event) end, --return success +} + +local function mcl_log(m,l) + if DBG then + if not l then l = "action" end + minetest.log(l,"[mcl_events] "..m) + end +end + +function mcl_events.register_event(name,def) + if table.indexof(disabled_events,name) ~= -1 then return end + mcl_events.registered_events[name] = def + mcl_events.registered_events[name].name = name +end + +local function addbars(self) + if not self.enable_bossbar then return end + for _,player in pairs(minetest.get_connected_players()) do + if vector.distance(self.pos,player:get_pos()) < 64 then + local bar = mcl_bossbars.add_bar(player, {color = "red", text = self.readable_name .. ": Wave "..self.stage.." / "..self.max_stage, percentage = self.percent }, true,1) + table.insert(self.bars,bar) + end + end +end + +local function start_event(p,e) + mcl_log("[mcl_events] Event started: "..e.readable_name.." at "..minetest.pos_to_string(vector.round(p.pos))) + local idx = #active_events + 1 + active_events[idx] = table.copy(e) + setmetatable(active_events[idx],{__index = event_tpl}) + for k,v in pairs(p) do active_events[idx][k] = v end + active_events[idx].stage = 0 + active_events[idx].percent = 100 + active_events[idx].bars = {} + active_events[idx].time_start = os.time() + if active_events[idx].on_start then + active_events[idx]:on_start(p.pos) + end + addbars(active_events[idx]) +end + +local function finish_event(self,idx) + mcl_log("[mcl_events] Finished: "..self.readable_name.." at "..minetest.pos_to_string(vector.round(self.pos))) + if self.on_complete then self:on_complete() end + for _,b in pairs(self.bars) do + mcl_bossbars.remove_bar(b) + end + table.remove(active_events,idx) +end + +local etime = 0 +function check_events(dtime) + --process active events + for idx,ae in pairs(active_events) do + if ae.cond_complete and ae:cond_complete() then + ae.finished = true + finish_event(ae,idx) + elseif not ae.cond_complete and ae.max_stage and ae.max_stage <= ae.stage then + ae.finished = true + finish_event(ae,idx) + elseif not ae.finished and ae.cond_progress then + local p = ae:cond_progress() + if p == true then + ae.stage = ae.stage + 1 + if ae:on_stage_begin() == true then + mcl_log("[mcl_events] Event "..ae.readable_name.." at "..minetest.pos_to_string(vector.round(ae.pos)).." failed at stage_begin of stage "..ae.stage ) + active_events[idx] = nil + end + elseif tonumber(p) then + ae.stage = tonumber(p) or ae.stage + 1 + ae:on_stage_begin() + end + elseif not ae.finished and ae.on_step then + ae:on_step(dtime) + end + addbars(ae) + end + -- check if a new event should be started + etime = etime - dtime + if etime > 0 then return end + etime = 10 + for _,e in pairs(mcl_events.registered_events) do + local pp = e.cond_start() + if pp then + --minetest.log("It's gonna start the raid maybe") + for _,p in pairs(pp) do + local start = true + if e.exclusive_to_area then + for _,ae in pairs(active_events) do + if e.name == ae.name and vector.distance(p.pos,ae.pos) < e.exclusive_to_area then start = false end + end + end + if start then + --minetest.log("It's gonna start the raid definitely") + start_event(p,e) + elseif DBG then + mcl_log("[mcl_events] Event "..e.readable_name.." already active at "..minetest.pos_to_string(vector.round(p.pos))) + end + end + else + --minetest.log("Do not start this raid") + end + end + for idx,ae in pairs(active_events) do + local player_near = false + for _,pl in pairs(minetest.get_connected_players()) do + if ae.pos and vector.distance(pl:get_pos(),ae.pos) < 64 then player_near = true end + end + if ae.pos and not player_near then + mcl_log("[mcl_events] Event "..ae.readable_name.." at "..minetest.pos_to_string(vector.round(ae.pos)).." aborted - no players near." ) + active_events[idx] = nil + end + end +end + +minetest.register_globalstep(check_events) + +mcl_info.register_debug_field("Active Events",{ + level = 4, + func = function(pl,pos) + return tostring(#active_events) + end +}) + +minetest.register_chatcommand("event_start",{ + privs = {debug = true}, + description = "Debug command to start events", + func = function(pname,param) + local p = minetest.get_player_by_name(pname) + local evdef = mcl_events.registered_events[param] + if not evdef then return false,"Event "..param.." doesn't exist.'" end + start_event({pos=p:get_pos(),player=pname,factor=1},evdef) + return true,"Started event "..param + end, +}) diff --git a/mods/CORE/mcl_events/mod.conf b/mods/CORE/mcl_events/mod.conf new file mode 100644 index 000000000..29a45628a --- /dev/null +++ b/mods/CORE/mcl_events/mod.conf @@ -0,0 +1,3 @@ +name = mcl_events +author = cora +depends = mcl_mobs,mcl_bossbars, mcl_info diff --git a/mods/CORE/mcl_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index 0132d1669..b67c7c6a2 100644 --- a/mods/CORE/mcl_explosions/init.lua +++ b/mods/CORE/mcl_explosions/init.lua @@ -130,10 +130,10 @@ local function add_particles(pos, radius) time = 0.125, minpos = pos, maxpos = pos, - minvel = {x = -radius, y = -radius, z = -radius}, - maxvel = {x = radius, y = radius, z = radius}, - minacc = vector.new(), - maxacc = vector.new(), + minvel = vector.new(-radius, -radius, -radius), + maxvel = vector.new(radius, radius, radius), + minacc = vector.zero(), + maxacc = vector.zero(), minexptime = 0.5, maxexptime = 1.0, minsize = radius * 0.5, @@ -207,7 +207,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc local npos_z = math.floor(rpos_z + 0.5) local npos = { x = npos_x, y = npos_y, z = npos_z } local idx = (npos_z - emin_z) * zstride + (npos_y - emin_y) * ystride + - npos_x - emin_x + 1 + npos_x - emin_x + 1 local cid = data[idx] local br = node_blastres[cid] or INDESTRUCT_BLASTRES @@ -288,7 +288,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc rdir_y = rdir_y / rdir_len rdir_z = rdir_z / rdir_len - for i=0, rdir_len / STEP_LENGTH do + for i = 0, rdir_len / STEP_LENGTH do rpos_x = rpos_x + rdir_x * STEP_LENGTH rpos_y = rpos_y + rdir_y * STEP_LENGTH rpos_z = rpos_z + rdir_z * STEP_LENGTH @@ -296,7 +296,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc local npos_y = math.floor(rpos_y + 0.5) local npos_z = math.floor(rpos_z + 0.5) local idx = (npos_z - emin_z) * zstride + (npos_y - emin_y) * ystride + - npos_x - emin_x + 1 + npos_x - emin_x + 1 local cid = data[idx] @@ -333,17 +333,17 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc end if sleep_formspec_doesnt_close_mt53 then - minetest.after(0.3, function() -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE - if not obj:is_player() then - return - end + minetest.after(0.3, + function() -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE + if not obj:is_player() then + return + end + mcl_util.deal_damage(obj, damage, { type = "explosion", direct = direct, source = source }) - mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source}) - - obj:add_velocity(vector.multiply(punch_dir, impact * 20)) - end) + obj:add_velocity(vector.multiply(punch_dir, impact * 20)) + end) else - mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source}) + mcl_util.deal_damage(obj, damage, { type = "explosion", direct = direct, source = source }) if obj:is_player() or ent.tnt_knockback then obj:add_velocity(vector.multiply(punch_dir, impact * 20)) @@ -389,23 +389,24 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc -- We use bulk_set_node instead of LVM because we want to have on_destruct and -- on_construct being called if #airs > 0 then - bulk_set_node(airs, {name="air"}) + bulk_set_node(airs, { name = "air" }) end if #fires > 0 then - bulk_set_node(fires, {name="mcl_fire:fire"}) + bulk_set_node(fires, { name = "mcl_fire:fire" }) end -- Update falling nodes - for a=1, #airs do + for a = 1, #airs do local p = airs[a] - check_for_falling({x=p.x, y=p.y+1, z=p.z}) + check_for_falling(vector.offset(p, 0, 1, 0)) end - for f=1, #fires do + for f = 1, #fires do local p = fires[f] - check_for_falling({x=p.x, y=p.y+1, z=p.z}) + check_for_falling(vector.offset(p, 0, 1, 0)) end -- Log explosion - minetest.log("action", "Explosion at "..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. @@ -429,6 +430,11 @@ end -- griefing - If true, the explosion will destroy nodes (default: true) -- grief_protected - If true, the explosion will also destroy nodes which have -- been protected (default: false) +---@param pos Vector +---@param strength number +---@param info {drop_chance: number, max_blast_resistance: number, sound: boolean, particles: boolean, fire: boolean, griefing: boolean, grief_protected: boolean} +---@param direct? ObjectRef +---@param source? ObjectRef function mcl_explosions.explode(pos, strength, info, direct, source) if info == nil then info = {} diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.ja.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.ja.tr new file mode 100644 index 000000000..ce59ab4b3 --- /dev/null +++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.ja.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_explosions +@1 was caught in an explosion.=@1は爆発に巻き込まれた。 diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index fec9c7ba9..f77b03828 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -3,26 +3,26 @@ mcl_vars = {} mcl_vars.redstone_tick = 0.1 ---- GUI / inventory menu settings +-- GUI / inventory menu settings mcl_vars.gui_slots = "listcolors[#9990;#FFF7;#FFF0;#000;#FFF]" + -- nonbg is added as formspec prepend in mcl_formspec_prepend -mcl_vars.gui_nonbg = mcl_vars.gui_slots .. - "style_type[image_button;border=false;bgimg=mcl_inventory_button9.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]".. - "style_type[button;border=false;bgimg=mcl_inventory_button9.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]".. - "style_type[field;textcolor=#323232]".. - "style_type[label;textcolor=#323232]".. - "style_type[textarea;textcolor=#323232]".. - "style_type[checkbox;textcolor=#323232]" +mcl_vars.gui_nonbg = table.concat({ + mcl_vars.gui_slots, + "style_type[image_button;border=false;bgimg=mcl_inventory_button9.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]", + "style_type[button;border=false;bgimg=mcl_inventory_button9.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]", + "style_type[field;textcolor=#323232]", + "style_type[label;textcolor=#323232]", + "style_type[textarea;textcolor=#323232]", + "style_type[checkbox;textcolor=#323232]", +}) -- Background stuff must be manually added by mods (no formspec prepend) mcl_vars.gui_bg_color = "bgcolor[#00000000]" mcl_vars.gui_bg_img = "background9[1,1;1,1;mcl_base_textures_background9.png;true;7]" --- Legacy -mcl_vars.inventory_header = "" - -- Tool wield size -mcl_vars.tool_wield_scale = { x = 1.8, y = 1.8, z = 1 } +mcl_vars.tool_wield_scale = vector.new(1.8, 1.8, 1) -- Mapgen variables local mg_name = minetest.get_mapgen_setting("mg_name") @@ -35,55 +35,69 @@ mcl_vars.chunksize = math.max(1, tonumber(minetest.get_mapgen_setting("chunksize mcl_vars.MAP_BLOCKSIZE = math.max(1, minetest.MAP_BLOCKSIZE or 16) mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000) mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, minetest.MAX_MAP_GENERATION_LIMIT or 31000) + 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 + local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE local central_chunk_max_pos = central_chunk_min_pos + mcl_vars.chunk_size_in_nodes - 1 local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE -local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE) +local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / + mcl_vars.MAP_BLOCKSIZE) local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1 local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / mcl_vars.chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits. + mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * mcl_vars.chunk_size_in_nodes mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * mcl_vars.chunk_size_in_nodes +---@param x integer +---@return integer local function coordinate_to_block(x) return math.floor(x / mcl_vars.MAP_BLOCKSIZE) end +---@param x integer +---@return integer local function coordinate_to_chunk(x) return math.floor((coordinate_to_block(x) - central_chunk_offset) / mcl_vars.chunksize) end +---@param pos Vector +---@return Vector function mcl_vars.pos_to_block(pos) - return { - x = coordinate_to_block(pos.x), - y = coordinate_to_block(pos.y), - z = coordinate_to_block(pos.z) - } + return vector.new( + coordinate_to_block(pos.x), + coordinate_to_block(pos.y), + coordinate_to_block(pos.z) + ) end +---@param pos Vector +---@return Vector function mcl_vars.pos_to_chunk(pos) - return { - x = coordinate_to_chunk(pos.x), - y = coordinate_to_chunk(pos.y), - z = coordinate_to_chunk(pos.z) - } + return vector.new( + coordinate_to_chunk(pos.x), + coordinate_to_chunk(pos.y), + coordinate_to_chunk(pos.z) + ) end local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / mcl_vars.chunk_size_in_nodes) local k_positive_z = k_positive * 2 local k_positive_y = k_positive_z * k_positive_z +---@param pos Vector +---@return integer function mcl_vars.get_chunk_number(pos) -- unsigned int local c = mcl_vars.pos_to_chunk(pos) - return - (c.y + k_positive) * k_positive_y + + return (c.y + k_positive) * k_positive_y + (c.z + k_positive) * k_positive_z + - c.x + k_positive + c.x + k_positive end if not superflat and not singlenode then @@ -117,11 +131,8 @@ elseif singlenode then mcl_vars.mg_bedrock_is_rough = false else -- Classic superflat - local ground = minetest.get_mapgen_setting("mgflat_ground_level") - ground = tonumber(ground) - if not ground then - ground = 8 - end + local ground = tonumber(minetest.get_mapgen_setting("mgflat_ground_level")) or 8 + mcl_vars.mg_overworld_min = ground - 3 mcl_vars.mg_overworld_max_official = mcl_vars.mg_overworld_min + minecraft_height_limit mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min @@ -138,6 +149,7 @@ mcl_vars.mg_nether_min = -29067 -- Carefully chosen to be at a mapchunk border mcl_vars.mg_nether_max = mcl_vars.mg_nether_min + 128 mcl_vars.mg_bedrock_nether_bottom_min = mcl_vars.mg_nether_min mcl_vars.mg_bedrock_nether_top_max = mcl_vars.mg_nether_max +mcl_vars.mg_nether_deco_max = mcl_vars.mg_nether_max -11 -- this is so ceiling decorations don't spill into other biomes as bedrock generation calls minetest.generate_decorations to put netherrack under the bedrock if not superflat then mcl_vars.mg_bedrock_nether_bottom_max = mcl_vars.mg_bedrock_nether_bottom_min + 4 mcl_vars.mg_bedrock_nether_top_min = mcl_vars.mg_bedrock_nether_top_max - 4 @@ -162,7 +174,8 @@ end mcl_vars.mg_end_min = -27073 -- Carefully chosen to be at a mapchunk border mcl_vars.mg_end_max_official = mcl_vars.mg_end_min + minecraft_height_limit mcl_vars.mg_end_max = mcl_vars.mg_overworld_min - 2000 -mcl_vars.mg_end_platform_pos = { x = 100, y = mcl_vars.mg_end_min + 74, z = 0 } +mcl_vars.mg_end_platform_pos = { x = 100, y = mcl_vars.mg_end_min + 64, z = 0 } +mcl_vars.mg_end_exit_portal_pos = vector.new(0, mcl_vars.mg_end_min + 71, 0) -- Realm barrier used to safely separate the End from the void below the Overworld mcl_vars.mg_realm_barrier_overworld_end_max = mcl_vars.mg_end_max @@ -179,14 +192,16 @@ minetest.craftitemdef_default.stack_max = 64 math.randomseed(os.time()) local chunks = {} -- intervals of chunks generated + +---@param pos Vector function mcl_vars.add_chunk(pos) local n = mcl_vars.get_chunk_number(pos) -- unsigned int local prev for i, d in pairs(chunks) do if n <= d[2] then -- we've found it if (n == d[2]) or (n >= d[1]) then return end -- already here - if n == d[1]-1 then -- right before: - if prev and (prev[2] == n-1) then + if n == d[1] - 1 then -- right before: + if prev and (prev[2] == n - 1) then prev[2] = d[2] table.remove(chunks, i) return @@ -194,17 +209,20 @@ function mcl_vars.add_chunk(pos) d[1] = n return end - if prev and (prev[2] == n-1) then --join to previous + if prev and (prev[2] == n - 1) then --join to previous prev[2] = n return end - table.insert(chunks, i, {n, n}) -- insert new interval before i + table.insert(chunks, i, { n, n }) -- insert new interval before i return end prev = d end - chunks[#chunks+1] = {n, n} + chunks[#chunks + 1] = { n, n } end + +---@param pos Vector +---@return boolean function mcl_vars.is_generated(pos) local n = mcl_vars.get_chunk_number(pos) -- unsigned int for i, d in pairs(chunks) do @@ -215,47 +233,46 @@ function mcl_vars.is_generated(pos) return false end --- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like mt 5.4 does. --- p: Position, if it's wrong, {name="error"} node will return. --- force: optional (default: false) - Do the maximum to still read the node within us_timeout. --- us_timeout: optional (default: 244 = 0.000244 s = 1/80/80/80), set it at least to 3000000 to let mapgen to finish its job. --- --- returns node definition, eg. {name="air"}. Unfortunately still can return {name="ignore"}. -function mcl_vars.get_node(p, force, us_timeout) +---"Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like mt 5.4 does. +---@param pos Vector Position, if it's wrong, `{name="error"}` node will return. +---@param force? boolean Optional (default: `false`), Do the maximum to still read the node within us_timeout. +---@param us_timeout? number Optional (default: `244 = 0.000244 s = 1/80/80/80`), set it at least to `3000000` to let mapgen to finish its job +---@return node # Node definition, eg. `{name="air"}`. Unfortunately still can return `{name="ignore"}`. +---@nodiscard +function mcl_vars.get_node(pos, force, us_timeout) -- check initial circumstances - if not p or not p.x or not p.y or not p.z then return {name="error"} end + if not pos or not pos.x or not pos.y or not pos.z then return { name = "error" } end -- try common way - local node = minetest.get_node(p) + local node = minetest.get_node(pos) if node.name ~= "ignore" then return node end - -- copy table to get sure it won't changed by other threads - local pos = {x=p.x,y=p.y,z=p.z} + -- copy vector to get sure it won't changed by other threads + local pos_copy = vector.copy(pos) -- try LVM - minetest.get_voxel_manip():read_from_map(pos, pos) - node = minetest.get_node(pos) + minetest.get_voxel_manip():read_from_map(pos_copy, pos_copy) + node = minetest.get_node(pos_copy) if node.name ~= "ignore" or not force then return node end -- all ways failed - need to emerge (or forceload if generated) - local us_timeout = us_timeout or 244 - if mcl_vars.is_generated(pos) then + if mcl_vars.is_generated(pos_copy) then minetest.chat_send_all("IMPOSSIBLE! Please report this to MCL2 issue tracker!") - minetest.forceload_block(pos) + minetest.forceload_block(pos_copy) else - minetest.emerge_area(pos, pos) + minetest.emerge_area(pos_copy, pos_copy) end local t = minetest.get_us_time() - node = minetest.get_node(pos) + node = minetest.get_node(pos_copy) - while (not node or node.name == "ignore") and (minetest.get_us_time() - t < us_timeout) do - node = minetest.get_node(pos) + while (not node or node.name == "ignore") and (minetest.get_us_time() - t < (us_timeout or 244)) do + node = minetest.get_node(pos_copy) end return node diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_soul_fire_flame.png b/mods/CORE/mcl_particles/textures/mcl_particles_soul_fire_flame.png new file mode 100644 index 000000000..94022a6c3 Binary files /dev/null and b/mods/CORE/mcl_particles/textures/mcl_particles_soul_fire_flame.png differ diff --git a/mods/CORE/mcl_sounds/README.txt b/mods/CORE/mcl_sounds/README.txt index 9fc2ba28f..2ede2c1f9 100644 --- a/mods/CORE/mcl_sounds/README.txt +++ b/mods/CORE/mcl_sounds/README.txt @@ -11,42 +11,22 @@ Creative Commons Attribution 3.0 Unported (CC BY-SA 3.0) http://creativecommons.org/licenses/by/3.0/ Glass breaking sounds (CC BY 3.0): - 1: http://www.freesound.org/people/cmusounddesign/sounds/71947/ - 2: http://www.freesound.org/people/Tomlija/sounds/97669/ - 3: http://www.freesound.org/people/lsprice/sounds/88808/ + 1: http://www.freesound.org/people/cmusounddesign/sounds/71947/ + 2: http://www.freesound.org/people/Tomlija/sounds/97669/ + 3: http://www.freesound.org/people/lsprice/sounds/88808/ default_tool_breaks.ogg by EdgardEdition (CC BY 3.0), http://www.freesound.org/people/EdgardEdition Mito551 (sounds) (CC BY-SA 3.0): - default_dig_choppy.ogg - default_dig_cracky.ogg - default_dig_crumbly.1.ogg - default_dig_crumbly.2.ogg + default_dig_crumbly.ogg default_dig_oddly_breakable_by_hand.ogg - default_dug_node.1.ogg - default_dug_node.2.ogg - default_grass_footstep.1.ogg - default_grass_footstep.2.ogg - default_grass_footstep.3.ogg - default_gravel_footstep.1.ogg - default_gravel_footstep.2.ogg - default_gravel_footstep.3.ogg - default_gravel_footstep.4.ogg - default_grass_footstep.1.ogg - default_place_node.1.ogg - default_place_node.2.ogg - default_place_node.3.ogg - default_place_node_hard.1.ogg - default_place_node_hard.2.ogg - default_hard_footstep.1.ogg - default_hard_footstep.2.ogg - default_hard_footstep.3.ogg - default_sand_footstep.1.ogg - default_sand_footstep.2.ogg - default_wood_footstep.1.ogg - default_wood_footstep.2.ogg - default_dirt_footstep.1.ogg - default_dirt_footstep.2.ogg + default_dug_node.*.ogg + default_grass_footstep.*.ogg + default_gravel_footstep.*.ogg + default_place_node.*.ogg + default_place_node_hard.*.ogg + default_wood_footstep.*.ogg + default_dirt_footstep.*.ogg default_glass_footstep.ogg Metal sounds: @@ -54,35 +34,64 @@ Metal sounds: - https://www.freesound.org/people/yadronoff/sounds/320397/ default_dug_metal.*.ogg - Iwan Gabovitch - qubodup - CC0 - http://opengameart.org/users/qubodup - default_metal_footstep.*.ogg - Ottomaani138 - CC0 - - https://www.freesound.org/people/Ottomaani138/sounds/232692/ + default_metal_footstep.*.ogg - (CC0 1.0) - CC0 1.0 + - https://freesound.org/people/mypantsfelldown/sounds/398937/ default_place_node_metal.*.ogg - Ogrebane - CC0 - http://opengameart.org/content/wood-and-metal-sound-effects-volume-2 -AGFX (CC BY 3.0) +AGFX (CC BY 3.0): https://www.freesound.org/people/AGFX/packs/1253/ - default_water_footstep.1.ogg - default_water_footstep.2.ogg - default_water_footstep.3.ogg -(default_water_footstep.4.ogg is silent) + default_water_footstep.*.ogg -blukotek (CC0 1.0) +blukotek (CC0 1.0): https://www.freesound.org/people/blukotek/sounds/251660/ default_dig_snappy.ogg -sonictechtonic (CC BY 3.0) +sonictechtonic (CC BY 3.0): https://www.freesound.org/people/sonictechtonic/sounds/241872/ player_damage.ogg -Voxelands project (CC BY-SA 3.0) +Sheyvan (CC0 1.0): +https://freesound.org/people/Sheyvan/sounds/476113/ + default_dig_choppy.*.ogg + +lolamadeus (CC0 1.0): +https://freesound.org/people/lolamadeus/sounds/179341/ + default_gravel_dig.*.ogg + default_gravel_dug.*.ogg + +Benboncan (CC BY 3.0): +https://freesound.org/people/Benboncan/sounds/71823/ + default_dig_cracky.*.ogg + +Erdie (CC BY 3.0): +https://freesound.org/people/Erdie/sounds/41579/ + default_hard_footstep.*.ogg + +worthahep88 (CC0 1.0): +https://freesound.org/people/worthahep88/sounds/319224/ + default_sand_footstep.*.ogg + +dheming (CC BY 3.0): +https://freesound.org/people/dheming/sounds/268023/ + default_ice_dig.*.ogg + +InspectorJ (CC BY 3.0): +https://freesound.org/people/InspectorJ/sounds/416967/ + default_ice_footstep.*.ogg + +Angel_Perez_Grandi (CC BY 3.0): +https://freesound.org/people/Angel_Perez_Grandi/sounds/49190/ + default_ice_dug.ogg + +Voxelands project (CC BY-SA 3.0): mcl_sounds_place_node_water.ogg mcl_sounds_dug_water.ogg (Note: Artists from the Voxelands project include: sdzen, darkrose, sapier, Tom Peter, Telaron, juskiddink) -Michel Baradari (CC BY 3.0) - +Michel Baradari (CC BY 3.0): default_place_node_lava.ogg Adam_N (CC0 1.0): @@ -90,7 +99,7 @@ Adam_N (CC0 1.0): Source: Alecia Shepherd (CC BY-SA 4.0): - mcl_sounds_cloth.ogg + mcl_sounds_cloth.*.ogg Source: SnowSong sound and music pack Unknown authors (WTFPL): diff --git a/mods/CORE/mcl_sounds/init.lua b/mods/CORE/mcl_sounds/init.lua index 13ca7bf72..30157060c 100644 --- a/mods/CORE/mcl_sounds/init.lua +++ b/mods/CORE/mcl_sounds/init.lua @@ -11,7 +11,7 @@ function mcl_sounds.node_sound_defaults(table) table.dug = table.dug or {name="default_dug_node", gain=0.25} table.dig = table.dig or - {name="default_dig_oddly_breakable_by_hand", gain=1.0} + {name="default_dig_oddly_breakable_by_hand", gain=0.5} table.place = table.place or {name="default_place_node_hard", gain=1.0} return table @@ -20,11 +20,11 @@ end function mcl_sounds.node_sound_stone_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_hard_footstep", gain=0.5} + {name="default_hard_footstep", gain=0.2} table.dug = table.dug or {name="default_hard_footstep", gain=1.0} table.dig = table.dig or - {name="default_dig_cracky", gain=1.0} + {name="default_dig_cracky", gain=0.5} mcl_sounds.node_sound_defaults(table) return table end @@ -32,13 +32,13 @@ end function mcl_sounds.node_sound_metal_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_metal_footstep", gain=0.5} + {name="default_metal_footstep", gain=0.2} table.dug = table.dug or - {name="default_dug_metal", gain=1.0} + {name="default_dug_metal", gain=0.5} table.dig = table.dig or - {name="default_dig_metal", gain=1.0} + {name="default_dig_metal", gain=0.5} table.place = table.place or - {name="default_place_node_metal", gain=1.0} + {name="default_place_node_metal", gain=0.5} mcl_sounds.node_sound_defaults(table) return table end @@ -46,11 +46,11 @@ end function mcl_sounds.node_sound_dirt_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_dirt_footstep", gain=1.0} + {name="default_dirt_footstep", gain=0.25} table.dug = table.dug or - {name="default_dirt_footstep", gain=1.5} + {name="default_dirt_footstep", gain=1.0} table.dig = table.dig or - {name="default_dig_crumbly", gain=1.0} + {name="default_dig_crumbly", gain=0.4} table.place = table.place or {name="default_place_node", gain=1.0} mcl_sounds.node_sound_defaults(table) @@ -60,11 +60,25 @@ end function mcl_sounds.node_sound_sand_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_sand_footstep", gain=0.5} + {name="default_sand_footstep", gain=0.05} table.dug = table.dug or - {name="default_sand_footstep", gain=1.0} + {name="default_sand_footstep", gain=0.15} table.dig = table.dig or - {name="default_dig_crumbly", gain=1.0} + {name="default_dig_crumbly", gain=0.4} + table.place = table.place or + {name="default_place_node", gain=1.0} + mcl_sounds.node_sound_defaults(table) + return table +end + +function mcl_sounds.node_sound_gravel_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name="default_gravel_footstep", gain=0.25} + table.dug = table.dug or + {name="default_gravel_dug", gain=1.0} + table.dig = table.dig or + {name="default_gravel_dig", gain=0.35} table.place = table.place or {name="default_place_node", gain=1.0} mcl_sounds.node_sound_defaults(table) @@ -78,21 +92,33 @@ function mcl_sounds.node_sound_snow_defaults(table) table.dug = table.dug or {name="pedology_snow_soft_footstep", gain=1.0} table.dig = table.dig or - {name="default_dig_crumbly", gain=1.0} + {name="pedology_snow_soft_footstep", gain=1.0} table.place = table.place or {name="default_place_node", gain=1.0} mcl_sounds.node_sound_defaults(table) return table end +function mcl_sounds.node_sound_ice_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name="default_ice_footstep", gain=0.15} + table.dug = table.dug or + {name="default_ice_dug", gain=0.5} + table.dig = table.dig or + {name="default_ice_dig", gain=0.5} + mcl_sounds.node_sound_defaults(table) + return table +end + function mcl_sounds.node_sound_wood_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_wood_footstep", gain=0.5} + {name="default_wood_footstep", gain=0.15} table.dug = table.dug or {name="default_wood_footstep", gain=1.0} table.dig = table.dig or - {name="default_dig_choppy", gain=1.0} + {name="default_dig_choppy", gain=0.4} mcl_sounds.node_sound_defaults(table) return table end @@ -128,11 +154,11 @@ end function mcl_sounds.node_sound_glass_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_glass_footstep", gain=0.5} + {name="default_glass_footstep", gain=0.3} table.dug = table.dug or {name="default_break_glass", gain=1.0} table.dig = table.dig or - {name="default_dig_cracky", gain=1.0} + {name="default_dig_cracky", gain=0.5} mcl_sounds.node_sound_defaults(table) return table end diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.1.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.1.ogg new file mode 100644 index 000000000..95fa6d4e7 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.2.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.2.ogg new file mode 100644 index 000000000..5d3a04443 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.3.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.3.ogg new file mode 100644 index 000000000..2bb0aceb5 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.1.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.1.ogg new file mode 100644 index 000000000..ffced27a6 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.2.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.2.ogg new file mode 100644 index 000000000..d9e801039 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.3.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.3.ogg new file mode 100644 index 000000000..7d19d4082 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.1.ogg index 84a197d2b..201aa3b2d 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.2.ogg index 2e23b8a2b..2667dbc21 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_grass_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_grass_footstep.1.ogg index 22d1ad6b8..a04cdb47c 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_grass_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_grass_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_grass_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_grass_footstep.2.ogg index 4ccd8a0f3..d193068d2 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_grass_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_grass_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_grass_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_grass_footstep.3.ogg index 20db84eda..e1897ea38 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_grass_footstep.3.ogg and b/mods/CORE/mcl_sounds/sounds/default_grass_footstep.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dig.1.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dig.1.ogg new file mode 100644 index 000000000..baf8fca71 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dig.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dig.2.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dig.2.ogg new file mode 100644 index 000000000..e0c0c50f9 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dig.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dug.1.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.1.ogg new file mode 100644 index 000000000..130343355 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dug.2.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.2.ogg new file mode 100644 index 000000000..ee5ed3309 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dug.3.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.3.ogg new file mode 100644 index 000000000..add4c54bf Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.1.ogg index 1748bc56a..0a08efa8d 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.2.ogg index fe39fd784..be52a8701 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.3.ogg index 5030e0607..a342787dd 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.3.ogg and b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_dig.1.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_dig.1.ogg new file mode 100644 index 000000000..97399c831 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_dig.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_dig.2.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_dig.2.ogg new file mode 100644 index 000000000..8a5da119b Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_dig.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_dig.3.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_dig.3.ogg new file mode 100644 index 000000000..765fb9be1 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_dig.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_dug.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_dug.ogg new file mode 100644 index 000000000..ae37673e0 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_dug.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.1.ogg new file mode 100644 index 000000000..c235f1eff Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.2.ogg new file mode 100644 index 000000000..61d2c990f Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.3.ogg new file mode 100644 index 000000000..2ecbb431c Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.1.ogg index 841286bdc..49fe89ba8 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.2.ogg index aa61ed338..878711d5b 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.3.ogg index 4cc1ca47a..2a566a83a 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.3.ogg and b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.1.ogg index 65b68c7e6..b92feabbb 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.2.ogg index 57f35f30a..6bc5da3e8 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.3.ogg new file mode 100644 index 000000000..880306fd3 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.3.ogg differ diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index a179d53e6..4684234e5 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -22,6 +22,29 @@ function table.update_nil(t, ...) return t end +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default",false) +local LOG_MODULE = "[MCL2]" +function mcl_util.mcl_log (message, module, bypass_default_logger) + local selected_module = LOG_MODULE + if module then + selected_module = module + end + if (bypass_default_logger or LOGGING_ON) and message then + minetest.log(selected_module .. " " .. message) + end +end + + +function mcl_util.file_exists(name) + if type(name) ~= "string" then return end + local f = io.open(name) + if not f then + return false + end + f:close() + return true +end + -- Based on minetest.rotate_and_place --[[ @@ -590,10 +613,12 @@ function mcl_util.get_object_name(object) end function mcl_util.replace_mob(obj, mob) + if not obj then return end local rot = obj:get_yaw() local pos = obj:get_pos() obj:remove() obj = minetest.add_entity(pos, mob) + if not obj then return end obj:set_yaw(rot) return obj end @@ -610,3 +635,96 @@ function mcl_util.get_pointed_thing(player, liquid) end end end + +-- This following part is 2 wrapper functions + helpers for +-- object:set_bones +-- and player:set_properties preventing them from being resent on +-- every globalstep when they have not changed. + +local function roundN(n, d) + if type(n) ~= "number" then return n end + local m = 10^d + return math.floor(n * m + 0.5) / m +end + +local function close_enough(a,b) + local rt=true + if type(a) == "table" and type(b) == "table" then + for k,v in pairs(a) do + if roundN(v,2) ~= roundN(b[k],2) then + rt=false + break + end + end + else + rt = roundN(a,2) == roundN(b,2) + end + return rt +end + +local function props_changed(props,oldprops) + local changed=false + local p={} + for k,v in pairs(props) do + if not close_enough(v,oldprops[k]) then + p[k]=v + changed=true + end + end + return changed,p +end + +--tests for roundN +local test_round1=15 +local test_round2=15.00199999999 +local test_round3=15.00111111 +local test_round4=15.00999999 + +assert(roundN(test_round1,2)==roundN(test_round1,2)) +assert(roundN(test_round1,2)==roundN(test_round2,2)) +assert(roundN(test_round1,2)==roundN(test_round3,2)) +assert(roundN(test_round1,2)~=roundN(test_round4,2)) + +-- tests for close_enough +local test_cb = {-0.35,0,-0.35,0.35,0.8,0.35} --collisionboxes +local test_cb_close = {-0.351213,0,-0.35,0.35,0.8,0.351212} +local test_cb_diff = {-0.35,0,-1.35,0.35,0.8,0.35} + +local test_eh = 1.65 --eye height +local test_eh_close = 1.65123123 +local test_eh_diff = 1.35 + +local test_nt = { r = 225, b = 225, a = 225, g = 225 } --nametag +local test_nt_diff = { r = 225, b = 225, a = 0, g = 225 } + +assert(close_enough(test_cb,test_cb_close)) +assert(not close_enough(test_cb,test_cb_diff)) +assert(close_enough(test_eh,test_eh_close)) +assert(not close_enough(test_eh,test_eh_diff)) +assert(not close_enough(test_nt,test_nt_diff)) --no floats involved here + +--tests for properties_changed +local test_properties_set1={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }} +local test_properties_set2={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 225, g = 225 }} + +local test_p1,_=props_changed(test_properties_set1,test_properties_set1) +local test_p2,_=props_changed(test_properties_set1,test_properties_set2) + +assert(not test_p1) +assert(test_p2) + +function mcl_util.set_properties(obj,props) + local changed,p=props_changed(props,obj:get_properties()) + if changed then + obj:set_properties(p) + end +end + +function mcl_util.set_bone_position(obj, bone, pos, rot) + local current_pos, current_rot = obj:get_bone_position(bone) + local pos_equal = not pos or vector.equals(vector.round(current_pos), vector.round(pos)) + local rot_equal = not rot or vector.equals(vector.round(current_rot), vector.round(rot)) + if not pos_equal or not rot_equal then + obj:set_bone_position(bone, pos or current_pos, rot or current_rot) + end +end diff --git a/mods/CORE/walkover/init.lua b/mods/CORE/walkover/init.lua index eb9de4218..552ac4ff4 100644 --- a/mods/CORE/walkover/init.lua +++ b/mods/CORE/walkover/init.lua @@ -28,11 +28,10 @@ end) local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime - if timer >= 0.3 then + if timer >= 0.6 then 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)) + local npos = vector.add(ppos, vector.new(0, -0.1, 0)) if npos then local node = get_node(npos) if node then diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index b7cc92775..b4d98b1e2 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -13,11 +13,21 @@ local function is_group(pos, group) end local is_water = flowlib.is_water +local function is_river_water(p) + local n = minetest.get_node(p).name + if n == "mclx_core:river_water_source" or n == "mclx_core:river_water_flowing" then + return true + end +end local function is_ice(pos) return is_group(pos, "ice") end +local function is_fire(pos) + return is_group(pos, "set_on_fire") +end + local function get_sign(i) if i == 0 then return 0 @@ -46,7 +56,7 @@ end local function set_attach(boat) boat._driver:set_attach(boat.object, "", - {x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0}) + {x = 0, y = 1.5, z = 1}, {x = 0, y = 0, z = 0}) end local function set_double_attach(boat) @@ -55,9 +65,13 @@ local function set_double_attach(boat) boat._passenger:set_attach(boat.object, "", {x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0}) end +local function set_choat_attach(boat) + boat._driver:set_attach(boat.object, "", + {x = 0, y = 1.5, z = 1}, {x = 0, y = 0, z = 0}) +end local function attach_object(self, obj) - if self._driver then + if self._driver and not self._inv_id then if self._driver:is_player() then self._passenger = obj else @@ -67,7 +81,11 @@ local function attach_object(self, obj) set_double_attach(self) else self._driver = obj - set_attach(self) + if self._inv_id then + set_choat_attach(self) + else + set_attach(self) + end end local visual_size = get_visual_size(obj) @@ -91,6 +109,7 @@ local function attach_object(self, obj) end local function detach_object(obj, change_pos) + if not obj or not obj:get_pos() then return end obj:set_detach() obj:set_properties({visual_size = get_visual_size(obj)}) if obj:is_player() then @@ -110,12 +129,14 @@ end local boat = { physical = true, + pointable = true, -- Warning: Do not change the position of the collisionbox top surface, -- lowering it causes the boat to fall through the world if underwater - collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, + collisionbox = {-0.5, -0.15, -0.5, 0.5, 0.55, 0.5}, + selectionbox = {-0.7, -0.15, -0.7, 0.7, 0.55, 0.7}, visual = "mesh", mesh = "mcl_boats_boat.b3d", - textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"}, + textures = { "mcl_boats_texture_oak_boat.png", "blank.png" }, visual_size = boat_visual_size, hp_max = boat_max_hp, damage_texture_modifier = "^[colorize:white:0", @@ -126,7 +147,7 @@ local boat = { _last_v = 0, -- Temporary speed variable _removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored _itemstring = "mcl_boats:boat", -- Itemstring of the boat item (implies boat type) - _animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling forwards + _animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling backwards _regen_timer = 0, _damage_anim = 0, } @@ -149,8 +170,14 @@ function boat.on_activate(self, staticdata, dtime_s) self._last_v = self._v self._itemstring = data.itemstring - while #data.textures < 5 do - table.insert(data.textures, data.textures[1]) + -- Update the texutes for existing old boat entity instances. + -- Maybe remove this in the future. + if #data.textures ~= 2 then + local has_chest = self._itemstring:find("chest") + data.textures = { + data.textures[1]:gsub("_chest", ""), + has_chest and "mcl_chests_normal.png" or "blank.png" + } end self.object:set_properties({textures = data.textures}) @@ -194,6 +221,8 @@ end function boat.on_step(self, dtime, moveresult) mcl_burning.tick(self.object, dtime, self) + -- mcl_burning.tick may remove object immediately + if not self.object:get_pos() then return end self._v = get_v(self.object:get_velocity()) * get_sign(self._v) local v_factor = 1 @@ -202,16 +231,21 @@ function boat.on_step(self, dtime, moveresult) local on_water = true local on_ice = false local in_water = is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z}) + local in_river_water = is_river_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z}) local waterp = {x=p.x, y=p.y-boat_y_offset - 0.1, z=p.z} if not is_water(waterp) then on_water = false if not in_water and is_ice(waterp) then on_ice = true + elseif is_fire({x=p.x, y=p.y-boat_y_offset, z=p.z}) then + boat.on_death(self, nil) + self.object:remove() + return else v_slowdown = 0.04 v_factor = 0.5 end - elseif in_water then + elseif in_water and not in_river_water then on_water = false in_water = true v_factor = 0.75 @@ -343,7 +377,18 @@ function boat.on_step(self, dtime, moveresult) else p.y = p.y + 1 local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian" - if is_water(p) or is_obsidian_boat then + if is_river_water(p) then + local y = self.object:get_velocity().y + if y >= 5 then + y = 5 + elseif y < 0 then + new_acce = {x = 0, y = 10, z = 0} + else + new_acce = {x = 0, y = 2, z = 0} + end + new_velo = get_velocity(self._v, self.object:get_yaw(), y) + self.object:set_pos(self.object:get_pos()) + elseif is_water(p) and not is_river_water(p) or is_obsidian_boat then -- Inside water: Slowly sink local y = self.object:get_velocity().y y = y - 0.01 @@ -383,13 +428,18 @@ end -- Register one entity for all boat types minetest.register_entity("mcl_boats:boat", boat) -local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "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", "mcl_core:obsidian" } -end -local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak", "obsidian" } +local cboat = table.copy(boat) +cboat.textures = { "mcl_boats_texture_oak_chest_boat.png", "mcl_chests_normal.png" } +cboat._itemstring = "mcl_boats:chest_boat" +cboat.collisionbox = {-0.5, -0.15, -0.5, 0.5, 0.75, 0.5} +cboat.selectionbox = {-0.7, -0.15, -0.7, 0.7, 0.75, 0.7} + +minetest.register_entity("mcl_boats:chest_boat", cboat) +mcl_entity_invs.register_inv("mcl_boats:chest_boat","Boat",27) + +local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "boat_obsidian", "boat_mangrove", "chest_boat", "chest_boat_spruce", "chest_boat_birch", "chest_boat_jungle", "chest_boat_acacia", "chest_boat_dark_oak", "chest_boat_mangrove" } +local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat"), S("Obsidian Boat"), S("Mangrove Boat"), S("Oak Chest Boat"), S("Spruce Chest Boat"), S("Birch Chest Boat"), S("Jungle Chest Boat"), S("Acacia Chest Boat"), S("Dark Oak Chest Boat"), S("Mangrove Chest Boat") } +local craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood", "mcl_core:obsidian", "mcl_mangrove:mangrove_wood" } for b=1, #boat_ids do local itemstring = "mcl_boats:"..boat_ids[b] @@ -405,6 +455,21 @@ for b=1, #boat_ids do end tt_help = S("Water vehicle") + local inventory_image + local texture + local id = boat_ids[b] + if id:find("chest") then + if id == "chest_boat" then id = "oak" end + local id = id:gsub("chest_boat_", "") + inventory_image = "mcl_boats_" .. id .. "_chest_boat.png" + texture = "mcl_boats_texture_" .. id .. "_boat.png" + else + if id == "boat" then id = "oak" end + local id = id:gsub("boat_", "") + inventory_image = "mcl_boats_" .. id .. "_boat.png" + texture = "mcl_boats_texture_" .. id .. "_boat.png" + end + minetest.register_craftitem(itemstring, { description = names[b], _tt_help = tt_help, @@ -412,7 +477,7 @@ for b=1, #boat_ids do _doc_items_entry_name = helpname, _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - inventory_image = "mcl_boats_"..images[b].."_boat.png", + inventory_image = inventory_image, liquids_pointable = true, groups = { boat = 1, transport = 1}, stack_max = 1, @@ -439,10 +504,15 @@ for b=1, #boat_ids do else pos = vector.add(pos, vector.multiply(dir, boat_y_offset_ground)) end - local boat = minetest.add_entity(pos, "mcl_boats:boat") - local texture = "mcl_boats_texture_"..images[b].."_boat.png" + local boat_ent = "mcl_boats:boat" + local chest_tex = "blank.png" + if itemstring:find("chest") then + boat_ent = "mcl_boats:chest_boat" + chest_tex = "mcl_chests_normal.png" + end + local boat = minetest.add_entity(pos, boat_ent) boat:get_luaentity()._itemstring = itemstring - boat:set_properties({textures = { texture, texture, texture, texture, texture }}) + boat:set_properties({ textures = { texture, chest_tex } }) boat:set_yaw(placer:get_look_horizontal()) if not minetest.is_creative_enabled(placer:get_player_name()) then itemstack:take_item() @@ -462,13 +532,22 @@ for b=1, #boat_ids do }) local c = craftstuffs[b] - minetest.register_craft({ - output = itemstring, - recipe = { - {c, "", c}, - {c, c, c}, - }, - }) + if not itemstring:find("chest") then + minetest.register_craft({ + output = itemstring:gsub(":boat",":chest_boat"), + recipe = { + {"mcl_chests:chest"}, + {itemstring}, + }, + }) + minetest.register_craft({ + output = itemstring, + recipe = { + {c, "", c}, + {c, c, c}, + }, + }) + end end minetest.register_craft({ diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr index 785d50146..f132f14df 100644 --- a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr @@ -9,4 +9,5 @@ Oak Boat=Bateau en Chêne Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Utilisez [Sneak] pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet. Spruce Boat=Bateau en Sapin Water vehicle=Véhicule aquatique -Sneak to dismount= \ No newline at end of file +Sneak to dismount=Se baisser pour descendre +Obsidian Boat=Bateau en Obsidienne \ No newline at end of file diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.ja.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.ja.tr new file mode 100644 index 000000000..05ff22b1b --- /dev/null +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.ja.tr @@ -0,0 +1,13 @@ +# textdomain: mcl_boats +Acacia Boat=アカシアのボート +Birch Boat=シラカバのボート +Boat=ボート +Boats are used to travel on the surface of water.=ボートは、水面を移動するために使われます。 +Dark Oak Boat=ダークオークのボート +Jungle Boat=ジャングルのボート +Oak Boat=オークのボート +Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=水源を右クリックすると、ボートが配置されます。ボートを右クリックすると、乗り込みます。[左][右]で舵取り、[前]で加速、[後]で減速または後退します。[スニーク]でボートから離れ、ボートをパンチするとアイテムとしてドロップします。 +Spruce Boat=トウヒのボート +Water vehicle=水上用の乗物 +Sneak to dismount=スニークで降りる +Obsidian Boat=黒曜石のボート \ No newline at end of file diff --git a/mods/ENTITIES/mcl_boats/locale/template.txt b/mods/ENTITIES/mcl_boats/locale/template.txt index ac52bc19f..c071f3ed4 100644 --- a/mods/ENTITIES/mcl_boats/locale/template.txt +++ b/mods/ENTITIES/mcl_boats/locale/template.txt @@ -10,3 +10,4 @@ Rightclick on a water source to place the boat. Rightclick the boat to enter it. Spruce Boat= Water vehicle= Sneak to dismount= +Obsidian Boat= \ No newline at end of file diff --git a/mods/ENTITIES/mcl_boats/mod.conf b/mods/ENTITIES/mcl_boats/mod.conf index 61463b6ec..fcbe3f2f6 100644 --- a/mods/ENTITIES/mcl_boats/mod.conf +++ b/mods/ENTITIES/mcl_boats/mod.conf @@ -1,7 +1,5 @@ name = mcl_boats author = PilzAdam description = Adds drivable boats. -depends = mcl_player, flowlib, mcl_title +depends = mcl_player, flowlib, mcl_title, mcl_entity_invs optional_depends = mcl_core, doc_identifier - - diff --git a/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d b/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d index 6c9c31469..344bb3e70 100644 Binary files a/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d and b/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_acacia_chest_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_acacia_chest_boat.png new file mode 100644 index 000000000..5fb44b766 Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_acacia_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_birch_chest_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_birch_chest_boat.png new file mode 100644 index 000000000..c5671285f Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_birch_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_dark_oak_chest_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_dark_oak_chest_boat.png new file mode 100644 index 000000000..28ab392da Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_dark_oak_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_jungle_chest_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_jungle_chest_boat.png new file mode 100644 index 000000000..304fd771d Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_jungle_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_mangrove_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_mangrove_boat.png new file mode 100644 index 000000000..f1f0d2506 Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_mangrove_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_mangrove_chest_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_mangrove_chest_boat.png new file mode 100644 index 000000000..ec2acd07f Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_mangrove_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_oak_chest_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_oak_chest_boat.png new file mode 100644 index 000000000..0c7c2e0e2 Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_oak_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_spruce_chest_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_spruce_chest_boat.png new file mode 100644 index 000000000..e7f043e56 Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_spruce_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_mangrove_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_mangrove_boat.png new file mode 100644 index 000000000..435db3966 Binary files /dev/null and b/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_mangrove_boat.png differ diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 885875aca..df0953398 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -1,3 +1,5 @@ +local enable_damage = minetest.settings:get_bool("enable_damage") + function mcl_burning.get_storage(obj) return obj:is_player() and mcl_burning.storage[obj] or obj:get_luaentity() end @@ -77,7 +79,7 @@ end -- 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. +-- If obj is dead, fireproof or enable_damage is disabled, this function does nothing. -- function mcl_burning.set_on_fire(obj, burn_time) if obj:get_hp() < 0 then @@ -89,8 +91,9 @@ function mcl_burning.set_on_fire(obj, burn_time) return end - if obj:is_player() and minetest.is_creative_enabled(obj:get_player_name()) then + if obj:is_player() and not enable_damage then burn_time = 0 + return else local max_fire_prot_lvl = 0 local inv = mcl_util.get_inventory(obj) @@ -134,6 +137,7 @@ function mcl_burning.set_on_fire(obj, burn_time) end function mcl_burning.extinguish(obj) + if not obj:get_pos() then return end if mcl_burning.is_burning(obj) then local storage = mcl_burning.get_storage(obj) if obj:is_player() then diff --git a/mods/ENTITIES/mcl_burning/mod.conf b/mods/ENTITIES/mcl_burning/mod.conf index c64959cbb..651698fc7 100644 --- a/mods/ENTITIES/mcl_burning/mod.conf +++ b/mods/ENTITIES/mcl_burning/mod.conf @@ -1,3 +1,4 @@ name = mcl_burning description = Burning Objects for MineClone2 author = Fleckenstein +depends = mcl_weather \ No newline at end of file diff --git a/mods/ENTITIES/mcl_dripping/README.md b/mods/ENTITIES/mcl_dripping/README.md new file mode 100644 index 000000000..d6ff75ff1 --- /dev/null +++ b/mods/ENTITIES/mcl_dripping/README.md @@ -0,0 +1,36 @@ +# mcl_dripping + +Dripping Mod by kddekadenz, modified for MineClone 2 by Wuzzy, NO11 and AFCM + +## Manual + +- drops are generated rarely under solid nodes +- they will stay some time at the generated block and than they fall down +- when they collide with the ground, a sound is played and they are destroyed + +Water and Lava have builtin drops registered. + +## License + +code & sounds: CC0 + +## API + +```lua +mcl_dripping.register_drop({ + -- The group the liquid's nodes belong to + liquid = "water", + -- The texture used (particles will take a random 2x2 area of it) + texture = "default_water_source_animated.png", + -- Define particle glow, ranges from `0` to `minetest.LIGHT_MAX` + light = 1, + -- The nodes (or node group) the particles will spawn under + nodes = { "group:opaque", "group:leaves" }, + -- The sound that will be played then the particle detaches from the roof, see SimpleSoundSpec in lua_api.txt + sound = "drippingwater_drip", + -- The interval for the ABM to run + interval = 60, + -- The chance of the ABM + chance = 10, +}) +``` diff --git a/mods/ENTITIES/mcl_dripping/init.lua b/mods/ENTITIES/mcl_dripping/init.lua index 57ba7ecfe..b5a5043b7 100644 --- a/mods/ENTITIES/mcl_dripping/init.lua +++ b/mods/ENTITIES/mcl_dripping/init.lua @@ -1,66 +1,101 @@ -- Dripping Water Mod -- by kddekadenz +-- License of code, textures & sounds: CC0 local math = math --- License of code, textures & sounds: CC0 +mcl_dripping = {} -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, - }) + +---@param pos Vector +---@param liquid string +---@param sound SimpleSoundSpec +---@param interval integer +---@param texture string +local function make_drop(pos, liquid, sound, interval, texture) + local pt = { + velocity = vector.zero(), + collision_removal = false, + } + + local t = math.random() + math.random(1, interval) + + minetest.after(t, function() + local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100 + + pt.pos = vector.offset(pos, x, -0.52, z) + pt.acceleration = vector.zero() + pt.collisiondetection = false + pt.expirationtime = t + + pt.texture = "[combine:2x2:" .. + -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=" .. texture + + minetest.add_particle(pt) + + minetest.after(t, function() + pt.acceleration = vector.new(0, -5, 0) + pt.collisiondetection = true + pt.expirationtime = math.random() + math.random(1, interval / 2) + + minetest.add_particle(pt) + + minetest.sound_play(sound, { pos = pos, gain = 0.5, max_hear_distance = 8 }, + true) + end) + end) +end + +---@class mcl_dripping_drop_definition +---@field liquid string The group the liquid's nodes belong to +---@field texture string The texture used (particles will take a random 2x2 area of it) +---@field light integer Define particle glow, ranges from `0` to `minetest.LIGHT_MAX` +---@field nodes string[] The nodes (or node group) the particles will spawn under +---@field interval integer The interval for the ABM to run +---@field chance integer The chance of the ABM +---@field sound SimpleSoundSpec The sound that will be played then the particle detaches from the roof + +---@param def mcl_dripping_drop_definition +function mcl_dripping.register_drop(def) minetest.register_abm({ label = "Create drops", - nodenames = nodes, - neighbors = {"group:" .. liquid}, - interval = 2, - chance = 22, + nodenames = def.nodes, + neighbors = { "group:" .. def.liquid }, + interval = def.interval, + chance = def.chance, 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) + local below = minetest.get_node(vector.offset(pos,0,-1,0)).name + if below ~= "air" then return end + local r = math.ceil(def.interval / 20) + local nn = minetest.find_nodes_in_area(vector.offset(pos, -r, 0, -r), vector.offset(pos, r, 0, r), def.nodes) + --start a bunch of particle cycles to be able to get away + --with longer abm cycles + table.shuffle(nn) + for i = 1, math.random(#nn) do + if minetest.get_item_group(minetest.get_node(vector.offset(nn[i], 0, 1, 0)).name, def.liquid) ~= 0 then + make_drop(nn[i], def.liquid, def.sound, def.interval, def.texture) + end end end, }) end -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 +mcl_dripping.register_drop({ + liquid = "water", + texture = "default_water_source_animated.png", + light = 1, + nodes = { "group:opaque", "group:leaves" }, + sound = "drippingwater_drip", + interval = 60.3, + chance = 10, +}) + +mcl_dripping.register_drop({ + liquid = "lava", + texture = "default_lava_source_animated.png", + light = math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), + nodes = { "group:opaque" }, + sound = "drippingwater_lavadrip", + interval = 110.1, + chance = 10, +}) diff --git a/mods/ENTITIES/mcl_dripping/readme.txt b/mods/ENTITIES/mcl_dripping/readme.txt deleted file mode 100644 index afe35608e..000000000 --- a/mods/ENTITIES/mcl_dripping/readme.txt +++ /dev/null @@ -1,29 +0,0 @@ -Dripping Mod -by kddekadenz - -modified for MineClone 2 by Wuzzy and NO11 - - -Installing instructions: - - 1. Copy the mcl_dripping mod folder into games/gamemode/mods - - 2. Start game and enjoy :) - - -Manual: - --> drops are generated rarely under solid nodes --> they will stay some time at the generated block and than they fall down --> when they collide with the ground, a sound is played and they are destroyed - - -License: - -code & sounds: CC0 - - -Changelog: - -16.04.2012 - first release -28.04.2012 - drops are now 3D; added lava drops; fixed generating of drops (not at edges now) diff --git a/mods/ENTITIES/mcl_entity_invs/api.txt b/mods/ENTITIES/mcl_entity_invs/api.txt new file mode 100644 index 000000000..98cee1a23 --- /dev/null +++ b/mods/ENTITIES/mcl_entity_invs/api.txt @@ -0,0 +1,13 @@ +mcl_entity_invs +=============== + +Inventories for your entities. It's simple. Depend on mcl_entity_invs and register your entity like so: + +* mcl_entity_invs.register_inv("entity:name","Title shown in formspec",inventory_size,disable_on_righclick) + *If disable_on_righclick is true other mods can handle when to show the inventory themselves + * The inventory size can be set dynamically by initializing it with an explicit nil + +* mcl_entity_invs.show_inv_form(entity,clicker,[formspec text]) + * formspec_text is an additional text that is put after the title + +It works by setting up a detached inventory per entity which is accessed by an id/hash generated from the entities position at creation, the progressed gametime at creation and a random salt. diff --git a/mods/ENTITIES/mcl_entity_invs/init.lua b/mods/ENTITIES/mcl_entity_invs/init.lua new file mode 100644 index 000000000..35af491e1 --- /dev/null +++ b/mods/ENTITIES/mcl_entity_invs/init.lua @@ -0,0 +1,210 @@ +mcl_entity_invs = {} + +local open_invs = {} + +local function mcl_log (message) + mcl_util.mcl_log (message, "[Entity Invs]") +end + +local function check_distance(inv,player,count) + for _,o in pairs(minetest.get_objects_inside_radius(player:get_pos(),5)) do + local l = o:get_luaentity() + if l and l._inv_id and inv:get_location().name == l._inv_id then return count end + end + return 0 +end + +local inv_callbacks = { + allow_take = function(inv, listname, index, stack, player) + return check_distance(inv,player,stack:get_count()) + end, + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return check_distance(inv,player,count) + end, + allow_put = function(inv, listname, index, stack, player) + return check_distance(inv,player,stack:get_count()) + end, +} + +function mcl_entity_invs.load_inv(ent,size) + mcl_log("load_inv") + if not ent._inv_id then return end + mcl_log("load_inv 2") + local inv = minetest.get_inventory({type="detached", name=ent._inv_id}) + if not inv then + mcl_log("load_inv 3") + inv = minetest.create_detached_inventory(ent._inv_id, inv_callbacks) + inv:set_size("main", size) + if ent._items then + inv:set_list("main",ent._items) + end + else + mcl_log("load_inv 4") + end + return inv +end + +function mcl_entity_invs.save_inv(ent) + if ent._inv then + ent._items = {} + for i,it in ipairs(ent._inv:get_list("main")) do + ent._items[i] = it:to_string() + end + minetest.remove_detached_inventory(ent._inv_id) + ent._inv = nil + end +end + +local function load_default_formspec (ent, text) + text = text or "" + + local invent_size = ent._inv_size + local div_by_two = invent_size % 2 == 0 + local div_by_three = invent_size % 3 == 0 + + --mcl_log("Div by 3: ".. tostring(div_by_three)) + --mcl_log("Div by 2: ".. tostring(div_by_two)) + --mcl_log("invent_size: ".. tostring(invent_size)) + local rows = 3 + if invent_size > 18 or (div_by_three == true and invent_size > 8) then + --mcl_log("Div by 3") + rows = 3 + elseif (div_by_two == true and invent_size > 3) or invent_size > 9 then + --mcl_log("Div by 2") + rows = 2 + else + --mcl_log("Not div by 2 or 3") + rows = 1 + end + + --local rows = 3 + local cols = (math.ceil(ent._inv_size/rows)) + local spacing = (9 - cols) / 2 + + local formspec = "size[9,8.75]" + .. "label[0,0;" .. minetest.formspec_escape( + minetest.colorize("#313131", ent._inv_title .. " ".. text)) .. "]" + .. "list[detached:"..ent._inv_id..";main;"..spacing..",0.5;"..cols..","..rows..";]" + .. mcl_formspec.get_itemslot_bg(spacing,0.5,cols,rows) + .. "label[0,4.0;" .. minetest.formspec_escape( + minetest.colorize("#313131", "Inventory")) .. "]" + .. "list[current_player;main;0,4.5;9,3;9]" + .. mcl_formspec.get_itemslot_bg(0,4.5,9,3) + .. "list[current_player;main;0,7.74;9,1;]" + .. mcl_formspec.get_itemslot_bg(0,7.74,9,1) + .. "listring[detached:"..ent._inv_id..";main]" + .. "listring[current_player;main]" + return formspec +end + + +function mcl_entity_invs.show_inv_form(ent,player,text) + if not ent._inv_id then return end + if not open_invs[ent] then + open_invs[ent] = 0 + end + ent._inv = mcl_entity_invs.load_inv(ent,ent._inv_size) + open_invs[ent] = open_invs[ent] + 1 + + local playername = player:get_player_name() + + minetest.show_formspec(playername, ent._inv_id, load_default_formspec (ent, text)) +end + +local function drop_inv(ent) + if not ent._items then return end + local pos = ent.object:get_pos() + for i,it in pairs(ent._items) do + local p = vector.add(pos,vector.new(math.random() - 0.5, math.random()-0.5, math.random()-0.5)) + minetest.add_item(p,it) + end + ent._items = nil +end + +local function on_remove(self,killer,oldf) + mcl_entity_invs.save_inv(self) + drop_inv(self) + if oldf then return oldf(self,killer) end +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + for k,v in pairs(open_invs) do + if formname == k._inv_id then + open_invs[k] = open_invs[k] - 1 + if open_invs[k] < 1 then + mcl_entity_invs.save_inv(k) + open_invs[k] = nil + end + end + end +end) + +function mcl_entity_invs.register_inv(entity_name,show_name,size,no_on_righclick,no_sneak) + assert(minetest.registered_entities[entity_name],"mcl_entity_invs.register_inv called with invalid entity: "..tostring(entity_name)) + minetest.registered_entities[entity_name]._inv_size = size + minetest.registered_entities[entity_name]._inv_title = show_name + + local old_oa = minetest.registered_entities[entity_name].on_activate + minetest.registered_entities[entity_name].on_activate = function(self,staticdata,dtime_s) + local r + if old_oa then r=old_oa(self,staticdata,dtime_s) end + local d = minetest.deserialize(staticdata) + if type(d) == "table" and d._inv_id then + self._inv_id = d._inv_id + self._items = d._items + self._inv_size = d._inv_size + else + self._inv_id="entity_inv_"..minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random())) + --gametime and position for collision safety and math.random salt to protect against position brute-force + end + return r + end + if not no_on_righclick then + local old_rc = minetest.registered_entities[entity_name].on_rightclick + minetest.registered_entities[entity_name].on_rightclick = function(self,clicker) + if no_sneak or clicker:get_player_control().sneak then + mcl_entity_invs.show_inv_form(self,clicker,"") + if not no_sneak then return end + end + if old_rc then return old_rc(self,clicker) end + end + end + + local old_gsd = minetest.registered_entities[entity_name].get_staticdata + minetest.registered_entities[entity_name].get_staticdata = function(self) + local old_sd = old_gsd(self) + local d = minetest.deserialize(old_sd) + assert(type(d) == "table","mcl_entity_invs currently only works with entities that return a (serialized) table in get_staticdata. "..tostring(self.name).." returned: "..tostring(old_sd)) + d._inv_id = self._inv_id + d._inv_size = self._inv_size + d._items = {} + if self._items then + for i,it in ipairs(self._items) do + d._items[i] = it + end + end + return minetest.serialize(d) + end + + local old_ode = minetest.registered_entities[entity_name].on_deactivate + minetest.registered_entities[entity_name].on_deactivate = function(self,removal) + mcl_entity_invs.save_inv(self) + if removal then + on_remove(self) + end + if old_ode then return old_ode(self,removal) end + end + + local old_od = minetest.registered_entities[entity_name].on_death + minetest.registered_entities[entity_name].on_death = function(self,killer) + if not self.is_mob then + on_remove(self,killer,old_od) + end + end + local old_odi = minetest.registered_entities[entity_name].on_die + minetest.registered_entities[entity_name].on_die = function(self,killer) + if self.is_mob then + on_remove(self,killer,old_od) + end + end +end diff --git a/mods/ENTITIES/mcl_entity_invs/mod.conf b/mods/ENTITIES/mcl_entity_invs/mod.conf new file mode 100644 index 000000000..8e94d6b1e --- /dev/null +++ b/mods/ENTITIES/mcl_entity_invs/mod.conf @@ -0,0 +1,3 @@ +name = mcl_entity_invs +author = cora +depends = mcl_formspec diff --git a/mods/ENTITIES/mcl_item_entity/README.txt b/mods/ENTITIES/mcl_item_entity/README.txt index 41e9e6e57..d39ec0ba9 100644 --- a/mods/ENTITIES/mcl_item_entity/README.txt +++ b/mods/ENTITIES/mcl_item_entity/README.txt @@ -25,4 +25,10 @@ http://minetest.net/ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. You just DO WHAT THE FUCK YOU WANT TO. + 0. You just DO WHAT THE FUCK YOU WANT TO. + +--------- + +Alterations and contributions are released under GNU GPLv3 after 11/11/2022 and for contributors: + +AncientMariner/ancientmarinerdev \ No newline at end of file diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 5d86071eb..60cfe9dd9 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -6,22 +6,25 @@ local pool = {} local tick = false + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_item_entities", false) +local function mcl_log(message) + if LOGGING_ON then + mcl_util.mcl_log(message, "[Item Entities]", true) + end +end + minetest.register_on_joinplayer(function(player) - local name - name = player:get_player_name() - pool[name] = 0 + pool[player:get_player_name()] = 0 end) minetest.register_on_leaveplayer(function(player) - local name - name = player:get_player_name() - pool[name] = nil + pool[player:get_player_name()] = nil end) - local has_awards = minetest.get_modpath("awards") -local mcl_item_entity = {} +mcl_item_entity = {} --basic settings local item_drop_settings = {} --settings table @@ -36,22 +39,29 @@ item_drop_settings.random_item_velocity = true --this sets random item velocity item_drop_settings.drop_single_item = false --if true, the drop control drops 1 item instead of the entire stack, and sneak+drop drops the stack -- drop_single_item is disabled by default because it is annoying to throw away items from the intentory screen -item_drop_settings.magnet_time = 0.75 -- how many seconds an item follows the player before giving up +item_drop_settings.magnet_time = 0.75 -- how many seconds an item follows the player before giving up local function get_gravity() return tonumber(minetest.settings:get("movement_gravity")) or 9.81 end -local registered_pickup_achievement = {} +mcl_item_entity.registered_pickup_achievement = {} ---TODO: remove limitation of 1 award per itemname +---Register an achievement that will be unlocked on pickup. +--- +---TODO: remove limitation of 1 award per itemname +---@param itemname string +---@param award string function mcl_item_entity.register_pickup_achievement(itemname, award) if not has_awards then - minetest.log("warning", "[mcl_item_entity] Trying to register pickup achievement ["..award.."] for ["..itemname.."] while awards missing") - elseif registered_pickup_achievement[itemname] then - minetest.log("error", "[mcl_item_entity] Trying to register already existing pickup achievement ["..award.."] for ["..itemname.."]") + minetest.log("warning", + "[mcl_item_entity] Trying to register pickup achievement [" .. award .. "] for [" .. + itemname .. "] while awards missing") + elseif mcl_item_entity.registered_pickup_achievement[itemname] then + minetest.log("error", + "[mcl_item_entity] Trying to register already existing pickup achievement [" .. award .. "] for [" .. itemname .. "]") else - registered_pickup_achievement[itemname] = award + mcl_item_entity.registered_pickup_achievement[itemname] = award end end @@ -59,12 +69,18 @@ mcl_item_entity.register_pickup_achievement("tree", "mcl:mineWood") mcl_item_entity.register_pickup_achievement("mcl_mobitems:blaze_rod", "mcl:blazeRod") mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow") mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds") +mcl_item_entity.register_pickup_achievement("mcl_core:crying_obsidian", "mcl:whosCuttingOnions") +mcl_item_entity.register_pickup_achievement("mcl_nether:ancient_debris", "mcl:hiddenInTheDepths") +mcl_item_entity.register_pickup_achievement("mcl_end:dragon_egg", "mcl:PickUpDragonEgg") +mcl_item_entity.register_pickup_achievement("mcl_armor:elytra", "mcl:skysTheLimit") +---@param object ObjectRef +---@param player ObjectRef local function check_pickup_achievements(object, player) if has_awards then local itemname = ItemStack(object:get_luaentity().itemstring):get_name() local playername = player:get_player_name() - for name,award in pairs(registered_pickup_achievement) do + for name, award in pairs(mcl_item_entity.registered_pickup_achievement) do if itemname == name or minetest.get_item_group(itemname, name) ~= 0 then awards.unlock(playername, award) end @@ -72,17 +88,23 @@ local function check_pickup_achievements(object, player) end end +---@param object ObjectRef +---@param luaentity Luaentity +---@param ignore_check? boolean local function enable_physics(object, luaentity, ignore_check) if luaentity.physical_state == false or ignore_check == true then luaentity.physical_state = true object:set_properties({ physical = true }) - object:set_velocity({x=0,y=0,z=0}) - object:set_acceleration({x=0,y=-get_gravity(),z=0}) + object:set_acceleration(vector.new(0, -get_gravity(), 0)) end end +---@param object ObjectRef +---@param luaentity Luaentity +---@param ignore_check? boolean +---@param reset_movement? boolean local function disable_physics(object, luaentity, ignore_check, reset_movement) if luaentity.physical_state == true or ignore_check == true then luaentity.physical_state = false @@ -90,17 +112,16 @@ local function disable_physics(object, luaentity, ignore_check, reset_movement) physical = false }) if reset_movement ~= false then - object:set_velocity({x=0,y=0,z=0}) - object:set_acceleration({x=0,y=0,z=0}) + object:set_velocity(vector.zero()) + object:set_acceleration(vector.zero()) end end end - -minetest.register_globalstep(function(dtime) +minetest.register_globalstep(function(_) tick = not tick - for _,player in pairs(minetest.get_connected_players()) do + for _, player in pairs(minetest.get_connected_players()) do if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then local name = player:get_player_name() @@ -112,7 +133,7 @@ minetest.register_globalstep(function(dtime) pos = pos, gain = 0.3, max_hear_distance = 16, - pitch = math.random(70,110)/100 + pitch = math.random(70, 110) / 100 }) if pool[name] > 6 then pool[name] = 6 @@ -122,15 +143,18 @@ minetest.register_globalstep(function(dtime) end - local inv = player:get_inventory() - local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} + local checkpos = vector.offset(pos, 0, item_drop_settings.player_collect_height, 0) --magnet and collection - for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do - if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then + for _, object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do + if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and + object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer + and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then - if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then + if object:get_luaentity()._magnet_timer >= 0 and + object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and + inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then -- Collection if not object:get_luaentity()._removed then @@ -145,8 +169,8 @@ minetest.register_globalstep(function(dtime) object:get_luaentity().target = checkpos object:get_luaentity()._removed = true - object:set_velocity({x=0,y=0,z=0}) - object:set_acceleration({x=0,y=0,z=0}) + object:set_velocity(vector.zero()) + object:set_acceleration(vector.zero()) object:move_to(checkpos) @@ -166,7 +190,6 @@ minetest.register_globalstep(function(dtime) local entity = object:get_luaentity() entity.collector = player:get_player_name() entity.collected = true - end end @@ -181,6 +204,11 @@ end) local tmp_id = 0 +---@param drop string|drop_definition +---@param toolname string +---@param param2 integer +---@param paramtype2 paramtype2 +---@return string[] local function get_drops(drop, toolname, param2, paramtype2) tmp_id = tmp_id + 1 local tmp_node_name = "mcl_item_entity:" .. tmp_id @@ -189,7 +217,7 @@ local function get_drops(drop, toolname, param2, paramtype2) drop = drop, paramtype2 = paramtype2 } - local drops = minetest.get_node_drops({name = tmp_node_name, param2 = param2}, toolname) + local drops = minetest.get_node_drops({ name = tmp_node_name, param2 = param2 }, toolname) minetest.registered_nodes[tmp_node_name] = nil return drops end @@ -252,7 +280,7 @@ function minetest.handle_node_drops(pos, drops, digger) * table: Drop every itemstring in this table when dug by shears _mcl_silk_touch_drop ]] - local enchantments = tool and mcl_enchanting.get_enchantments(tool, "silk_touch") + local enchantments = tool and mcl_enchanting.get_enchantments(tool) local silk_touch_drop = false local nodedef = minetest.registered_nodes[dug_node.name] @@ -281,7 +309,8 @@ function minetest.handle_node_drops(pos, drops, digger) local max_count = fortune_drop.max_count + fortune_level * (fortune_drop.factor or 1) local chance = fortune_drop.chance or fortune_drop.get_chance and fortune_drop.get_chance(fortune_level) if not chance or math.random() < chance then - drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count, fortune_drop.cap) + drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count, + fortune_drop.cap) elseif fortune_drop.override then drops = {} end @@ -293,13 +322,13 @@ function minetest.handle_node_drops(pos, drops, digger) end if digger and mcl_experience.throw_xp and not silk_touch_drop then - local experience_amount = minetest.get_item_group(dug_node.name,"xp") + local experience_amount = minetest.get_item_group(dug_node.name, "xp") if experience_amount > 0 then mcl_experience.throw_xp(pos, experience_amount) end end - for _,item in ipairs(drops) do + for _, item in ipairs(drops) do local count if type(item) == "string" then count = ItemStack(item):get_count() @@ -308,7 +337,7 @@ function minetest.handle_node_drops(pos, drops, digger) end local drop_item = ItemStack(item) drop_item:set_count(1) - for i=1,count do + for i = 1, count do local dpos = table.copy(pos) -- Apply offset for plantlike_rooted nodes because of their special shape if nodedef and nodedef.drawtype == "plantlike_rooted" and nodedef.walkable then @@ -317,18 +346,14 @@ function minetest.handle_node_drops(pos, drops, digger) -- Spawn item and apply random speed local obj = minetest.add_item(dpos, drop_item) if obj then - local x = math.random(1, 5) - if math.random(1,2) == 1 then - x = -x + -- set the velocity multiplier to the stored amount or if the game dug this node, apply a bigger velocity + local v = 1 + if digger and digger:is_player() then + obj:get_luaentity().random_velocity = 1 + else + obj:get_luaentity().random_velocity = 1.6 end - local z = math.random(1, 5) - if math.random(1,2) == 1 then - z = -z - end - obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z}) - obj:get_luaentity().age = item_drop_settings.dug_buffer - obj:get_luaentity()._insta_collect = false end end @@ -339,7 +364,7 @@ end function minetest.item_drop(itemstack, dropper, pos) if dropper and dropper:is_player() then local v = dropper:get_look_dir() - local p = {x=pos.x, y=pos.y+1.2, z=pos.z} + local p = vector.offset(pos, 0, 1.2, 0) local cs = itemstack:get_count() if dropper:get_player_control().sneak then cs = 1 @@ -347,9 +372,9 @@ function minetest.item_drop(itemstack, dropper, pos) local item = itemstack:take_item(cs) local obj = minetest.add_item(p, item) if obj then - v.x = v.x*4 - v.y = v.y*4 + 2 - v.z = v.z*4 + v.x = v.x * 4 + v.y = v.y * 4 + 2 + v.z = v.z * 4 obj:set_velocity(v) -- Force collection delay obj:get_luaentity()._insta_collect = false @@ -367,27 +392,137 @@ 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 }) + 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 }) + table.insert(o, { [one] = -1, y = 0, [zero] = 0 }) + table.insert(o, { [one] = 1, y = 0, [zero] = 0 }) end return o end +local function hopper_take_item(self, pos) + --mcl_log("self.itemstring: ".. self.itemstring) + --mcl_log("self.itemstring: ".. minetest.pos_to_string(pos)) + + local objs = minetest.get_objects_inside_radius(pos, 2) + + if objs and self.itemstring then + --mcl_log("there is an itemstring. Number of objs: ".. #objs) + + for k, v in pairs(objs) do + local ent = v:get_luaentity() + + -- Don't forget actual hoppers + if ent and ent.name == "mcl_minecarts:hopper_minecart" then + local taken_items = false + + mcl_log("ent.name: " .. tostring(ent.name)) + mcl_log("ent pos: " .. tostring(ent.object:get_pos())) + + local inv = mcl_entity_invs.load_inv(ent, 5) + + if not inv then + mcl_log("No inv") + return false + end + + local current_itemstack = ItemStack(self.itemstring) + + mcl_log("inv. size: " .. ent._inv_size) + if inv:room_for_item("main", current_itemstack) then + mcl_log("Room") + inv:add_item("main", current_itemstack) + self.object:get_luaentity().itemstring = "" + self.object:remove() + taken_items = true + else + mcl_log("no Room") + end + + if not taken_items then + local items_remaining = current_itemstack:get_count() + + -- This will take part of a floating item stack if no slot can hold the full amount + for i = 1, ent._inv_size, 1 do + local stack = inv:get_stack("main", i) + + mcl_log("i: " .. tostring(i)) + mcl_log("Items remaining: " .. items_remaining) + mcl_log("Name: " .. tostring(stack:get_name())) + + if current_itemstack:get_name() == stack:get_name() then + mcl_log("We have a match. Name: " .. tostring(stack:get_name())) + + local room_for = stack:get_stack_max() - stack:get_count() + mcl_log("Room for: " .. tostring(room_for)) + + if room_for == 0 then + -- Do nothing + mcl_log("No room") + elseif room_for < items_remaining then + mcl_log("We have more items remaining than space") + + items_remaining = items_remaining - room_for + stack:set_count(stack:get_stack_max()) + inv:set_stack("main", i, stack) + taken_items = true + else + local new_stack_size = stack:get_count() + items_remaining + stack:set_count(new_stack_size) + mcl_log("We have more than enough space. Now holds: " .. new_stack_size) + + inv:set_stack("main", i, stack) + items_remaining = 0 + + self.object:get_luaentity().itemstring = "" + self.object:remove() + + taken_items = true + break + end + + mcl_log("Count: " .. tostring(stack:get_count())) + mcl_log("stack max: " .. tostring(stack:get_stack_max())) + --mcl_log("Is it empty: " .. stack:to_string()) + end + + if i == ent._inv_size and taken_items then + mcl_log("We are on last item and still have items left. Set final stack size: " .. items_remaining) + current_itemstack:set_count(items_remaining) + --mcl_log("Itemstack2: " .. current_itemstack:to_string()) + self.itemstring = current_itemstack:to_string() + end + end + end + + --Add in, and delete + if taken_items then + mcl_log("Saving") + mcl_entity_invs.save_inv(ent) + return taken_items + else + mcl_log("No need to save") + end + end + end + end + + return false +end + minetest.register_entity(":__builtin:item", { initial_properties = { hp_max = 1, physical = true, collide_with_objects = false, - collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3}, + collisionbox = { -0.3, -0.3, -0.3, 0.3, 0.3, 0.3 }, pointable = false, visual = "wielditem", - visual_size = {x = 0.4, y = 0.4}, - textures = {""}, - spritediv = {x = 1, y = 1}, - initial_sprite_basepos = {x = 0, y = 0}, + visual_size = { x = 0.4, y = 0.4 }, + textures = { "" }, + spritediv = { x = 1, y = 1 }, + initial_sprite_basepos = { x = 0, y = 0 }, is_visible = false, infotext = "", }, @@ -407,9 +542,33 @@ minetest.register_entity(":__builtin:item", { -- Number of seconds this item entity has existed so far age = 0, + -- Multiplier for initial random velocity when the item is spawned + random_velocity = 1, + -- How old it has become in the collection animation collection_age = 0, + -- Function to apply a random velocity + apply_random_vel = function(self, speed) + if not self or not self.object or not self.object:get_luaentity() then + return + end + -- if you passed a value then use that for the velocity multiplier + if speed ~= nil then self.random_velocity = speed end + + local vel = self.object:get_velocity() + if vel and vel.x == 0 and vel.z == 0 and self.random_velocity > 0 then + local v = self.random_velocity + local x = math.random(5, 10) / 10 * v + if math.random(0, 10) < 5 then x = -x end + local z = math.random(5, 10) / 10 * v + if math.random(0, 10) < 5 then z = -z end + local y = math.random(2, 4) + self.object:set_velocity(vector.new(x, y, z)) + end + self.random_velocity = 0 + end, + set_item = function(self, itemstring) self.itemstring = itemstring if self.itemstring == "" then @@ -433,7 +592,7 @@ minetest.register_entity(":__builtin:item", { local max_count = stack:get_stack_max() if count > max_count then count = max_count - self.itemstring = stack:get_name().." "..max_count + self.itemstring = stack:get_name() .. " " .. max_count end local itemtable = stack:to_table() local itemname = nil @@ -454,35 +613,17 @@ minetest.register_entity(":__builtin:item", { local prop = { is_visible = true, visual = "wielditem", - textures = {itemname}, - visual_size = {x = s, y = s}, - collisionbox = {-c, -c, -c, c, c, c}, + textures = { itemname }, + visual_size = { x = s, y = s }, + collisionbox = { -c, -c, -c, c, c, c }, automatic_rotate = math.pi * 0.5, infotext = description, glow = glow, } self.object:set_properties(prop) - if item_drop_settings.random_item_velocity == true then - minetest.after(0, function(self) - if not self or not self.object or not self.object:get_luaentity() then - return - end - local vel = self.object:get_velocity() - if vel and vel.x == 0 and vel.z == 0 then - local x = math.random(1, 5) - if math.random(1,2) == 1 then - x = -x - end - local z = math.random(1, 5) - if math.random(1,2) == 1 then - z = -z - end - local y = math.random(2,4) - self.object:set_velocity({x=1/x, y=y, z=1/z}) - end - end, self) + if item_drop_settings.random_item_velocity == true and self.age < 1 then + minetest.after(0, self.apply_random_vel, self) end - end, get_staticdata = function(self) @@ -536,9 +677,9 @@ minetest.register_entity(":__builtin:item", { self.itemstring = data.itemstring self.always_collect = data.always_collect if data.age then - self.age = data.age + dtime_s + self.age = data.age else - self.age = dtime_s + self.age = self.age end --remember collection data -- If true, can collect item without delay @@ -570,9 +711,9 @@ minetest.register_entity(":__builtin:item", { self._forcestart = nil self._forcetimer = 0 - self.object:set_armor_groups({immortal = 1}) - self.object:set_velocity({x = 0, y = 2, z = 0}) - self.object:set_acceleration({x = 0, y = -get_gravity(), z = 0}) + self.object:set_armor_groups({ immortal = 1 }) + -- self.object:set_velocity(vector.new(0, 2, 0)) + self.object:set_acceleration(vector.new(0, -get_gravity(), 0)) self:set_item(self.itemstring) end, @@ -585,9 +726,9 @@ minetest.register_entity(":__builtin:item", { local stack = ItemStack(entity.itemstring) local name = stack:get_name() if own_stack:get_name() ~= name or - own_stack:get_meta() ~= stack:get_meta() or - own_stack:get_wear() ~= stack:get_wear() or - own_stack:get_free_space() == 0 then + own_stack:get_meta() ~= stack:get_meta() or + own_stack:get_wear() ~= stack:get_wear() or + own_stack:get_free_space() == 0 then -- Can not merge different or full stack return false end @@ -601,12 +742,13 @@ minetest.register_entity(":__builtin:item", { end -- Merge the remote stack into this one - local pos = object:get_pos() - pos.y = pos.y + ((total_count - count) / max_count) * 0.15 - self.object:move_to(pos) + -- local pos = object:get_pos() + -- pos.y = pos.y + ((total_count - count) / max_count) * 0.15 + -- self.object:move_to(pos) self.age = 0 -- Handle as new entity own_stack:set_count(total_count) + self.random_velocity = 0 self:set_item(own_stack:to_string()) entity._removed = true @@ -619,8 +761,8 @@ minetest.register_entity(":__builtin:item", { 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}) + self.object:set_velocity(vector.zero()) + self.object:set_acceleration(vector.zero()) return end self.age = self.age + dtime @@ -635,45 +777,72 @@ minetest.register_entity(":__builtin:item", { -- Delete corrupted item entities. The itemstring MUST be non-empty on its first step, -- otherwise there might have some data corruption. if self.itemstring == "" then - minetest.log("warning", "Item entity with empty itemstring found at "..minetest.pos_to_string(self.object:get_pos()).. "! Deleting it now.") + minetest.log("warning", + "Item entity with empty itemstring found at " .. minetest.pos_to_string(self.object:get_pos()) .. + "! Deleting it now.") self._removed = true self.object:remove() return end local p = self.object:get_pos() - local node = minetest.get_node_or_nil(p) - local in_unloaded = (node == nil) - - if self.is_clock then - self.object:set_properties({ - textures = {"mcl_clock:clock_" .. (mcl_worlds.clock_works(p) and mcl_clock.old_time or mcl_clock.random_frame)} - }) - end - - -- If no collector was found for a long enough time, declare the magnet as disabled - if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then - self._magnet_active = false - enable_physics(self.object, self) + -- If hopper has taken item, it has gone, and no operations should be conducted on this item + if hopper_take_item(self, p) then return end + + local node = minetest.get_node(p) + local in_unloaded = node.name == "ignore" + if in_unloaded then -- Don't infinetly fall into unloaded map disable_physics(self.object, self) return end - -- Destroy item in lava, fire or special nodes + if self.is_clock then + self.object:set_properties({ + textures = { "mcl_clock:clock_" .. (mcl_worlds.clock_works(p) and mcl_clock.old_time or mcl_clock.random_frame) } + }) + end + local nn = node.name + local is_in_water = (minetest.get_item_group(nn, "liquid") ~= 0) + local nn_above = minetest.get_node(vector.offset(p, 0, 0.1, 0)).name + -- make sure it's more or less stationary and is at water level + local sleep_threshold = 0.3 + local is_floating = false + local is_stationary = math.abs(self.object:get_velocity().x) < sleep_threshold + and math.abs(self.object:get_velocity().y) < sleep_threshold + and math.abs(self.object:get_velocity().z) < sleep_threshold + if is_in_water and is_stationary then + is_floating = (is_in_water + and (minetest.get_item_group(nn_above, "liquid") == 0)) + end + + if is_floating and self.physical_state == true then + self.object:set_velocity(vector.zero()) + self.object:set_acceleration(vector.zero()) + disable_physics(self.object, self) + end + -- If no collector was found for a long enough time, declare the magnet as disabled + if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then + self._magnet_active = false + enable_physics(self.object, self) + return + end + + -- Destroy item in lava, fire or special nodes + local def = minetest.registered_nodes[nn] local lg = minetest.get_item_group(nn, "lava") local fg = minetest.get_item_group(nn, "fire") local dg = minetest.get_item_group(nn, "destroys_items") if (def and (lg ~= 0 or fg ~= 0 or dg == 1)) then --Wait 2 seconds to allow mob drops to be cooked, & picked up instead of instantly destroyed. - if self.age > 2 then + if self.age > 2 and minetest.get_item_group(self.itemstring, "fire_immune") == 0 then if dg ~= 2 then - minetest.sound_play("builtin_item_lava", {pos = self.object:get_pos(), gain = 0.5}) + minetest.sound_play("builtin_item_lava", { pos = self.object:get_pos(), gain = 0.5 }) end self._removed = true self.object:remove() @@ -694,7 +863,7 @@ minetest.register_entity(":__builtin:item", { end -- Push item out when stuck inside solid opaque node - if def and def.walkable and def.groups and def.groups.opaque == 1 then + if not is_in_water and def and def.walkable and def.groups and def.groups.opaque == 1 then local shootdir local cx = (p.x % 1) - 0.5 local cz = (p.z % 1) - 0.5 @@ -713,7 +882,7 @@ minetest.register_entity(":__builtin:item", { end -- Check which one of the 4 sides is free - for o=1, #order do + for o = 1, #order do local nn = minetest.get_node(vector.add(p, order[o])).name local def = minetest.registered_nodes[nn] if def and def.walkable == false and nn ~= "ignore" then @@ -723,7 +892,7 @@ minetest.register_entity(":__builtin:item", { end -- If none of the 4 sides is free, shoot upwards if shootdir == nil then - shootdir = { x=0, y=1, z=0 } + shootdir = vector.new(0, 1, 0) local nn = minetest.get_node(vector.add(p, shootdir)).name if nn == "ignore" then -- Do not push into ignore @@ -733,11 +902,11 @@ minetest.register_entity(":__builtin:item", { -- Set new item moving speed accordingly local newv = vector.multiply(shootdir, 3) - self.object:set_acceleration({x = 0, y = 0, z = 0}) + self.object:set_acceleration(vector.zero()) self.object:set_velocity(newv) - disable_physics(self.object, self, false, false) + if shootdir.y == 0 then self._force = newv p.x = math.floor(p.x) @@ -755,10 +924,10 @@ minetest.register_entity(":__builtin:item", { if self._forcetimer > 0 then local cbox = self.object:get_properties().collisionbox local ok = false - if self._force.x > 0 and (p.x > (self._forcestart.x + 0.5 + (cbox[4] - cbox[1])/2)) then ok = true - elseif self._force.x < 0 and (p.x < (self._forcestart.x + 0.5 - (cbox[4] - cbox[1])/2)) then ok = true - elseif self._force.z > 0 and (p.z > (self._forcestart.z + 0.5 + (cbox[6] - cbox[3])/2)) then ok = true - elseif self._force.z < 0 and (p.z < (self._forcestart.z + 0.5 - (cbox[6] - cbox[3])/2)) then ok = true end + if self._force.x > 0 and (p.x > (self._forcestart.x + 0.5 + (cbox[4] - cbox[1]) / 2)) then ok = true + elseif self._force.x < 0 and (p.x < (self._forcestart.x + 0.5 - (cbox[4] - cbox[1]) / 2)) then ok = true + elseif self._force.z > 0 and (p.z > (self._forcestart.z + 0.5 + (cbox[6] - cbox[3]) / 2)) then ok = true + elseif self._force.z < 0 and (p.z < (self._forcestart.z + 0.5 - (cbox[6] - cbox[3]) / 2)) then ok = true end -- Item was successfully forced out. No more pushing if ok then self._forcetimer = -1 @@ -774,8 +943,9 @@ minetest.register_entity(":__builtin:item", { return end - -- Move item around on flowing liquids - if def and def.liquidtype == "flowing" then + -- Move item around on flowing liquids; add 'source' check to allow items to continue flowing a bit in the source block of flowing water. + if def and not is_floating and (def.liquidtype == "flowing" or def.liquidtype == "source") then + self._flowing = true --[[ Get flowing direction (function call from flowlib), if there's a liquid. NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7. @@ -784,11 +954,11 @@ minetest.register_entity(":__builtin:item", { -- 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 + local f = 1.2 -- 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}) + -- Swap to acceleration instead of a static speed to better mimic MC mechanics. + self.object:set_acceleration(vector.new(newv.x, -0.22, newv.z)) self.physical_state = true self._flowing = true @@ -797,7 +967,30 @@ minetest.register_entity(":__builtin:item", { }) return end - elseif self._flowing == true then + if is_in_water and def.liquidtype == "source" then + local cur_vec = self.object:get_velocity() + -- apply some acceleration in the opposite direction so it doesn't slide forever + local vec = { + x = 0 - cur_vec.x * 0.9, + y = 3 - cur_vec.y * 0.9, + z = 0 - cur_vec.z * 0.9 + } + self.object:set_acceleration(vec) + -- slow down the item in water + local vel = self.object:get_velocity() + if vel.y < 0 then + vel.y = vel.y * 0.9 + end + self.object:set_velocity(vel) + if self.physical_state ~= false or self._flowing ~= true then + self.physical_state = true + self._flowing = true + self.object:set_properties({ + physical = true + }) + end + end + elseif self._flowing == true and not is_in_water and not is_floating then -- Disable flowing physics if not on/in flowing liquid self._flowing = false enable_physics(self.object, self, true) @@ -805,29 +998,35 @@ minetest.register_entity(":__builtin:item", { end -- If node is not registered or node is walkably solid and resting on nodebox - local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name + local nn = minetest.get_node(vector.offset(p, 0, -0.5, 0)).name + local def = minetest.registered_nodes[nn] local v = self.object:get_velocity() + local is_on_floor = def and (def.walkable + and not def.groups.slippery and v.y == 0) - if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and v.y == 0 then - if self.physical_state then - local own_stack = ItemStack(self.object:get_luaentity().itemstring) - -- Merge with close entities of the same item - for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do - local obj = object:get_luaentity() - if obj and obj.name == "__builtin:item" - and obj.physical_state == false then - if self:try_merge_with(own_stack, object, obj) then - return - end + if not minetest.registered_nodes[nn] + or is_floating or is_on_floor then + local own_stack = ItemStack(self.object:get_luaentity().itemstring) + -- Merge with close entities of the same item + for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do + local obj = object:get_luaentity() + if obj and obj.name == "__builtin:item" + and obj.physical_state == false then + if self:try_merge_with(own_stack, object, obj) then + return end end - disable_physics(self.object, self) + -- don't disable if underwater + if not is_in_water then + disable_physics(self.object, self) + end end else - if self._magnet_active == false then + if self._magnet_active == false and not is_floating then enable_physics(self.object, self) end end + end, -- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index d894f9722..6a837207f 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -677,7 +677,8 @@ register_minecart( { "mcl_chests_normal.png", "mcl_minecarts_minecart.png" }, "mcl_minecarts_minecart_chest.png", {"mcl_minecarts:minecart", "mcl_chests:chest"}, - nil, nil, false) + nil, nil, true) +mcl_entity_invs.register_inv("mcl_minecarts:chest_minecart","Minecart",27,false,true) -- Minecart with Furnace register_minecart( @@ -730,7 +731,7 @@ register_minecart( "mcl_minecarts_minecart.png", }}) end - end, nil, false + end, nil, true ) -- Minecart with Command Block @@ -769,8 +770,9 @@ register_minecart( }, "mcl_minecarts_minecart_hopper.png", {"mcl_minecarts:minecart", "mcl_hoppers:hopper"}, - nil, nil, false + nil, nil, true ) +mcl_entity_invs.register_inv("mcl_minecarts:hopper_minecart", "Hopper Minecart", 5, false, true) -- Minecart with TNT register_minecart( @@ -830,8 +832,7 @@ minetest.register_craft({ }, }) --- TODO: Re-enable crafting of special minecarts when they have been implemented ---[[minetest.register_craft({ +minetest.register_craft({ output = "mcl_minecarts:furnace_minecart", recipe = { {"mcl_furnaces:furnace"}, @@ -847,18 +848,18 @@ minetest.register_craft({ }, }) + minetest.register_craft({ output = "mcl_minecarts:chest_minecart", recipe = { {"mcl_chests:chest"}, {"mcl_minecarts:minecart"}, }, -})]] +}) if has_mcl_wip then mcl_wip.register_wip_item("mcl_minecarts:chest_minecart") mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart") mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart") - mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart") end diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr index 67ed5eb1b..8ad3b34b2 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr @@ -33,4 +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 +Sneak to dismount=Se baisser pour descendre \ No newline at end of file diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ja.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ja.tr new file mode 100644 index 000000000..30af73c48 --- /dev/null +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ja.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_minecarts +Minecart=トロッコ +Minecarts can be used for a quick transportion on rails.=トロッコは、レールを使った高速輸送を可能にします。 +Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type.=トロッコはレール上にしか乗らない為、常に線路に沿って走ります。直進できない丁字路では、取り敢えず左折します。速度はレールの種類によって異なります。 +You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=レールの上にトロッコを置けます。右クリックで乗り込みます。パンチすると動き出します。 +To obtain the minecart, punch it while holding down the sneak key.=トロッコを入手するには、スニークキーを押しながらパンチします。 +A minecart with TNT is an explosive vehicle that travels on rail.=TNT付きトロッコは、レール上を行きかう爆薬車両です。 +Place it on rails. Punch it to move it. The TNT is ignited with a flint and steel or when the minecart is on an powered activator rail.=レール上に配置。パンチで移動。TNTが着火するのは、火打石と打金を使った時か、稼動中のアクティベーターレール上にトロッコが乗った時です。 +To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=トロッコとTNTを入手するには、スニークキーを押しながらパンチしてください。TNTに火が着いていた場合は、無理です。 +A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=かまど付きトロッコは、レール上を走行する車両です。燃料で自走できます。 +Place it on rails. If you give it some coal, the furnace will start burning for a long time and the minecart will be able to move itself. Punch it to get it moving.=レールの上に置きます。石炭を与えると、かまどが長時間燃え続け、トロッコが自走可能になります。パンチすると動き出します。 +To obtain the minecart and furnace, punch them while holding down the sneak key.=トロッコとかまどを入手するには、スニークキーを押しながらパンチします。 +Minecart with Chest=チェスト付きトロッコ +Minecart with Furnace=かまど付きトロッコ +Minecart with Command Block=コマンドブロック付きトロッコ +Minecart with Hopper=ホッパー付きトロッコ +Minecart with TNT=TNT付きトロッコ +Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed.=地面に置いて線路を作ると、レール同士が自動的につながり、必要に応じてカーブや丁字路、踏切、坂道などに変化します。 +Rail=レール +Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=レールを利用して、トロッコの輸送路が敷けます。普通のレールは、摩擦の関係でトロッコが少しずつ減速していきます。 +Powered Rail=パワードレール +Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=レールを利用して、トロッコの輸送路が敷けます。パワードレールは、トロッコを加速させたり、ブレーキをかけたりできます。 +Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=レッドストーン動力なしだと、このレールはトロッコにブレーキをかけます。このレールでトロッコを加速させるには、レッドストーン動力を供給してください。 +Activator Rail=アクティベーターレール +Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=レールを利用して、トロッコの輸送路が敷けます。アクティベーターレールは、特殊なトロッコを作動させるために使われます。 +To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=このレールでトロッコを作動させるには、レッドストーン動力を与えたレール上にトロッコを送り込みます。 +Detector Rail= +Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms.=レールを利用して、トロッコの輸送路が敷けます。ディテクターレールは、その上にあるトロッコを検知でき、その際レッドストーン機構の動力源となります。 +To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=トロッコを検知してレッドストーン動力を供給するには、レッドストーン導線またはレッドストーン機構に接続し、任意のトロッコをレール上に送り込みます。 +Track for minecarts=トロッコ用の線路 +Speed up when powered, slow down when not powered=稼動中は加速、非稼動中は減速 +Activates minecarts when powered=稼動中はトロッコを作動 +Emits redstone power when a minecart is detected=トロッコを検知するとレッドストーン動力を放出 +Vehicle for fast travel on rails=レール上を快速移動するための車両 +Can be ignited by tools or powered activator rail=道具や稼動中のアクティベーターレールにより着火が可能 +Sneak to dismount=スニークで降りる diff --git a/mods/ENTITIES/mcl_minecarts/mod.conf b/mods/ENTITIES/mcl_minecarts/mod.conf index 3b8ae5551..b810c2b6a 100644 --- a/mods/ENTITIES/mcl_minecarts/mod.conf +++ b/mods/ENTITIES/mcl_minecarts/mod.conf @@ -1,6 +1,5 @@ name = mcl_minecarts author = Krock description = Minecarts are vehicles to move players quickly on rails. -depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons +depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons, mcl_entity_invs optional_depends = doc_identifier, mcl_wip - diff --git a/mods/ENTITIES/mcl_minecarts/rails.lua b/mods/ENTITIES/mcl_minecarts/rails.lua index 91282f253..5117fe48c 100644 --- a/mods/ENTITIES/mcl_minecarts/rails.lua +++ b/mods/ENTITIES/mcl_minecarts/rails.lua @@ -21,7 +21,7 @@ local function register_rail(itemstring, tiles, def_extras, creative) stack_max = 64, groups = groups, sounds = mcl_sounds.node_sound_metal_defaults(), - _mcl_blast_resistance = 3.5, + _mcl_blast_resistance = 0.7, _mcl_hardness = 0.7, after_destruct = function(pos) -- Scan for minecarts in this pos and force them to execute their "floating" check. diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 933634cce..e9265d36b 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -1,65 +1,28 @@ - +local mob_class = mcl_mobs.mob_class +local mob_class_meta = {__index = mcl_mobs.mob_class} +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs -- API for Mobs Redo: MineClone 2 Edition (MRM) -mcl_mobs = {} - -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 ENTITY_CRAMMING_MAX = 24 -local CRAMMING_DAMAGE = 3 - -local MOB_CAP = {} -MOB_CAP.hostile = 70 -MOB_CAP.passive = 10 -MOB_CAP.ambient = 15 -MOB_CAP.water = 15 +local PATHFINDING = "gowp" -- Localize local S = minetest.get_translator("mcl_mobs") --- Invisibility mod check -mcl_mobs.invis = {} - --- 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) +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false) +local function mcl_log (message) + if LOGGING_ON then + mcl_util.mcl_log (message, "[Mobs]", true) end end +-- Invisibility mod check +mcl_mobs.invis = {} --- 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 remove_far = true local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false -local remove_far = true -local difficulty = tonumber(minetest.settings:get("mob_difficulty")) or 1.0 -local show_health = false -local max_per_block = tonumber(minetest.settings:get("max_objects_per_block") or 64) -local mobs_spawn_chance = tonumber(minetest.settings:get("mobs_spawn_chance") or 2.5) - --- Shows helpful debug info above each mob -local mobs_debug = minetest.settings:get_bool("mobs_debug", false) +local mobs_debug = minetest.settings:get_bool("mobs_debug", false) -- Shows helpful debug info above each mob +local spawn_logging = minetest.settings:get_bool("mcl_logging_mobs_spawn",true) -- Peaceful mode message so players will know there are no monsters if minetest.settings:get_bool("only_peaceful_mobs", false) then @@ -69,584 +32,23 @@ if minetest.settings:get_bool("only_peaceful_mobs", false) then 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" -mcl_mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt" - -minetest.register_chatcommand("clearmobs",{ - privs={maphack=true}, - params = "||", - description=S("Removes all spawned mobs except nametagged and tamed ones. all removes all mobs, nametagged only nametagged ones and with the range paramter all mobs in a distance of the current player are removed."), - func=function(n,param) - local p = minetest.get_player_by_name(n) - local num=tonumber(param) - for _,o in pairs(minetest.luaentities) do - if o.is_mob then - if param == "all" or - ( param == "nametagged" and o.nametag ) or - ( param == "" and not o.nametag and not o.tamed ) or - ( num and num > 0 and vector.distance(p:get_pos(),o.object:get_pos()) <= num ) then - o.object:remove() - end - end - end -end}) - -----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}) +local node_ok = function(pos, fallback) + fallback = fallback or mcl_mobs.fallback_node + local node = minetest.get_node_or_nil(pos) + if node and minetest.registered_nodes[node.name] then + return node end + return minetest.registered_nodes[fallback] end -local disable_physics = function(object, luaentity, ignore_check, reset_movement) - if luaentity.physical_state == true or ignore_check == true then - luaentity.physical_state = false - object:set_properties({ - physical = false - }) - if reset_movement ~= false then - object:set_velocity({x=0,y=0,z=0}) - object:set_acceleration({x=0,y=0,z=0}) - end - end -end - - --- play sound -local mob_sound = function(self, soundname, is_opinion, fixed_pitch) - - local soundinfo - if self.sounds_child and self.child then - soundinfo = self.sounds_child - elseif self.sounds then - soundinfo = self.sounds - end - if not soundinfo then - return - end - local sound = soundinfo[soundname] - if sound then - if is_opinion and self.opinion_sound_cooloff > 0 then - return - end - local pitch - if not fixed_pitch then - local base_pitch = soundinfo.base_pitch - if not base_pitch then - base_pitch = 1 - end - if self.child and (not self.sounds_child) then - -- Children have higher pitch - pitch = base_pitch * 1.5 - else - pitch = base_pitch - end - -- randomize the pitch a bit - pitch = pitch + math.random(-10, 10) * 0.005 - end - minetest.sound_play(sound, { - object = self.object, - gain = 1.0, - max_hear_distance = self.sounds.distance, - pitch = pitch, - }, true) - self.opinion_sound_cooloff = 1 - end -end - --- Return true if object is in view_range -local function object_in_range(self, object) - if not object then - return false - end - local factor - -- Apply view range reduction for special player armor - if object:is_player() 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 random(0, 100) < 90 then - --mob_sound(self, "war_cry", true) - --end -end - - --- collision function borrowed amended from jordan4ibanez open_ai mod -local collision = function(self) - - local pos = self.object:get_pos() - local vel = self.object:get_velocity() - local x = 0 - local z = 0 - local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 - - for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do - - local ent = object:get_luaentity() - if object:is_player() or (ent and ent.is_mob and object ~= self.object) then - - local pos2 = object:get_pos() - local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} - local force = (width + 0.5) - vector.distance( - {x = pos.x, y = 0, z = pos.z}, - {x = pos2.x, y = 0, z = pos2.z}) - - x = x + (vec.x * force) - z = z + (vec.z * force) - end - end - - return({x,z}) -end - --- move mob in facing direction -local set_velocity = function(self, v) - - local c_x, c_y = 0, 0 - - -- can mob be pushed, if so calculate direction - if self.pushable then - c_x, c_y = unpack(collision(self)) - end - - -- halt mob if it has been ordered to stay - if self.order == "stand" then - self.object:set_velocity({x = 0, y = 0, z = 0}) - return - end - - local yaw = (self.object:get_yaw() or 0) + self.rotate - - self.object:set_velocity({ - x = (sin(yaw) * -v) + c_x, - y = self.object:get_velocity().y, - z = (cos(yaw) * v) + c_y, - }) -end - - - --- calculate mob velocity -local get_velocity = function(self) - - local v = self.object:get_velocity() - if v then - return (v.x * v.x + v.z * v.z) ^ 0.5 - end - - return 0 -end - -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 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 - --- 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 - - self.target_yaw = yaw - self.delay = delay - - return self.target_yaw -end - --- global function to set mob yaw -function mcl_mobs:yaw(self, yaw, delay, dtime) - set_yaw(self, yaw, delay, dtime) -end - -local add_texture_mod = function(self, mod) - local full_mod = "" - local already_added = false - for i=1, #self.texture_mods do - if mod == self.texture_mods[i] then - already_added = true - end - full_mod = full_mod .. self.texture_mods[i] - end - if not already_added then - full_mod = full_mod .. mod - table.insert(self.texture_mods, mod) - end - self.object:set_texture_mod(full_mod) -end -local remove_texture_mod = function(self, mod) - local full_mod = "" - local remove = {} - for i=1, #self.texture_mods do - if self.texture_mods[i] ~= mod then - full_mod = full_mod .. self.texture_mods[i] - else - table.insert(remove, i) - end - end - for i=#remove, 1 do - table.remove(self.texture_mods, remove[i]) - end - self.object:set_texture_mod(full_mod) -end - --- 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" or def.walkable == false and - (def.liquidtype == "none" or minetest.get_item_group(nod, "fake_liquid") == 1) then - return true - end - end - - return false -end - --- set defined animation -local set_animation = function(self, anim, fixed_frame) - if not self.animation or not anim then - return - end - if self.state == "die" and anim ~= "die" and anim ~= "stand" then - return - end - - if flight_check(self) and self.fly and anim == "walk" then anim = "fly" end - - self.animation.current = self.animation.current or "" - - if (anim == self.animation.current - or not self.animation[anim .. "_start"] - or not self.animation[anim .. "_end"]) and self.state ~= "die" then - return - end - - self.animation.current = anim - - local a_start = self.animation[anim .. "_start"] - local a_end - if fixed_frame then - a_end = a_start - else - a_end = self.animation[anim .. "_end"] - end - - self.object:set_animation({ - x = a_start, - y = a_end}, - self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, - 0, self.animation[anim .. "_loop"] ~= false) -end - - --- above function exported for mount.lua -function mcl_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 - - --- Returns true if node is a water hazard -local is_node_waterhazard = function(self, nodename) - local nn = nodename - if self.water_damage > 0 then - if minetest.get_item_group(nn, "water") ~= 0 then - return true - end - end - if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].drowning and minetest.registered_nodes[nn].drowning > 0 then - if self.breath_max ~= -1 then - -- check if the mob is water-breathing _and_ the block is water; only return true if neither is the case - -- this will prevent water-breathing mobs to classify water or e.g. sand below them as dangerous - if not self.breathes_in_water and minetest.get_item_group(nn, "water") ~= 0 then - return true - end - end - end - return false -end - - --- check line of sight (BrunoMine) -local line_of_sight = function(self, pos1, pos2, stepsize) - - stepsize = stepsize or 1 - - local s, pos = minetest.line_of_sight(pos1, pos2, stepsize) - - -- normal walking and flying mobs can see you through air - if s == true then - return true - end - - -- New pos1 to be analyzed - local npos1 = {x = pos1.x, y = pos1.y, z = pos1.z} - - local r, pos = minetest.line_of_sight(npos1, pos2, stepsize) - - -- Checks the return - if r == true then return true end - - -- Nodename found - local nn = minetest.get_node(pos).name - - -- Target Distance (td) to travel - local td = vector.distance(pos1, pos2) - - -- Actual Distance (ad) traveled - local ad = 0 - - -- It continues to advance in the line of sight in search of a real - -- obstruction which counts as 'normal' nodebox. - while minetest.registered_nodes[nn] - and minetest.registered_nodes[nn].walkable == false do - - -- Check if you can still move forward - if td < ad + stepsize then - return true -- Reached the target - end - - -- Moves the analyzed pos - local d = vector.distance(pos1, pos2) - - npos1.x = ((pos2.x - pos1.x) / d * stepsize) + pos1.x - npos1.y = ((pos2.y - pos1.y) / d * stepsize) + pos1.y - npos1.z = ((pos2.z - pos1.z) / d * stepsize) + pos1.z - - -- NaN checks - if d == 0 - or npos1.x ~= npos1.x - or npos1.y ~= npos1.y - or npos1.z ~= npos1.z then - return false - end - - ad = ad + stepsize - - -- scan again - r, pos = minetest.line_of_sight(npos1, pos2, stepsize) - - if r == true then return true end - - -- New Nodename found - nn = minetest.get_node(pos).name - - end - - return false -end - --- 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 - -mcl_mobs.death_effect = function(pos, yaw, collisionbox, rotate) - local min, max - if collisionbox then - min = {x=collisionbox[1], y=collisionbox[2], z=collisionbox[3]} - max = {x=collisionbox[4], y=collisionbox[5], z=collisionbox[6]} - else - min = { x = -0.5, y = 0, z = -0.5 } - max = { x = 0.5, y = 0.5, z = 0.5 } - end - if rotate then - min = vector.rotate(min, {x=0, y=yaw, z=pi/2}) - max = vector.rotate(max, {x=0, y=yaw, z=pi/2}) - min, max = vector.sort(min, max) - min = vector.multiply(min, 0.5) - max = vector.multiply(max, 0.5) - end - - minetest.add_particlespawner({ - amount = 50, - time = 0.001, - minpos = vector.add(pos, min), - maxpos = vector.add(pos, max), - minvel = vector.new(-5,-5,-5), - maxvel = vector.new(5,5,5), - minexptime = 1.1, - maxexptime = 1.5, - minsize = 1, - maxsize = 2, - collisiondetection = false, - vertical = false, - texture = "mcl_particles_mob_death.png^[colorize:#000000:255", - }) - - minetest.sound_play("mcl_mobs_mob_poof", { - pos = pos, - gain = 1.0, - max_hear_distance = 8, - }, true) -end - -local update_tag = function(self) +function mob_class:update_tag() --update nametag and/or the debug box local tag if mobs_debug then - tag = "nametag = '"..tostring(self.nametag).."'\n".. + local name = self.name + if self.nametag and self.nametag ~= "" then + name = self.nametag + end + tag = "name = '"..tostring(name).."'\n".. "state = '"..tostring(self.state).."'\n".. "order = '"..tostring(self.order).."'\n".. "attack = "..tostring(self.attack).."\n".. @@ -657,2735 +59,34 @@ local update_tag = function(self) "horny = "..tostring(self.horny).."\n".. "hornytimer = "..tostring(self.hornytimer).."\n".. "runaway_timer = "..tostring(self.runaway_timer).."\n".. - "following = "..tostring(self.following) + "following = "..tostring(self.following).."\n".. + "lifetimer = "..tostring(self.lifetimer) else tag = self.nametag end self.object:set_properties({ nametag = tag, }) - - update_roll(self) end --- drop items -local item_drop = function(self, cooked, looting_level) +function mob_class:get_staticdata() - -- no drops if disabled by setting - if not mobs_drop_items then return end - - looting_level = looting_level or 0 - - -- no drops for child mobs (except monster) - if (self.child and self.type ~= "monster") then - return - end - - local obj, item, num - 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 random() < chance then - num = random(dropdef.min or 1, dropdef.max or 1) - elseif not dropdef.looting_ignore_chance then - do_common_looting = false - end - - if do_common_looting then - num = num + math.floor(math.random(0, looting_level) + 0.5) - end - - if num > 0 then - item = dropdef.name - - -- cook items when true - if cooked then - - local output = minetest.get_craft_result({ - method = "cooking", width = 1, items = {item}}) - - if output and output.item and not output.item:is_empty() then - item = output.item:get_name() - end - end - - -- add item if it exists - 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 = random(-10, 10) / 9, - y = 6, - z = random(-10, 10) / 9, - }) - elseif obj then - obj:remove() -- item does not exist - end - end - end - - self.drops = {} -end - - --- check if mob is dead or only hurt -local check_for_death = function(self, cause, cmi_cause) - - if self.state == "die" then - return true - end - - -- has health actually changed? - if self.health == self.old_health and self.health > 0 then - return false - end - - local damaged = self.health < self.old_health - self.old_health = self.health - - -- still got some health? - if self.health > 0 then - - -- make sure health isn't higher than max - if self.health > self.hp_max then - self.health = self.hp_max - end - - -- play damage sound if health was reduced and make mob flash red. - if damaged then - add_texture_mod(self, "^[colorize:red:130") - minetest.after(.2, function(self) - if self and self.object then - remove_texture_mod(self, "^[colorize:red:130") - end - end, self) - mob_sound(self, "damage") - end - - -- backup nametag so we can show health stats - if not self.nametag2 then - self.nametag2 = self.nametag or "" - end - - if show_health - and (cmi_cause and cmi_cause.type == "punch") then - - self.htimer = 2 - self.nametag = "♥ " .. self.health .. " / " .. self.hp_max - - update_tag(self) - end - - return false - end - - mob_sound(self, "death") - - local function death_handle(self) - -- dropped cooked item if mob died in fire or lava - if cause == "lava" or cause == "fire" then - item_drop(self, true, 0) - else - local wielditem = ItemStack() - if cause == "hit" then - local puncher = cmi_cause.puncher - if puncher then - wielditem = puncher:get_wielded_item() - end - end - local cooked = mcl_burning.is_burning(self.object) or mcl_enchanting.has_enchantment(wielditem, "fire_aspect") - local looting = mcl_enchanting.get_enchantment(wielditem, "looting") - item_drop(self, cooked, looting) - - if ((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 - - -- execute custom death function - if self.on_die then - - local pos = self.object:get_pos() - local on_die_exit = self.on_die(self, pos, cmi_cause) - if on_die_exit ~= true then - death_handle(self) - end - - if on_die_exit == true then - self.state = "die" - mcl_burning.extinguish(self.object) - self.object:remove() - return true - end - end - - local collisionbox - if self.collisionbox then - collisionbox = table.copy(self.collisionbox) - end - - self.state = "die" - self.attack = nil - self.v_start = false - self.fall_speed = DEFAULT_FALL_SPEED - self.timer = 0 - self.blinktimer = 0 - remove_texture_mod(self, "^[colorize:#FF000040") - remove_texture_mod(self, "^[brighten") - self.passive = true - - self.object:set_properties({ - pointable = false, - collide_with_objects = false, - }) - - set_velocity(self, 0) - local acc = self.object:get_acceleration() - acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0 - self.object:set_acceleration(acc) - - local length - -- default death function and die animation (if defined) - if self.instant_death then - length = 0 - elseif self.animation - and self.animation.die_start - and self.animation.die_end then - - local frames = self.animation.die_end - self.animation.die_start - local speed = self.animation.die_speed or 15 - length = max(frames / speed, 0) + DEATH_DELAY - set_animation(self, "die") - else - local rot = self.object:get_rotation() - rot.z = pi/2 - self.object:set_rotation(rot) - length = 1 + DEATH_DELAY - set_animation(self, "stand", true) - end - - - -- Remove body after a few seconds and drop stuff - local kill = function(self) - if not self.object:get_luaentity() then - return - end - - death_handle(self) - local dpos = self.object:get_pos() - local cbox = self.collisionbox - local yaw = self.object:get_rotation().y - mcl_burning.extinguish(self.object) - self.object:remove() - mcl_mobs.death_effect(dpos, yaw, cbox, not self.instant_death) - end - if length <= 0 then - kill(self) - else - minetest.after(length, kill, self) - end - - return true -end - - --- check if within physical map limits (-30911 to 30927) -local within_limits, wmin, wmax = nil, -30913, 30928 -within_limits = function(pos, radius) - if mcl_vars then - if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then - wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max - within_limits = function(pos, radius) - return pos - and (pos.x - radius) > wmin and (pos.x + radius) < wmax - and (pos.y - radius) > wmin and (pos.y + radius) < wmax - and (pos.z - radius) > wmin and (pos.z + radius) < wmax - end - end - end - return pos - and (pos.x - radius) > wmin and (pos.x + radius) < wmax - and (pos.y - radius) > wmin and (pos.y + radius) < wmax - and (pos.z - radius) > wmin and (pos.z + radius) < wmax -end - - --- is mob facing a cliff or danger -local is_at_cliff_or_danger = function(self) - - if self.fear_height == 0 then -- 0 for no falling protection! - return false - end - - if not self.object:get_luaentity() then - return false - end - local yaw = self.object:get_yaw() - local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5) - local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5) - local pos = self.object:get_pos() - local ypos = pos.y + self.collisionbox[2] -- just above floor - - local free_fall, blocker = minetest.line_of_sight( - {x = pos.x + dir_x, y = ypos, z = pos.z + dir_z}, - {x = pos.x + dir_x, y = ypos - self.fear_height, z = pos.z + dir_z}) - if free_fall then - return true - else - local bnode = minetest.get_node(blocker) - local danger = is_node_dangerous(self, bnode.name) - if danger then - return true - else - local def = minetest.registered_nodes[bnode.name] - if def and def.walkable then - return false - end - end - end - - return false -end - - --- copy the 'mob facing cliff_or_danger check' from above, and rework to avoid water -local is_at_water_danger = function(self) - - - if not self.object:get_luaentity() then - return false - end - local yaw = self.object:get_yaw() - local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5) - local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5) - local pos = self.object:get_pos() - local ypos = pos.y + self.collisionbox[2] -- just above floor - - local free_fall, blocker = minetest.line_of_sight( - {x = pos.x + dir_x, y = ypos, z = pos.z + dir_z}, - {x = pos.x + dir_x, y = ypos - 3, z = pos.z + dir_z}) - if free_fall then - return true - else - local bnode = minetest.get_node(blocker) - local waterdanger = is_node_waterhazard(self, bnode.name) - if - waterdanger and (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) then - return false - elseif waterdanger and (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) == false then - return true - else - local def = minetest.registered_nodes[bnode.name] - if def and def.walkable then - return false - end - end - end - - return false -end - - --- get node but use fallback for nil or unknown -local node_ok = function(pos, fallback) - - fallback = fallback or mcl_mobs.fallback_node - - local node = minetest.get_node_or_nil(pos) - - if node and minetest.registered_nodes[node.name] then - return node - end - - return minetest.registered_nodes[fallback] -end - -local function get_light(pos, tod) - 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 -end - --- environmental damage (water, lava, fire, light etc.) -local do_env_damage = function(self) - - -- feed/tame text timer (so mob 'full' messages dont spam chat) - if self.htimer > 0 then - self.htimer = self.htimer - 1 - end - - -- reset nametag after showing health stats - if self.htimer < 1 and self.nametag2 then - - self.nametag = self.nametag2 - self.nametag2 = nil - - update_tag(self) - end - - local pos = self.object:get_pos() - - self.time_of_day = minetest.get_timeofday() - - -- remove mob if beyond map limits - if not within_limits(pos, 0) then - mcl_burning.extinguish(self.object) - self.object:remove() - return true - end - - - -- Deal light damage to mob, returns true if mob died - local deal_light_damage = function(self, pos, damage) - if not ((mcl_weather.rain.raining or mcl_weather.state == "snow") and mcl_weather.is_outdoor(pos)) then - self.health = self.health - damage - - effect(pos, 5, "mcl_particles_smoke.png") - - if check_for_death(self, "light", {type = "light"}) then - return true - end - end - end - - -- Use get_node_light for Minetest version 5.3 where get_natural_light - -- does not exist yet. - local sunlight = get_light(pos, self.time_of_day) - - -- bright light harms mob - if self.light_damage ~= 0 and (sunlight or 0) > 12 then - if deal_light_damage(self, pos, self.light_damage) then - return true - end - end - local _, dim = mcl_worlds.y_to_layer(pos.y) - if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (sunlight or 0) >= minetest.LIGHT_MAX and dim == "overworld" then - if self.ignited_by_sunlight then - mcl_burning.set_on_fire(self.object, 10) - else - deal_light_damage(self, pos, self.sunlight_damage) - return true - end - end - - local y_level = self.collisionbox[2] - - if self.child then - y_level = self.collisionbox[2] * 0.5 - end - - -- what is mob standing in? - pos.y = pos.y + y_level + 0.25 -- foot level - local pos2 = {x=pos.x, y=pos.y-1, z=pos.z} - self.standing_in = node_ok(pos, "air").name - self.standing_on = node_ok(pos2, "air").name - - -- don't fall when on ignore, just stand still - if self.standing_in == "ignore" then - self.object:set_velocity({x = 0, y = 0, z = 0}) - end - - local nodef = minetest.registered_nodes[self.standing_in] - - -- rain - if self.rain_damage > 0 then - if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then - - self.health = self.health - self.rain_damage - - if check_for_death(self, "rain", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - end - - pos.y = pos.y + 1 -- for particle effect position - - -- water damage - if self.water_damage > 0 - and nodef.groups.water then - - if self.water_damage ~= 0 then - - self.health = self.health - self.water_damage - - effect(pos, 5, "mcl_particles_smoke.png", nil, nil, 1, nil) - - if check_for_death(self, "water", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - - -- lava damage - elseif self.lava_damage > 0 - and (nodef.groups.lava) then - - if self.lava_damage ~= 0 then - - self.health = self.health - self.lava_damage - - effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) - - if check_for_death(self, "lava", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - - -- fire damage - elseif self.fire_damage > 0 - and (nodef.groups.fire) then - - if self.fire_damage ~= 0 then - - self.health = self.health - self.fire_damage - - effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) - - if check_for_death(self, "fire", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - - -- damage_per_second node check - elseif nodef.damage_per_second ~= 0 and not nodef.groups.lava and not nodef.groups.fire then - - self.health = self.health - nodef.damage_per_second - - effect(pos, 5, "mcl_particles_smoke.png") - - if check_for_death(self, "dps", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - - -- Drowning damage - if self.breath_max ~= -1 then - local drowning = false - if self.breathes_in_water then - if minetest.get_item_group(self.standing_in, "water") == 0 then - drowning = true - end - elseif nodef.drowning > 0 then - drowning = true - end - if drowning then - - self.breath = math.max(0, self.breath - 1) - - effect(pos, 2, "bubble.png", nil, nil, 1, nil) - if self.breath <= 0 then - local dmg - if nodef.drowning > 0 then - dmg = nodef.drowning - else - dmg = 4 - end - damage_effect(self, dmg) - self.health = self.health - dmg - end - if check_for_death(self, "drowning", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - else - self.breath = math.min(self.breath_max, self.breath + 1) - end - end - - --- suffocation inside solid node - -- FIXME: Redundant with mcl_playerplus - if (self.suffocation == true) - and (nodef.walkable == nil or nodef.walkable == true) - and (nodef.collision_box == nil or nodef.collision_box.type == "regular") - and (nodef.node_box == nil or nodef.node_box.type == "regular") - and (nodef.groups.disable_suffocation ~= 1) - and (nodef.groups.opaque == 1) then - - -- Short grace period before starting to take suffocation damage. - -- This is different from players, who take damage instantly. - -- This has been done because mobs might briefly be inside solid nodes - -- when e.g. climbing up stairs. - -- This is a bit hacky because it assumes that do_env_damage - -- is called roughly every second only. - self.suffocation_timer = self.suffocation_timer + 1 - if self.suffocation_timer >= 3 then - -- 2 damage per second - -- TODO: Deal this damage once every 1/2 second - self.health = self.health - 2 - - if check_for_death(self, "suffocation", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - else - self.suffocation_timer = 0 - end - - return check_for_death(self, "", {type = "unknown"}) -end - - --- jump if facing a solid node (not fences or gates) -local do_jump = function(self) - - if not self.jump - or self.jump_height == 0 - or self.fly - or (self.child and self.type ~= "monster") - or self.order == "stand" then - return false - end - - self.facing_fence = false - - -- something stopping us while moving? - if self.state ~= "stand" - and get_velocity(self) > 0.5 - and self.object:get_velocity().y ~= 0 then - return false - end - - local pos = self.object:get_pos() - local yaw = self.object:get_yaw() - - -- what is mob standing on? - pos.y = pos.y + self.collisionbox[2] - 0.2 - - local nod = node_ok(pos) - - if minetest.registered_nodes[nod.name].walkable == false then - return false - end - - -- where is front - local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5) - local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5) - - -- what is in front of mob? - nod = node_ok({ - x = pos.x + dir_x, - y = pos.y + 0.5, - z = pos.z + dir_z - }) - - -- this is used to detect if there's a block on top of the block in front of the mob. - -- If there is, there is no point in jumping as we won't manage. - local nodTop = node_ok({ - x = pos.x + dir_x, - y = pos.y + 1.5, - z = pos.z + dir_z - }, "air") - - -- we don't attempt to jump if there's a stack of blocks blocking - if minetest.registered_nodes[nodTop.name].walkable == true then - return false - end - - -- thin blocks that do not need to be jumped - if nod.name == node_snow then - return false - end - - 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 - - local v = self.object:get_velocity() - - v.y = self.jump_height - - set_animation(self, "jump") -- only when defined - - self.object:set_velocity(v) - - -- when in air move forward - minetest.after(0.3, function(self, v) - if (not self.object) or (not self.object:get_luaentity()) or (self.state == "die") then - return - end - self.object:set_acceleration({ - x = v.x * 2, - y = -10, - z = v.z * 2, - }) - end, self, v) - - if self.jump_sound_cooloff <= 0 then - mob_sound(self, "jump") - self.jump_sound_cooloff = 0.5 - end - else - self.facing_fence = true - end - - -- if we jumped against a block/wall 4 times then turn - if self.object:get_velocity().x ~= 0 - and self.object:get_velocity().z ~= 0 then - - self.jump_count = (self.jump_count or 0) + 1 - - if self.jump_count == 4 then - - local yaw = self.object:get_yaw() or 0 - - yaw = set_yaw(self, yaw + 1.35, 8) - - self.jump_count = 0 - end - end - - return true - end - - return false -end - - --- blast damage to entities nearby -local entity_physics = function(pos, radius) - - radius = radius * 2 - - local objs = minetest.get_objects_inside_radius(pos, radius) - local obj_pos, dist - - for n = 1, #objs do - - obj_pos = objs[n]:get_pos() - - dist = vector.distance(pos, obj_pos) - if dist < 1 then dist = 1 end - - local damage = floor((4 / dist) * radius) - local ent = objs[n]:get_luaentity() - - -- punches work on entities AND players - objs[n]:punch(objs[n], 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = damage}, - }, pos) - end -end - - --- should mob follow what I'm holding ? -local follow_holding = function(self, clicker) - if self.nofollow then return false end - - if mcl_mobs.invis[clicker:get_player_name()] then - return false - end - - local item = clicker:get_wielded_item() - local t = type(self.follow) - - -- single item - if t == "string" - and item:get_name() == self.follow then - return true - - -- multiple items - elseif t == "table" then - - for no = 1, #self.follow do - - if self.follow[no] == item:get_name() then - return true - end - end - end - - return false -end - - --- find two animals of same type and breed if nearby and horny -local breed = function(self) - - -- child takes a long time before growing into adult - if self.child == true then - - -- When a child, hornytimer is used to count age until adulthood - self.hornytimer = self.hornytimer + 1 - - if self.hornytimer >= CHILD_GROW_TIME then - - self.child = false - self.hornytimer = 0 - - self.object:set_properties({ - textures = self.base_texture, - mesh = self.base_mesh, - visual_size = self.base_size, - collisionbox = self.base_colbox, - selectionbox = self.base_selbox, - }) - - -- custom function when child grows up - if self.on_grown then - self.on_grown(self) - else - -- jump when fully grown so as not to fall into ground - self.object:set_velocity({ - x = 0, - y = self.jump_height, - z = 0 - }) - end - end - - return - end - - -- horny animal can mate for HORNY_TIME seconds, - -- afterwards horny animal cannot mate again for HORNY_AGAIN_TIME seconds - if self.horny == true - and self.hornytimer < HORNY_TIME + HORNY_AGAIN_TIME then - - self.hornytimer = self.hornytimer + 1 - - if self.hornytimer >= HORNY_TIME + HORNY_AGAIN_TIME then - self.hornytimer = 0 - self.horny = false - end - end - - -- find another same animal who is also horny and mate if nearby - if self.horny == true - and self.hornytimer <= HORNY_TIME then - - local pos = self.object:get_pos() - - effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8, "heart.png", 3, 4, 1, 0.1) - - local objs = minetest.get_objects_inside_radius(pos, 3) - local num = 0 - local ent = nil - - for n = 1, #objs do - - ent = objs[n]:get_luaentity() - - -- check for same animal with different colour - local canmate = false - - if ent then - - if ent.name == self.name then - canmate = true - else - local entname = string.split(ent.name,":") - local selfname = string.split(self.name,":") - - if entname[1] == selfname[1] then - entname = string.split(entname[2],"_") - selfname = string.split(selfname[2],"_") - - if entname[1] == selfname[1] then - canmate = true - end - end - end - end - - if ent - and canmate == true - and ent.horny == true - and ent.hornytimer <= HORNY_TIME then - num = num + 1 - end - - -- found your mate? then have a baby - if num > 1 then - - self.hornytimer = HORNY_TIME + 1 - ent.hornytimer = HORNY_TIME + 1 - - -- spawn baby - minetest.after(5, function(parent1, parent2, pos) - if not parent1.object:get_luaentity() then - return - end - if not parent2.object:get_luaentity() then - return - end - - mcl_experience.throw_xp(pos, math.random(1, 7)) - - -- custom breed function - if parent1.on_breed then - -- when false, skip going any further - if parent1.on_breed(parent1, parent2) == false then - return - end - end - - local child = mcl_mobs:spawn_child(pos, parent1.name) - - local ent_c = child:get_luaentity() - - - -- Use texture of one of the parents - local p = math.random(1, 2) - if p == 1 then - ent_c.base_texture = parent1.base_texture - else - ent_c.base_texture = parent2.base_texture - end - child:set_properties({ - textures = ent_c.base_texture - }) - - -- tamed and owned by parents' owner - ent_c.tamed = true - ent_c.owner = parent1.owner - end, self, ent, pos) - - num = 0 - - break - end - end - end -end - - --- find and replace what mob is looking for (grass, wheat etc.) -local replace = function(self, pos) - - if not self.replace_rate - or not self.replace_what - or self.child == true - or self.object:get_velocity().y ~= 0 - or random(1, self.replace_rate) > 1 then - return - end - - local what, with, y_offset - - if type(self.replace_what[1]) == "table" then - - local num = random(#self.replace_what) - - what = self.replace_what[num][1] or "" - with = self.replace_what[num][2] or "" - y_offset = self.replace_what[num][3] or 0 - else - what = self.replace_what - with = self.replace_with or "" - y_offset = self.replace_offset or 0 - end - - pos.y = pos.y + y_offset - - local node = minetest.get_node(pos) - if node.name == what then - - local oldnode = {name = what, param2 = node.param2} - local newnode = {name = with, param2 = node.param2} - local on_replace_return - - if self.on_replace then - on_replace_return = self.on_replace(self, pos, oldnode, newnode) - end - - if on_replace_return ~= false then - - if mobs_griefing then - minetest.set_node(pos, newnode) - end - - end - end -end - - --- check if daytime and also if mob is docile during daylight hours -local day_docile = function(self) - - if self.docile_by_day == false then - - return false - - elseif self.docile_by_day == true - and self.time_of_day > 0.2 - and self.time_of_day < 0.8 then - - return true - end -end - - -local los_switcher = false -local height_switcher = false - --- path finding and smart mob routine by rnd, line_of_sight and other edits by Elkien3 -local smart_mobs = function(self, s, p, dist, dtime) - - local s1 = self.path.lastpos - - local target_pos = self.attack:get_pos() - - -- is it becoming stuck? - if abs(s1.x - s.x) + abs(s1.z - s.z) < .5 then - self.path.stuck_timer = self.path.stuck_timer + dtime - else - self.path.stuck_timer = 0 - end - - self.path.lastpos = {x = s.x, y = s.y, z = s.z} - - local use_pathfind = false - local has_lineofsight = minetest.line_of_sight( - {x = s.x, y = (s.y) + .5, z = s.z}, - {x = target_pos.x, y = (target_pos.y) + 1.5, z = target_pos.z}, .2) - - -- im stuck, search for path - if not has_lineofsight then - - if los_switcher == true then - use_pathfind = true - los_switcher = false - end -- cannot see target! - else - if los_switcher == false then - - los_switcher = true - use_pathfind = false - - minetest.after(1, function(self) - if not self.object:get_luaentity() then - return - end - if has_lineofsight then self.path.following = false end - end, self) - end -- can see target! - end - - if (self.path.stuck_timer > stuck_timeout and not self.path.following) then - - use_pathfind = true - self.path.stuck_timer = 0 - - minetest.after(1, function(self) - if not self.object:get_luaentity() then - return - end - if has_lineofsight then self.path.following = false end - end, self) - end - - if (self.path.stuck_timer > stuck_path_timeout and self.path.following) then - - use_pathfind = true - self.path.stuck_timer = 0 - - minetest.after(1, function(self) - if not self.object:get_luaentity() then - return - end - if has_lineofsight then self.path.following = false end - end, self) - end - - if math.abs(vector.subtract(s,target_pos).y) > self.stepheight then - - if height_switcher then - use_pathfind = true - height_switcher = false - end - else - if not height_switcher then - use_pathfind = false - height_switcher = true - end - end - - if use_pathfind then - -- lets try find a path, first take care of positions - -- since pathfinder is very sensitive - local sheight = self.collisionbox[5] - self.collisionbox[2] - - -- round position to center of node to avoid stuck in walls - -- also adjust height for player models! - s.x = floor(s.x + 0.5) - s.z = floor(s.z + 0.5) - - local ssight, sground = minetest.line_of_sight(s, { - x = s.x, y = s.y - 4, z = s.z}, 1) - - -- determine node above ground - if not ssight then - s.y = sground.y + 1 - end - - local p1 = self.attack:get_pos() - - p1.x = floor(p1.x + 0.5) - p1.y = floor(p1.y + 0.5) - p1.z = floor(p1.z + 0.5) - - local dropheight = 12 - if self.fear_height ~= 0 then dropheight = self.fear_height end - local jumpheight = 0 - if self.jump and self.jump_height >= 4 then - jumpheight = math.min(math.ceil(self.jump_height / 4), 4) - elseif self.stepheight > 0.5 then - jumpheight = 1 - end - self.path.way = minetest.find_path(s, p1, 16, jumpheight, dropheight, "A*_noprefetch") - - self.state = "" - do_attack(self, self.attack) - - -- no path found, try something else - if not self.path.way then - - self.path.following = false - - -- lets make way by digging/building if not accessible - if self.pathfinding == 2 and mobs_griefing then - - -- is player higher than mob? - if s.y < p1.y then - - -- build upwards - if not minetest.is_protected(s, "") then - - local ndef1 = minetest.registered_nodes[self.standing_in] - - if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then - - minetest.set_node(s, {name = mcl_mobs.fallback_node}) - end - end - - local sheight = math.ceil(self.collisionbox[5]) + 1 - - -- assume mob is 2 blocks high so it digs above its head - s.y = s.y + sheight - - -- remove one block above to make room to jump - if not minetest.is_protected(s, "") then - - local node1 = node_ok(s, "air").name - local ndef1 = minetest.registered_nodes[node1] - - if node1 ~= "air" - and node1 ~= "ignore" - and ndef1 - and not ndef1.groups.level - and not ndef1.groups.unbreakable - and not ndef1.groups.liquid then - - minetest.set_node(s, {name = "air"}) - minetest.add_item(s, ItemStack(node1)) - - end - end - - s.y = s.y - sheight - self.object:set_pos({x = s.x, y = s.y + 2, z = s.z}) - - else -- dig 2 blocks to make door toward player direction - - local yaw1 = self.object:get_yaw() + pi / 2 - local p1 = { - x = s.x + cos(yaw1), - y = s.y, - z = s.z + sin(yaw1) - } - - if not minetest.is_protected(p1, "") then - - local node1 = node_ok(p1, "air").name - local ndef1 = minetest.registered_nodes[node1] - - if node1 ~= "air" - and node1 ~= "ignore" - and ndef1 - and not ndef1.groups.level - and not ndef1.groups.unbreakable - and not ndef1.groups.liquid then - - minetest.add_item(p1, ItemStack(node1)) - minetest.set_node(p1, {name = "air"}) - end - - p1.y = p1.y + 1 - node1 = node_ok(p1, "air").name - ndef1 = minetest.registered_nodes[node1] - - if node1 ~= "air" - and node1 ~= "ignore" - and ndef1 - and not ndef1.groups.level - and not ndef1.groups.unbreakable - and not ndef1.groups.liquid then - - minetest.add_item(p1, ItemStack(node1)) - minetest.set_node(p1, {name = "air"}) - end - - end - end - end - - -- will try again in 2 seconds - self.path.stuck_timer = stuck_timeout - 2 - elseif s.y < p1.y and (not self.fly) then - do_jump(self) --add jump to pathfinding - self.path.following = true - -- Yay, I found path! - -- TODO: Implement war_cry sound without being annoying - --mob_sound(self, "war_cry", true) - else - set_velocity(self, self.walk_velocity) - - -- follow path now that it has it - self.path.following = true - end - end -end - - --- specific attacks -local specific_attack = function(list, what) - - -- no list so attack default (player, animals etc.) - if list == nil then - return true - end - - -- found entity on list to attack? - for no = 1, #list do - - if list[no] == what then - return true - end - end - - return false -end - --- monster find someone to attack -local monster_attack = function(self) - - if self.type ~= "monster" - or not damage_enabled - or minetest.is_creative_enabled("") - or self.passive - or self.state == "attack" - or day_docile(self) then - return - end - - local s = self.object:get_pos() - local p, sp, dist - local player, obj, min_player - local type, name = "", "" - local min_dist = self.view_range + 1 - local objs = minetest.get_objects_inside_radius(s, self.view_range) - - for n = 1, #objs do - - if objs[n]:is_player() then - - if mcl_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 mcl_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 mcl_mobs.invis[ players[n]:get_player_name() ] then - - self.following = players[n] - - break - end - end - end - - if self.type == "npc" - and self.order == "follow" - and self.state ~= "attack" - and self.order ~= "sit" - and self.owner ~= "" then - - -- 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 - -local function go_to_pos(entity,b) - if not entity then return end - local s=entity.object:get_pos() - if vector.distance(b,s) < 1 then - --set_velocity(entity,0) - return true + for _,p in pairs(minetest.get_connected_players()) do + self:remove_particlespawners(p:get_player_name()) end - local v = { x = b.x - s.x, z = b.z - s.z } - local yaw = (math.atan(v.z / v.x) + math.pi / 2) - entity.rotate - if b.x > s.x then yaw = yaw + math.pi end - entity.object:set_yaw(yaw) - set_velocity(entity,entity.follow_velocity) - mcl_mobs:set_animation(entity, "walk") -end - -local function check_doors(self) - local p = self.object:get_pos() - local t = minetest.get_timeofday() - local dd = minetest.find_nodes_in_area(vector.offset(p,-1,-1,-1),vector.offset(p,1,1,1),{"group:door"}) - for _,d in pairs(dd) do - local n = minetest.get_node(d) - if n.name:find("_b_") then - local def = minetest.registered_nodes[n.name] - local closed = n.name:find("_b_1") - if t < 0.3 or t > 0.8 then - if not closed then def.on_rightclick(d,n,self) end - else - if closed then def.on_rightclick(d,n,self) end - end - - end - end -end - --- execute current state (stand, walk, run, attacks) --- returns true if mob has died -local do_states = function(self, dtime) - if self.can_open_doors then check_doors(self) end - - local yaw = self.object:get_yaw() or 0 - - if self.state == "stand" then - if random(1, 4) == 1 then - - local s = self.object:get_pos() - local objs = minetest.get_objects_inside_radius(s, 3) - - for n = 1, #objs do - - if objs[n]:is_player() then - lp = objs[n]:get_pos() - break - end - end - - -- look at any players nearby, otherwise turn randomly - if self.look_at_players then - - local vec = { - x = lp.x - s.x, - z = lp.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if lp.x > s.x then yaw = yaw + pi end - else - yaw = yaw + random(-0.5, 0.5) - end - - yaw = set_yaw(self, yaw, 8) - end - - set_velocity(self, 0) - set_animation(self, "stand") - - -- npc's ordered to stand stay standing - if self.type ~= "npc" - or self.order ~= "stand" then - - if self.walk_chance ~= 0 - and self.facing_fence ~= true - and random(1, 100) <= self.walk_chance - and is_at_cliff_or_danger(self) == false then - - set_velocity(self, self.walk_velocity) - self.state = "walk" - set_animation(self, "walk") - end - end - - elseif self.state == "gowp" then - local p = self.object:get_pos() - if not p or not self._target then return end - if vector.distance(p,self._target) < 2 or ( self.waypoints and #self.waypoints == 0 ) then - self.waypoints = nil - self._target = nil - self.current_target = nil - self.state = "walk" - if self.callback_arrived then return self.callback_arrived(self) end - return true - end - if self.waypoints and ( not self.current_target or vector.distance(p,self.current_target) < 1.5 ) then - self.current_target = table.remove(self.waypoints, 1) - --minetest.log("nextwp:".. tostring(self.current_target) ) - elseif self.current_target then - go_to_pos(self,self.current_target) - end - - if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then - self.waypoints=minetest.find_path(p,self._target,150,1,4) - self.current_target = nil - return - end - if not self.current_target then - --minetest.log("no path") - self.state = "walk" - end - - elseif self.state == "walk" then - local s = self.object:get_pos() - local lp = nil - - -- is there something I need to avoid? - if (self.water_damage > 0 - and self.lava_damage > 0) - or self.breath_max ~= -1 then - - lp = minetest.find_node_near(s, 1, {"group:water", "group:lava"}) - - elseif self.water_damage > 0 then - - lp = minetest.find_node_near(s, 1, {"group:water"}) - - elseif self.lava_damage > 0 then - - lp = minetest.find_node_near(s, 1, {"group:lava"}) - - elseif self.fire_damage > 0 then - - lp = minetest.find_node_near(s, 1, {"group:fire"}) - - end - - local is_in_danger = false - if lp then - -- If mob in or on dangerous block, look for land - if (is_node_dangerous(self, self.standing_in) or - is_node_dangerous(self, self.standing_on)) or (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) and (not self.fly) then - is_in_danger = true - - -- If mob in or on dangerous block, look for land - if is_in_danger then - -- Better way to find shore - copied from upstream - lp = minetest.find_nodes_in_area_under_air( - {x = s.x - 5, y = s.y - 0.5, z = s.z - 5}, - {x = s.x + 5, y = s.y + 1, z = s.z + 5}, - {"group:solid"}) - - lp = #lp > 0 and lp[random(#lp)] - - -- did we find land? - if lp then - - local vec = { - x = lp.x - s.x, - z = lp.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - - if lp.x > s.x then yaw = yaw + pi end - - -- look towards land and move in that direction - yaw = set_yaw(self, yaw, 6) - set_velocity(self, self.walk_velocity) - - end - end - - -- A danger is near but mob is not inside - else - - -- Randomly turn - if random(1, 100) <= 30 then - yaw = yaw + random(-0.5, 0.5) - yaw = set_yaw(self, yaw, 8) - end - end - - yaw = set_yaw(self, yaw, 8) - - -- otherwise randomly turn - elseif random(1, 100) <= 30 then - - yaw = yaw + random(-0.5, 0.5) - yaw = set_yaw(self, yaw, 8) - end - - -- stand for great fall or danger or fence in front - local cliff_or_danger = false - if is_in_danger then - cliff_or_danger = is_at_cliff_or_danger(self) - end - if self.facing_fence == true - or cliff_or_danger - or random(1, 100) <= 30 then - - set_velocity(self, 0) - self.state = "stand" - set_animation(self, "stand") - local yaw = self.object:get_yaw() or 0 - yaw = set_yaw(self, yaw + 0.78, 8) - else - - set_velocity(self, self.walk_velocity) - - if flight_check(self) - and self.animation - and self.animation.fly_start - and self.animation.fly_end then - set_animation(self, "fly") - else - set_animation(self, "walk") - end - end - - -- runaway when punched - elseif self.state == "runaway" then - - self.runaway_timer = self.runaway_timer + 1 - - -- stop after 5 seconds or when at cliff - if self.runaway_timer > 5 - or is_at_cliff_or_danger(self) then - self.runaway_timer = 0 - set_velocity(self, 0) - self.state = "stand" - set_animation(self, "stand") - local yaw = self.object:get_yaw() or 0 - yaw = set_yaw(self, yaw + 0.78, 8) - else - set_velocity(self, self.run_velocity) - set_animation(self, "run") - end - - -- attack routines (explode, dogfight, shoot, dogshoot) - elseif self.state == "attack" then - - local s = self.object:get_pos() - local p = self.attack:get_pos() or s - - -- stop attacking if player invisible or out of range - if not self.attack - or not self.attack:get_pos() - or not object_in_range(self, self.attack) - or self.attack:get_hp() <= 0 - or (self.attack:is_player() and mcl_mobs.invis[ self.attack:get_player_name() ]) then - - self.state = "stand" - set_velocity(self, 0) - set_animation(self, "stand") - self.attack = nil - self.v_start = false - self.timer = 0 - self.blinktimer = 0 - self.path.way = nil - - return - end - - -- calculate distance from mob and enemy - local dist = vector.distance(p, s) - - if self.attack_type == "explode" then - - local vec = { - x = p.x - s.x, - z = p.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if p.x > s.x then yaw = yaw + pi end - - yaw = set_yaw(self, yaw, 0, dtime) - - local node_break_radius = self.explosion_radius or 1 - local entity_damage_radius = self.explosion_damage_radius - or (node_break_radius * 2) - - -- start timer when in reach and line of sight - if not self.v_start - and dist <= self.reach - and line_of_sight(self, s, p, 2) then - - self.v_start = true - self.timer = 0 - self.blinktimer = 0 - mob_sound(self, "fuse", nil, false) - - -- stop timer if out of reach or direct line of sight - elseif self.allow_fuse_reset - and self.v_start - and (dist >= self.explosiontimer_reset_radius - or not line_of_sight(self, s, p, 2)) then - self.v_start = false - self.timer = 0 - self.blinktimer = 0 - self.blinkstatus = false - remove_texture_mod(self, "^[brighten") - end - - -- walk right up to player unless the timer is active - if self.v_start and (self.stop_to_explode or dist < self.reach) then - set_velocity(self, 0) - else - set_velocity(self, self.run_velocity) - end - - if self.animation and self.animation.run_start then - set_animation(self, "run") - else - set_animation(self, "walk") - end - - if self.v_start then - - self.timer = self.timer + dtime - self.blinktimer = (self.blinktimer or 0) + dtime - - if self.blinktimer > 0.2 then - - self.blinktimer = 0 - - if self.blinkstatus then - remove_texture_mod(self, "^[brighten") - else - add_texture_mod(self, "^[brighten") - end - - self.blinkstatus = not self.blinkstatus - end - - if self.timer > self.explosion_timer then - - local pos = self.object:get_pos() - - if mobs_griefing and not minetest.is_protected(pos, "") then - mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { drop_chance = 1.0 }, self.object) - else - minetest.sound_play(self.sounds.explode, { - pos = pos, - gain = 1.0, - max_hear_distance = self.sounds.distance or 32 - }, true) - - entity_physics(pos, entity_damage_radius) - effect(pos, 32, "mcl_particles_smoke.png", nil, nil, node_break_radius, 1, 0) - end - mcl_burning.extinguish(self.object) - self.object:remove() - - return true - end - end - - elseif self.attack_type == "dogfight" - or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 2) - or (self.attack_type == "dogshoot" and dist <= self.reach and dogswitch(self) == 0) then - - if self.fly - and dist > self.reach then - - local p1 = s - local me_y = floor(p1.y) - local p2 = p - local p_y = floor(p2.y + 1) - local v = self.object:get_velocity() - - if flight_check(self, s) then - - if me_y < p_y then - - self.object:set_velocity({ - x = v.x, - y = 1 * self.walk_velocity, - z = v.z - }) - - elseif me_y > p_y then - - self.object:set_velocity({ - x = v.x, - y = -1 * self.walk_velocity, - z = v.z - }) - end - else - if me_y < p_y then - - self.object:set_velocity({ - x = v.x, - y = 0.01, - z = v.z - }) - - elseif me_y > p_y then - - self.object:set_velocity({ - x = v.x, - y = -0.01, - z = v.z - }) - end - end - - end - - -- rnd: new movement direction - if self.path.following - and self.path.way - and self.attack_type ~= "dogshoot" then - - -- no paths longer than 50 - if #self.path.way > 50 - or dist < self.reach then - self.path.following = false - return - end - - local p1 = self.path.way[1] - - if not p1 then - self.path.following = false - return - end - - if abs(p1.x-s.x) + abs(p1.z - s.z) < 0.6 then - -- reached waypoint, remove it from queue - table.remove(self.path.way, 1) - end - - -- set new temporary target - p = {x = p1.x, y = p1.y, z = p1.z} - end - - local vec = { - x = p.x - s.x, - z = p.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if p.x > s.x then yaw = yaw + pi end - - yaw = set_yaw(self, yaw, 0, dtime) - - -- move towards enemy if beyond mob reach - if dist > self.reach then - - -- path finding by rnd - if self.pathfinding -- only if mob has pathfinding enabled - and enable_pathfinding then - - smart_mobs(self, s, p, dist, dtime) - end - - if is_at_cliff_or_danger(self) then - - set_velocity(self, 0) - set_animation(self, "stand") - local yaw = self.object:get_yaw() or 0 - yaw = set_yaw(self, yaw + 0.78, 8) - else - - if self.path.stuck then - set_velocity(self, self.walk_velocity) - else - set_velocity(self, self.run_velocity) - end - - if self.animation and self.animation.run_start then - set_animation(self, "run") - else - set_animation(self, "walk") - end - end - - else -- rnd: if inside reach range - - self.path.stuck = false - self.path.stuck_timer = 0 - self.path.following = false -- not stuck anymore - - set_velocity(self, 0) - - if not self.custom_attack then - - if self.timer > 1 then - - self.timer = 0 - - if self.double_melee_attack - and random(1, 2) == 1 then - set_animation(self, "punch2") - else - set_animation(self, "punch") - end - - local p2 = p - local s2 = s - - p2.y = p2.y + .5 - s2.y = s2.y + .5 - - if line_of_sight(self, p2, s2) == true then - - -- play attack sound - mob_sound(self, "attack") - - -- punch player (or what player is attached to) - local attached = self.attack:get_attach() - if attached then - self.attack = attached - end - self.attack:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = self.damage} - }, nil) - end - end - else -- call custom attack every second - if self.custom_attack - and self.timer > 1 then - - self.timer = 0 - - self.custom_attack(self, p) - end - end - end - - elseif self.attack_type == "shoot" - or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 1) - or (self.attack_type == "dogshoot" and dist > self.reach and dogswitch(self) == 0) then - - p.y = p.y - .5 - s.y = s.y + .5 - - local dist = vector.distance(p, s) - local vec = { - x = p.x - s.x, - y = p.y - s.y, - z = p.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if p.x > s.x then yaw = yaw + pi end - - yaw = set_yaw(self, yaw, 0, dtime) - - set_velocity(self, 0) - - local p = self.object:get_pos() - p.y = p.y + (self.collisionbox[2] + self.collisionbox[5]) / 2 - - if self.shoot_interval - and self.timer > self.shoot_interval - and not minetest.raycast(p, self.attack:get_pos(), false, false):next() - and random(1, 100) <= 60 then - - self.timer = 0 - set_animation(self, "shoot") - - -- play shoot attack sound - mob_sound(self, "shoot_attack") - - -- Shoot arrow - if minetest.registered_entities[self.arrow] then - - local arrow, ent - local v = 1 - if not self.shoot_arrow then - self.firing = true - minetest.after(1, function() - self.firing = false - end) - arrow = minetest.add_entity(p, self.arrow) - ent = arrow:get_luaentity() - if ent.velocity then - v = ent.velocity - end - ent.switch = 1 - ent.owner_id = tostring(self.object) -- add unique owner id to arrow - - -- important for mcl_shields - ent._shooter = self.object - ent._saved_shooter_pos = self.object:get_pos() - end - - local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5 - -- offset makes shoot aim accurate - vec.y = vec.y + self.shoot_offset - vec.x = vec.x * (v / amount) - vec.y = vec.y * (v / amount) - vec.z = vec.z * (v / amount) - if self.shoot_arrow then - vec = vector.normalize(vec) - self:shoot_arrow(p, vec) - else - arrow:set_velocity(vec) - end - end - end - end - end -end - -local plane_adjacents = { - vector.new(1,0,0), - vector.new(-1,0,0), - vector.new(0,0,1), - vector.new(0,0,-1), -} - -function mcl_mobs:gopath(self,target,callback_arrived) - local p = self.object:get_pos() - local t = vector.offset(target,0,1,0) - local wp = minetest.find_path(p,t,150,1,4) - if not wp then - local d = minetest.find_node_near(target,16,{"group:door"}) - if d then - for _,v in pairs(plane_adjacents) do - local pos = vector.add(d,v) - local n = minetest.get_node(pos) - if n.name == "air" then - wp = minetest.find_path(p,pos,150,1,4) - if wp then break end - end - end - end - end - if wp and #wp > 0 then - self._target = t - self.callback_arrived = callback_arrived - self.waypoints = wp - self.state = "gowp" - return true - else - --minetest.log("no path found") - end -end - -local function player_near(pos) - for _,o in pairs(minetest.get_objects_inside_radius(pos,2)) do - if o:is_player() then return true end - end -end - -local function check_item_pickup(self) - if self.pick_up and #self.pick_up > 0 then - local p = self.object:get_pos() - for _,o in pairs(minetest.get_objects_inside_radius(p,2)) do - local l=o:get_luaentity() - if l and l.name == "__builtin:item" then - for k,v in pairs(self.pick_up) do - if not player_near(p) and self.on_pick_up and l.itemstring:find(v) then - if self.on_pick_up(self,l) == nil then o:remove() end - end - end - end - end - end -end - -local function damage_mob(self,reason,damage) - if not self.health then return 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, reason, {type = reason}) then - return true - end - end -end - -local function check_entity_cramming(self) - local p = self.object:get_pos() - local oo = minetest.get_objects_inside_radius(p,1) - local mobs = {} - for _,o in pairs(oo) do - local l = o:get_luaentity() - if l and l.is_mob and l.health > 0 then table.insert(mobs,l) end - end - local clear = #mobs < ENTITY_CRAMMING_MAX - local ncram = {} - for _,l in pairs(mobs) do - if l then - if clear then - l.cram = nil - elseif l.cram == nil and not self.child then - table.insert(ncram,l) - elseif l.cram then - damage_mob(l,"cramming",CRAMMING_DAMAGE) - end - end - end - for i,l in pairs(ncram) do - if i > ENTITY_CRAMMING_MAX then - l.cram = true - else - l.cram = nil - end - end -end - --- falling and fall damage --- returns true if mob died -local falling = function(self, pos) - - if self.fly and self.state ~= "die" then - return - end - - if mcl_portals ~= nil then - if mcl_portals.nether_portal_cooloff(self.object) then - return false -- mob has teleported through Nether portal - it's 99% not falling - end - end - - -- floating in water (or falling) - local v = self.object:get_velocity() - - if v.y > 0 then - - -- apply gravity when moving up - self.object:set_acceleration({ - x = 0, - y = -10, - z = 0 - }) - - elseif v.y <= 0 and v.y > self.fall_speed then - - -- fall downwards at set speed - self.object:set_acceleration({ - x = 0, - y = self.fall_speed, - z = 0 - }) - else - -- stop accelerating once max fall speed hit - self.object:set_acceleration({x = 0, y = 0, z = 0}) - end - - 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 / (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_mob(self,"fall",damage) - end - - self.old_y = self.object:get_pos().y - end - end -end - -local teleport = function(self, target) - if self.do_teleport then - if self.do_teleport(self, target) == false then - return - end - end -end - - --- deal damage and effects when mob punched -local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) - - -- custom punch function - if self.do_punch then - - -- when false skip going any further - if self.do_punch(self, hitter, tflp, tool_capabilities, dir) == false then - return - end - end - - -- error checking when mod profiling is enabled - if not tool_capabilities then - minetest.log("warning", "[mobs] Mod profiling enabled, damage not enabled") - return - end - - local is_player = hitter:is_player() - - if is_player then - -- is mob protected? - if self.protected and minetest.is_protected(self.object:get_pos(), hitter:get_player_name()) then - return - end - - -- set/update 'drop xp' timestamp if hitted by player - self.xp_timestamp = minetest.get_us_time() - end - - - -- punch interval - local weapon = hitter:get_wielded_item() - local punch_interval = 1.4 - - -- exhaust attacker - if is_player then - mcl_hunger.exhaust(hitter:get_player_name(), mcl_hunger.EXHAUST_ATTACK) - end - - -- calculate mob damage - local damage = 0 - local armor = self.object:get_armor_groups() or {} - local tmp - - -- quick error check incase it ends up 0 (serialize.h check test) - if tflp == 0 then - tflp = 0.2 - end - - - for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do - - tmp = tflp / (tool_capabilities.full_punch_interval or 1.4) - - if tmp < 0 then - tmp = 0.0 - elseif tmp > 1 then - tmp = 1.0 - end - - damage = damage + (tool_capabilities.damage_groups[group] or 0) - * tmp * ((armor[group] or 0) / 100.0) - end - - if weapon then - local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect") - if fire_aspect_level > 0 then - mcl_burning.set_on_fire(self.object, fire_aspect_level * 4) - end - end - - -- check for tool immunity or special damage - for n = 1, #self.immune_to do - - if self.immune_to[n][1] == weapon:get_name() then - - damage = self.immune_to[n][2] or 0 - break - end - end - - -- healing - if damage <= -1 then - self.health = self.health - floor(damage) - return - end - - if tool_capabilities then - punch_interval = tool_capabilities.full_punch_interval or 1.4 - end - - -- add weapon wear manually - -- Required because we have custom health handling ("health" property) - if minetest.is_creative_enabled("") ~= true - and tool_capabilities then - if tool_capabilities.punch_attack_uses then - -- Without this delay, the wear does not work. Quite hacky ... - minetest.after(0, function(name) - local player = minetest.get_player_by_name(name) - if not player then return end - local weapon = hitter:get_wielded_item(player) - local def = weapon:get_definition() - if def.tool_capabilities and def.tool_capabilities.punch_attack_uses then - local wear = 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 mcl_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 + if spawn_logging then + minetest.log("action", "[mcl_mobs] Mob "..tostring(self.name).." despawns at "..minetest.pos_to_string(vector.round(self.object:get_pos())) .. " - out of range") + end - minetest.log("action", "Mob "..name.." despawns in mob_staticdata at "..minetest.pos_to_string(self.object.get_pos(), 1)) - mcl_burning.extinguish(self.object) - self.object:remove() - - return ""-- nil + return "remove"-- nil end ---]] + self.remove_ok = true self.attack = nil self.following = nil @@ -3408,20 +109,19 @@ local mob_staticdata = function(self) return minetest.serialize(tmp) end - --- activate mob and reload settings -local mob_activate = function(self, staticdata, def, dtime) - - -- remove monsters in peaceful mode +function mob_class:mob_activate(staticdata, def, dtime) + if not self.object:get_pos() or staticdata == "remove" then + mcl_burning.extinguish(self.object) + self.object:remove() + return + end if self.type == "monster" and minetest.settings:get_bool("only_peaceful_mobs", false) then mcl_burning.extinguish(self.object) self.object:remove() - return end - -- load entity variables local tmp = minetest.deserialize(staticdata) if tmp then @@ -3430,7 +130,6 @@ local mob_activate = function(self, staticdata, def, dtime) end end - -- select random texture, set model and size if not self.base_texture then -- compatiblity with old simple mobs textures @@ -3438,38 +137,36 @@ local mob_activate = function(self, staticdata, def, dtime) def.textures = {def.textures} end - self.base_texture = def.textures[random(1, #def.textures)] + local c = 1 + if #def.textures > c then c = #def.textures end + + self.base_texture = def.textures[math.random(c)] 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 = { @@ -3500,13 +197,12 @@ local mob_activate = function(self, staticdata, def, dtime) end if self.health == 0 then - self.health = random (self.hp_min, self.hp_max) + self.health = math.random (self.hp_min, self.hp_max) end if self.breath == nil then self.breath = self.breath_max end - -- pathfinding init self.path = {} self.path.way = {} -- path to follow, table of positions self.path.lastpos = {x = 0, y = 0, z = 0} @@ -3546,129 +242,83 @@ local mob_activate = function(self, staticdata, def, dtime) self.blinktimer = 0 self.blinkstatus = false - -- check existing nametag if not self.nametag then self.nametag = def.nametag end - - -- set anything changed above - self.object:set_properties(self) - set_yaw(self, (random(0, 360) - 180) / 180 * pi, 6) - update_tag(self) - set_animation(self, "stand") - - -- run on_spawn function if found - if self.on_spawn and not self.on_spawn_run then - if self.on_spawn(self) then - self.on_spawn_run = true -- if true, set flag to run once only + if not self.custom_visual_size then + self.visual_size = nil + self.base_size = self.visual_size + if self.child then + self.visual_size = { + x = self.visual_size.x * 0.5, + y = self.visual_size.y * 0.5, + } end end - -- run after_activate + self.object:set_properties(self) + self:set_yaw( (math.random(0, 360) - 180) / 180 * math.pi, 6) + self:update_tag() + self._current_animation = nil + self:set_animation( "stand") + + if self.on_spawn and not self.on_spawn_run then + if self.on_spawn(self) then + self.on_spawn_run = true + end + end + + if not self.wears_armor and self.armor_list then + self.armor_list = nil + end + + if not self._run_armor_init and self.wears_armor then + self.armor_list={helmet="",chestplate="",boots="",leggings=""} + self:set_armor_texture() + self._run_armor_init = true + end + if def.after_activate then def.after_activate(self, staticdata, def, dtime) end end +-- execute current state (stand, walk, run, attacks) +-- returns true if mob has died +function mob_class:do_states(dtime) + --if self.can_open_doors then check_doors(self) end --- main mob function -local mob_step = function(self, dtime) - check_item_pickup(self) - if not self.fire_resistant then - mcl_burning.tick(self.object, dtime, self) - 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 + if self.state == "stand" then + self:do_states_stand() + elseif self.state == PATHFINDING then + self:check_gowp(dtime) + elseif self.state == "walk" then + self:do_states_walk() + elseif self.state == "runaway" then + -- runaway when punched + self:do_states_runaway() + elseif self.state == "attack" then + -- attack routines (explode, dogfight, shoot, dogshoot) + if self:do_states_attack(dtime) then + return true end end +end +local function update_timers (self, dtime) -- knockback timer if self.pause_timer > 0 then - self.pause_timer = self.pause_timer - dtime - - return + return true end -- attack timer self.timer = self.timer + dtime - if self.state ~= "attack" and self.state ~= "gowp" then + if self.state ~= "attack" and self.state ~= PATHFINDING then if self.timer < 1 then - return + return true end - self.timer = 0 end @@ -3676,808 +326,83 @@ local mob_step = function(self, dtime) if self.timer > 100 then self.timer = 1 end +end - -- mob plays random sound at times - if random(1, 70) == 1 then - mob_sound(self, "random", true) +-- main mob function +function mob_class:on_step(dtime) + self.lifetimer = self.lifetimer - dtime + + local pos = self.object:get_pos() + if not pos then return end + + if self:check_despawn(pos) then return true end + + self:slow_mob() + if self:falling(pos) then return end + + self:check_suspend() + self:check_water_flow() + + self:env_danger_movement_checks (dtime) + + if not self.fire_resistant then + mcl_burning.tick(self.object, dtime, self) + -- mcl_burning.tick may remove object immediately + if not self.object:get_pos() then return end end - -- environmental damage timer (every 1 second) - self.env_damage_timer = self.env_damage_timer + dtime + if mobs_debug then self:update_tag() end - if (self.state == "attack" and self.env_damage_timer > 1) - or self.state ~= "attack" then - check_entity_cramming(self) - self.env_damage_timer = 0 + if self.state == "die" then return end - -- check for environmental damage (water, fire, lava etc.) - if do_env_damage(self) then + 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 + + --Mob following code. + self:follow_flop() + --set animation speed relitive to velocity + self:set_animation_speed() + self:check_smooth_rotation(dtime) + self:check_head_swivel(dtime) + + self:do_jump() + self:set_armor_texture() + self:check_runaway_from() + + self:monster_attack() + self:npc_attack() + self:check_breeding() + self:check_aggro(dtime) + + -- run custom function (defined in mob lua file) + if self.do_custom then + if self.do_custom(self, dtime) == false then return end - - -- node replace check (cow eats grass etc.) - replace(self, pos) end - monster_attack(self) + if update_timers(self, dtime) then return end - npc_attack(self) + self:check_particlespawners(dtime) + self:check_item_pickup() - breed(self) - - if do_states(self, dtime) then - return + -- mob plays random sound at times. Should be 120. Zombie and mob farms are ridiculous + if math.random(1, 70) == 1 then + self:mob_sound("random", true) end + if self:env_damage (dtime, pos) then return end + if self:do_states(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" - set_animation(self, "stand") - local yaw = self.object:get_yaw() or 0 - yaw = set_yaw(self, yaw + 0.78, 8) - end - - -- Despawning: when lifetimer expires, remove mob - if remove_far - and self.can_despawn == true - and ((not self.nametag) or (self.nametag == "")) - and self.state ~= "attack" - and self.following == nil then - - self.lifetimer = self.lifetimer - dtime - if self.despawn_immediately or self.lifetimer <= 0 then - minetest.log("action", "Mob "..self.name.." despawns in mob_step at "..minetest.pos_to_string(pos, 1)) - mcl_burning.extinguish(self.object) - self.object:remove() - elseif self.lifetimer <= 10 then - if math.random(10) < 4 then - self.despawn_immediately = true - else - self.lifetimer = 20 - end - end - end end - --- default function when mobs are blown up with TNT -local do_tnt = function(obj, damage) - - obj.object:punch(obj.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = damage}, - }, nil) - - return false, true, {} -end - - -mcl_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 minetest.is_creative_enabled(clicker:get_player_name()) then - item:take_item() - clicker:set_wielded_item(item) - end - return true - end - - end - return false -end - -local create_mob_on_rightclick = function(on_rightclick) - return function(self, clicker) - local stop = on_rightclick_prefix(self, clicker) - if (not stop) and (on_rightclick) then - on_rightclick(self, clicker) - end - end -end - --- register mob entity -function mcl_mobs:register_mob(name, def) - - mcl_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, - nofollow = def.nofollow, - can_open_doors = def.can_open_doors, - 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, - 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, - pick_up = def.pick_up, - explosion_strength = def.explosion_strength, - suffocation_timer = 0, - follow_velocity = def.follow_velocity or 2.4, - instant_death = def.instant_death or false, - fire_resistant = def.fire_resistant or false, - fire_damage_resistant = def.fire_damage_resistant or false, - ignited_by_sunlight = def.ignited_by_sunlight or false, - -- 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_pick_up = def.on_pick_up, - - 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.is_mob = true - 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 mcl_mobs:register_mob function - - --- register arrow for shoot attack -function mcl_mobs:register_arrow(name, def) - - if not name or not def then return end -- errorcheck - - minetest.register_entity(name, { - - physical = false, - visual = def.visual, - visual_size = def.visual_size, - textures = def.textures, - velocity = def.velocity, - hit_player = def.hit_player, - hit_node = def.hit_node, - hit_mob = def.hit_mob, - hit_object = def.hit_object, - drop = def.drop or false, -- drops arrow as registered item when true - collisionbox = {0, 0, 0, 0, 0, 0}, -- remove box around arrows - timer = 0, - switch = 0, - owner_id = def.owner_id, - rotate = def.rotate, - on_punch = function(self) - local vel = self.object:get_velocity() - self.object:set_velocity({x=vel.x * -1, y=vel.y * -1, z=vel.z * -1}) - end, - collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0}, - automatic_face_movement_dir = def.rotate - and (def.rotate - (pi / 180)) or false, - - on_activate = def.on_activate, - - on_step = def.on_step or function(self, dtime) - - self.timer = self.timer + 1 - - local pos = self.object:get_pos() - - if self.switch == 0 - or self.timer > 150 - or not within_limits(pos, 0) then - mcl_burning.extinguish(self.object) - self.object:remove(); - - return - end - - -- does arrow have a tail (fireball) - if def.tail - and def.tail == 1 - and def.tail_texture then - - minetest.add_particle({ - pos = pos, - velocity = {x = 0, y = 0, z = 0}, - acceleration = {x = 0, y = 0, z = 0}, - expirationtime = def.expire or 0.25, - collisiondetection = false, - texture = def.tail_texture, - size = def.tail_size or 5, - glow = def.glow or 0, - }) - end - - if self.hit_node then - - local node = node_ok(pos).name - - if minetest.registered_nodes[node].walkable then - - self.hit_node(self, pos, node) - - if self.drop == true then - - pos.y = pos.y + 1 - - self.lastpos = (self.lastpos or pos) - - minetest.add_item(self.lastpos, self.object:get_luaentity().name) - end - - self.object:remove(); - - return - end - end - - if self.hit_player or self.hit_mob or self.hit_object then - - for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do - - if self.hit_player - and player:is_player() then - - self.hit_player(self, player) - self.object:remove(); - return - end - - local entity = player:get_luaentity() - - if entity - and self.hit_mob - and entity.is_mob == true - and tostring(player) ~= self.owner_id - and entity.name ~= self.object:get_luaentity().name then - self.hit_mob(self, player) - self.object:remove(); - return - end - - if entity - and self.hit_object - and (not entity.is_mob) - and tostring(player) ~= self.owner_id - and entity.name ~= self.object:get_luaentity().name then - self.hit_object(self, player) - self.object:remove(); - return - end - end - end - - self.lastpos = pos - end - }) -end - - --- no damage to nodes explosion -function mcl_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 mcl_mobs:boom(self, pos, strength, fire) - if mobs_griefing and not minetest.is_protected(pos, "") then - mcl_explosions.explode(pos, strength, { drop_chance = 1.0, fire = fire }, self.object) - else - mcl_mobs: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 mcl_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 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 minetest.is_creative_enabled(name) then - itemstack:take_item() - end - return itemstack - end - - if not minetest.registered_entities[mob] then - return itemstack - end - - if minetest.settings:get_bool("only_peaceful_mobs", false) - and minetest.registered_entities[mob].type == "monster" then - minetest.chat_send_player(name, S("Only peaceful mobs allowed!")) - return itemstack - end - - pos.y = pos.y - 0.5 - - local mob = minetest.add_entity(pos, mob) - 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 minetest.is_creative_enabled(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 mcl_mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith) - return false -end - - --- No-op in MCL2 (protecting mobs is not possible). -function mcl_mobs:protect(self, clicker) - return false -end - - --- feeding, taming and breeding (thanks blert2112) -function mcl_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 self.nofollow or follow_holding(self, clicker) then - - -- if not in creative then take item - if not minetest.is_creative_enabled(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 mcl_mobs:spawn_child(pos, mob_type) - local child = minetest.add_entity(pos, mob_type) - if not child then - return - end - - local ent = child:get_luaentity() - 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 mcl_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 @@ -4494,3 +419,22 @@ minetest.register_globalstep(function(dtime) end timer = 0 end) + +minetest.register_chatcommand("clearmobs",{ + privs={maphack=true}, + params = "||", + description=S("Removes all spawned mobs except nametagged and tamed ones. all removes all mobs, nametagged only nametagged ones and with the range paramter all mobs in a distance of the current player are removed."), + func=function(n,param) + local p = minetest.get_player_by_name(n) + local num=tonumber(param) + for _,o in pairs(minetest.luaentities) do + if o.is_mob then + if param == "all" or + ( param == "nametagged" and o.nametag ) or + ( param == "" and ( not o.nametag or o.nametag == "" ) and not o.tamed ) or + ( num and num > 0 and vector.distance(p:get_pos(),o.object:get_pos()) <= num ) then + o.object:remove() + end + end + end +end}) diff --git a/mods/ENTITIES/mcl_mobs/api.txt b/mods/ENTITIES/mcl_mobs/api.txt index b9b6613b6..5b5809bca 100644 --- a/mods/ENTITIES/mcl_mobs/api.txt +++ b/mods/ENTITIES/mcl_mobs/api.txt @@ -258,7 +258,10 @@ functions needed for the mob to work properly which contains the following: 'nofollow' Do not follow players when they wield the "follow" item. For mobs (like villagers) that are bred in a different way. 'pick_up' table of itemstrings the mob will pick up (e.g. for breeding) - 'on_pick_up' function that will be called on item pickup - return true to not pickup the item + 'on_pick_up' function that will be called on item pickup - arguments are self and the itementity return a (modified) itemstack + 'custom_visual_size' will not reset visual_size from the base class on reload + 'noyaw' If true this mob will not automatically change yaw + 'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners. mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival @@ -433,7 +436,7 @@ true the mob will not spawn. MineClone 2 extensions ---------------------- -mobs:spawn_child(pos, mob_type) +mcl_mobs:spawn_child(pos, mob_type) This function spawns a mob as a child. The parameter mob_type is the entitystring of the new mob. @@ -443,6 +446,7 @@ mobs:death_effect(pos, collisionbox) Create death particles at pos with the given collisionbox. +mcl_mobs.spawn(pos,name/entity name) Making Arrows ------------- @@ -484,13 +488,13 @@ This function registers a arrow for mobs with the attack type shoot. Spawn Eggs ---------- -mobs:register_egg(name, description, background, addegg, no_creative) +mobs:register_egg(name, description, background_color, overlay_color, addegg, no_creative) This function registers a spawn egg which can be used by admin to properly spawn in a mob. 'name' this is the name of your new mob to spawn e.g. "mob:sheep" 'description' the name of the new egg you are creating e.g. "Spawn Sheep" - 'background'the texture displayed for the egg in inventory + 'background_color' and 'overlay_color' define the colors for the texture displayed for the egg in inventory 'addegg' would you like an egg image in front of your texture (1 = yes, 0 = no) 'no_creative' when set to true this stops spawn egg appearing in creative diff --git a/mods/ENTITIES/mcl_mobs/breeding.lua b/mods/ENTITIES/mcl_mobs/breeding.lua new file mode 100644 index 000000000..33e05f23b --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/breeding.lua @@ -0,0 +1,351 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +local HORNY_TIME = 30 +local HORNY_AGAIN_TIME = 300 +local CHILD_GROW_TIME = 60*20 + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false) + +local LOG_MODULE = "[mcl_mobs]" +local function mcl_log (message) + if LOGGING_ON and message then + minetest.log(LOG_MODULE .. " " .. message) + end +end + +-- No-op in MCL2 (capturing mobs is not possible). +-- Provided for compability with Mobs Redo +function mcl_mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith) + return false +end + + +-- No-op in MCL2 (protecting mobs is not possible). +function mcl_mobs:protect(self, clicker) + return false +end + + +-- feeding, taming and breeding (thanks blert2112) +function mob_class:feed_tame(clicker, feed_count, breed, tame, notake) + if not self.follow then + return false + end + -- can eat/tame with item in hand + if self.nofollow or self:follow_holding(clicker) then + local consume_food = false + + -- tame if not still a baby + + if tame and not self.child then + if not self.owner or self.owner == "" then + self.tamed = true + self.owner = clicker:get_player_name() + consume_food = true + end + end + + -- increase health + + if self.health < self.hp_max and not consume_food then + consume_food = true + self.health = math.min(self.health + 4, self.hp_max) + + if self.htimer < 1 then + self.htimer = 5 + end + self.object:set_hp(self.health) + end + + -- make children grow quicker + + if not consume_food and self.child == true then + consume_food = true + -- deduct 10% of the time to adulthood + self.hornytimer = self.hornytimer + ((CHILD_GROW_TIME - self.hornytimer) * 0.1) + end + + -- breed animals + + if breed and not consume_food and self.hornytimer == 0 and not self.horny then + self.food = (self.food or 0) + 1 + consume_food = true + if self.food >= feed_count then + self.food = 0 + self.horny = true + end + end + + self:update_tag() + -- play a sound if the animal used the item and take the item if not in creative + if consume_food then + -- don't consume food if clicker is in creative + if not minetest.is_creative_enabled(clicker:get_player_name()) and not notake then + local item = clicker:get_wielded_item() + item:take_item() + clicker:set_wielded_item(item) + end + -- always play the eat sound if food is used, even in creative + self:mob_sound("eat", nil, true) + + else + -- make sound when the mob doesn't want food + self:mob_sound("random", true) + end + return true + end + return false +end + +-- Spawn a child +function mcl_mobs.spawn_child(pos, mob_type) + local child = minetest.add_entity(pos, mob_type) + if not child then + return + end + + local ent = child:get_luaentity() + mcl_mobs.effect(pos, 15, "mcl_particles_smoke.png", 1, 2, 2, 15, 5) + + ent.child = true + + local textures + -- using specific child texture (if found) + if ent.child_texture then + textures = ent.child_texture[1] + end + + -- and resize to half height + child:set_properties({ + textures = textures, + visual_size = { + x = ent.base_size.x * .5, + y = ent.base_size.y * .5, + }, + collisionbox = { + ent.base_colbox[1] * .5, + ent.base_colbox[2] * .5, + ent.base_colbox[3] * .5, + ent.base_colbox[4] * .5, + ent.base_colbox[5] * .5, + ent.base_colbox[6] * .5, + }, + selectionbox = { + ent.base_selbox[1] * .5, + ent.base_selbox[2] * .5, + ent.base_selbox[3] * .5, + ent.base_selbox[4] * .5, + ent.base_selbox[5] * .5, + ent.base_selbox[6] * .5, + }, + }) + + ent.animation = ent._child_animations + ent._current_animation = nil + ent:set_animation("stand") + + return child +end + +-- find two animals of same type and breed if nearby and horny +function mob_class:check_breeding() + + --mcl_log("In breed function") + -- child takes a long time before growing into adult + if self.child == true then + + -- When a child, hornytimer is used to count age until adulthood + self.hornytimer = self.hornytimer + 1 + + if self.hornytimer >= CHILD_GROW_TIME then + + self.child = false + self.hornytimer = 0 + + self.object:set_properties({ + textures = self.base_texture, + mesh = self.base_mesh, + visual_size = self.base_size, + collisionbox = self.base_colbox, + selectionbox = self.base_selbox, + }) + + -- custom function when child grows up + if self.on_grown then + self.on_grown(self) + else + -- jump when fully grown so as not to fall into ground + self.object:set_velocity({ + x = 0, + y = self.jump_height*3, + z = 0 + }) + end + + self.animation = nil + local anim = self._current_animation + self._current_animation = nil -- Mobs Redo does nothing otherwise + self:set_animation(anim) + end + + return + end + + -- horny animal can mate for HORNY_TIME seconds, + -- afterwards horny animal cannot mate again for HORNY_AGAIN_TIME seconds + if self.horny == true + and self.hornytimer < HORNY_TIME + HORNY_AGAIN_TIME then + + self.hornytimer = self.hornytimer + 1 + + if self.hornytimer >= HORNY_TIME + HORNY_AGAIN_TIME then + self.hornytimer = 0 + self.horny = false + end + end + + -- find another same animal who is also horny and mate if nearby + if self.horny == true + and self.hornytimer <= HORNY_TIME then + + mcl_log("In breed function. All good. Do the magic.") + + local pos = self.object:get_pos() + + mcl_mobs.effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8, "heart.png", 3, 4, 1, 0.1) + + local objs = minetest.get_objects_inside_radius(pos, 3) + local num = 0 + local ent = nil + + for n = 1, #objs do + + ent = objs[n]:get_luaentity() + + -- check for same animal with different colour + local canmate = false + + if ent then + + if ent.name == self.name then + canmate = true + else + local entname = string.split(ent.name,":") + local selfname = string.split(self.name,":") + + if entname[1] == selfname[1] then + entname = string.split(entname[2],"_") + selfname = string.split(selfname[2],"_") + + if entname[1] == selfname[1] then + canmate = true + end + end + end + end + + if canmate then mcl_log("In breed function. Can mate.") end + + if ent + and canmate == true + and ent.horny == true + and ent.hornytimer <= HORNY_TIME then + num = num + 1 + end + + -- found your mate? then have a baby + if num > 1 then + + self.hornytimer = HORNY_TIME + 1 + ent.hornytimer = HORNY_TIME + 1 + + -- spawn baby + + + minetest.after(5, function(parent1, parent2, pos) + if not parent1.object:get_luaentity() then + return + end + if not parent2.object:get_luaentity() then + return + end + + mcl_experience.throw_xp(pos, math.random(1, 7)) + + -- custom breed function + if parent1.on_breed then + -- when false, skip going any further + if parent1.on_breed(parent1, parent2) == false then + return + end + end + + local child = mcl_mobs.spawn_child(pos, parent1.name) + + local ent_c = child:get_luaentity() + + + -- Use texture of one of the parents + local p = math.random(1, 2) + if p == 1 then + ent_c.base_texture = parent1.base_texture + else + ent_c.base_texture = parent2.base_texture + end + child:set_properties({ + textures = ent_c.base_texture + }) + + -- tamed and owned by parents' owner + ent_c.tamed = true + ent_c.owner = parent1.owner + end, self, ent, pos) + + num = 0 + + break + end + end + end +end + +function mob_class:toggle_sit(clicker,p) + if not self.tamed or self.child or self.owner ~= clicker:get_player_name() then + return + end + local pos = self.object:get_pos() + local particle + if not self.order or self.order == "" or self.order == "sit" then + particle = "mobs_mc_wolf_icon_roam.png" + self.order = "roam" + self.state = "stand" + self.walk_chance = default_walk_chance + self.jump = true + self:set_animation("stand") + -- TODO: Add sitting model + else + particle = "mobs_mc_wolf_icon_sit.png" + self.order = "sit" + self.state = "stand" + self.walk_chance = 0 + self.jump = false + if self.animation.sit_start then + self:set_animation("sit") + else + self:set_animation("stand") + end + end + local pp = vector.new(0,1.4,0) + if p then pp = vector.offset(pp,0,p,0) end + -- Display icon to show current order (sit or roam) + minetest.add_particle({ + pos = vector.add(pos, pp), + velocity = {x=0,y=0.2,z=0}, + expirationtime = 1, + size = 4, + texture = particle, + playername = self.owner, + glow = minetest.LIGHT_MAX, + }) +end diff --git a/mods/ENTITIES/mcl_mobs/combat.lua b/mods/ENTITIES/mcl_mobs/combat.lua new file mode 100644 index 000000000..1886c7ccc --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/combat.lua @@ -0,0 +1,1202 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +local damage_enabled = minetest.settings:get_bool("enable_damage") +local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false + +-- pathfinding settings +local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching +local stuck_path_timeout = 10 -- how long will mob follow path before giving up + +local enable_pathfinding = true + +local atann = math.atan +local function atan(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + + +-- check if daytime and also if mob is docile during daylight hours +function mob_class:day_docile() + if self.docile_by_day == false then + return false + elseif self.docile_by_day == true + and self.time_of_day > 0.2 + and self.time_of_day < 0.8 then + return true + end +end + +-- attack player/mob +function mob_class:do_attack(player) + + if self.state == "attack" or self.state == "die" then + return + end + + self.attack = player + self.state = "attack" + + -- TODO: Implement war_cry sound without being annoying + --if random(0, 100) < 90 then + --self:mob_sound("war_cry", true) + --end +end + +-- blast damage to entities nearby +local function entity_physics(pos,radius) + + radius = radius * 2 + + local objs = minetest.get_objects_inside_radius(pos, radius) + local obj_pos, dist + + for n = 1, #objs do + + obj_pos = objs[n]:get_pos() + + dist = vector.distance(pos, obj_pos) + if dist < 1 then dist = 1 end + + local damage = math.floor((4 / dist) * radius) + local ent = objs[n]:get_luaentity() + + -- punches work on entities AND players + objs[n]:punch(objs[n], 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = damage}, + }, pos) + end +end + +function mob_class:entity_physics(pos,radius) return entity_physics(pos,radius) end + +local los_switcher = false +local height_switcher = false + +-- path finding and smart mob routine by rnd, line_of_sight and other edits by Elkien3 +function mob_class:smart_mobs(s, p, dist, dtime) + + local s1 = self.path.lastpos + + local target_pos = self.attack:get_pos() + + -- is it becoming stuck? + if math.abs(s1.x - s.x) + math.abs(s1.z - s.z) < .5 then + self.path.stuck_timer = self.path.stuck_timer + dtime + else + self.path.stuck_timer = 0 + end + + self.path.lastpos = {x = s.x, y = s.y, z = s.z} + + local use_pathfind = false + local has_lineofsight = minetest.line_of_sight( + {x = s.x, y = (s.y) + .5, z = s.z}, + {x = target_pos.x, y = (target_pos.y) + 1.5, z = target_pos.z}, .2) + + -- im stuck, search for path + if not has_lineofsight then + + if los_switcher == true then + use_pathfind = true + los_switcher = false + end -- cannot see target! + else + if los_switcher == false then + + los_switcher = true + use_pathfind = false + + minetest.after(1, function(self) + if not self.object:get_luaentity() then + return + end + if has_lineofsight then self.path.following = false end + end, self) + end -- can see target! + end + + if (self.path.stuck_timer > stuck_timeout and not self.path.following) then + + use_pathfind = true + self.path.stuck_timer = 0 + + minetest.after(1, function(self) + if not self.object:get_luaentity() then + return + end + if has_lineofsight then self.path.following = false end + end, self) + end + + if (self.path.stuck_timer > stuck_path_timeout and self.path.following) then + + use_pathfind = true + self.path.stuck_timer = 0 + + minetest.after(1, function(self) + if not self.object:get_luaentity() then + return + end + if has_lineofsight then self.path.following = false end + end, self) + end + + if math.abs(vector.subtract(s,target_pos).y) > self.stepheight then + + if height_switcher then + use_pathfind = true + height_switcher = false + end + else + if not height_switcher then + use_pathfind = false + height_switcher = true + end + end + + if use_pathfind then + -- lets try find a path, first take care of positions + -- since pathfinder is very sensitive + local sheight = self.collisionbox[5] - self.collisionbox[2] + + -- round position to center of node to avoid stuck in walls + -- also adjust height for player models! + s.x = math.floor(s.x + 0.5) + s.z = math.floor(s.z + 0.5) + + local ssight, sground = minetest.line_of_sight(s, { + x = s.x, y = s.y - 4, z = s.z}, 1) + + -- determine node above ground + if not ssight then + s.y = sground.y + 1 + end + + local p1 = self.attack:get_pos() + + p1.x = math.floor(p1.x + 0.5) + p1.y = math.floor(p1.y + 0.5) + p1.z = math.floor(p1.z + 0.5) + + local dropheight = 12 + if self.fear_height ~= 0 then dropheight = self.fear_height end + local jumpheight = 0 + if self.jump and self.jump_height >= 4 then + jumpheight = math.min(math.ceil(self.jump_height / 4), 4) + elseif self.stepheight > 0.5 then + jumpheight = 1 + end + self.path.way = minetest.find_path(s, p1, 16, jumpheight, dropheight, "A*_noprefetch") + + self.state = "" + self:do_attack(self.attack) + + -- no path found, try something else + if not self.path.way then + + self.path.following = false + + -- lets make way by digging/building if not accessible + if self.pathfinding == 2 and mobs_griefing then + + -- is player higher than mob? + if s.y < p1.y then + + -- build upwards + if not minetest.is_protected(s, "") then + + local ndef1 = minetest.registered_nodes[self.standing_in] + + if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then + + minetest.set_node(s, {name = mcl_mobs.fallback_node}) + end + end + + local sheight = math.ceil(self.collisionbox[5]) + 1 + + -- assume mob is 2 blocks high so it digs above its head + s.y = s.y + sheight + + -- remove one block above to make room to jump + if not minetest.is_protected(s, "") then + + local node1 = node_ok(s, "air").name + local ndef1 = minetest.registered_nodes[node1] + + if node1 ~= "air" + and node1 ~= "ignore" + and ndef1 + and not ndef1.groups.level + and not ndef1.groups.unbreakable + and not ndef1.groups.liquid then + + minetest.set_node(s, {name = "air"}) + minetest.add_item(s, ItemStack(node1)) + + end + end + + s.y = s.y - sheight + self.object:set_pos({x = s.x, y = s.y + 2, z = s.z}) + + else -- dig 2 blocks to make door toward player direction + + local yaw1 = self.object:get_yaw() + math.pi / 2 + local p1 = { + x = s.x + math.cos(yaw1), + y = s.y, + z = s.z + math.sin(yaw1) + } + + if not minetest.is_protected(p1, "") then + + local node1 = node_ok(p1, "air").name + local ndef1 = minetest.registered_nodes[node1] + + if node1 ~= "air" + and node1 ~= "ignore" + and ndef1 + and not ndef1.groups.level + and not ndef1.groups.unbreakable + and not ndef1.groups.liquid then + + minetest.add_item(p1, ItemStack(node1)) + minetest.set_node(p1, {name = "air"}) + end + + p1.y = p1.y + 1 + node1 = node_ok(p1, "air").name + ndef1 = minetest.registered_nodes[node1] + + if node1 ~= "air" + and node1 ~= "ignore" + and ndef1 + and not ndef1.groups.level + and not ndef1.groups.unbreakable + and not ndef1.groups.liquid then + + minetest.add_item(p1, ItemStack(node1)) + minetest.set_node(p1, {name = "air"}) + end + + end + end + end + + -- will try again in 2 seconds + self.path.stuck_timer = stuck_timeout - 2 + elseif s.y < p1.y and (not self.fly) then + self:do_jump() --add jump to pathfinding + self.path.following = true + -- Yay, I found path! + -- TODO: Implement war_cry sound without being annoying + --self:mob_sound("war_cry", true) + else + self:set_velocity(self.walk_velocity) + + -- follow path now that it has it + self.path.following = true + end + end +end + + +-- specific attacks +local specific_attack = function(list, what) + + -- no list so attack default (player, animals etc.) + if list == nil then + return true + end + + -- found entity on list to attack? + for no = 1, #list do + + if list[no] == what then + return true + end + end + + return false +end + +-- find someone to attack +function mob_class:monster_attack() + if not damage_enabled + or self.passive ~= false + or self.state == "attack" + or self:day_docile() then + return + end + + local s = self.object:get_pos() + local p, sp, dist + local player, obj, min_player + local type, name = "", "" + local min_dist = self.view_range + 1 + local objs = minetest.get_objects_inside_radius(s, self.view_range) + local blacklist_attack = {} + + for n = 1, #objs do + if not objs[n]:is_player() then + obj = objs[n]:get_luaentity() + + if obj then + player = obj.object + name = obj.name or "" + end + if obj and obj.type == self.type and obj.passive == false and obj.state == "attack" and obj.attack then + table.insert(blacklist_attack, obj.attack) + end + end + end + + for n = 1, #objs do + + + if objs[n]:is_player() then + if mcl_mobs.invis[ objs[n]:get_player_name() ] or (not self:object_in_range(objs[n])) then + type = "" + elseif (self.type == "monster" or self._aggro) then + player = objs[n] + type = "player" + name = "player" + end + else + obj = objs[n]:get_luaentity() + + if obj then + player = obj.object + type = obj.type + name = obj.name or "" + end + + end + + -- find specific mob to attack, failing that attack player/npc/animal + if specific_attack(self.specific_attack, name) + and (type == "player" or ( type == "npc" and self.attack_npcs ) + or (type == "animal" and self.attack_animals == true)) then + + p = player:get_pos() + sp = s + + dist = vector.distance(p, s) + + -- aim higher to make looking up hills more realistic + p.y = p.y + 1 + sp.y = sp.y + 1 + + local attacked_p = false + for c=1, #blacklist_attack do + if blacklist_attack[c] == player then + attacked_p = true + end + end + -- choose closest player to attack + if dist < min_dist + and not attacked_p + and self:line_of_sight( sp, p, 2) == true then + min_dist = dist + min_player = player + end + end + end + if not min_player and #blacklist_attack > 0 then + min_player=blacklist_attack[math.random(#blacklist_attack)] + end + -- attack player + if min_player then + self:do_attack(min_player) + end +end + + +-- npc, find closest monster to attack +function mob_class:npc_attack() + + if self.type ~= "npc" + or not self.attacks_monsters + or self.state == "attack" then + return + end + + local p, sp, obj, min_player + local s = self.object:get_pos() + local min_dist = self.view_range + 1 + local objs = minetest.get_objects_inside_radius(s, self.view_range) + + for n = 1, #objs do + + obj = objs[n]:get_luaentity() + + if obj and obj.type == "monster" then + + p = obj.object:get_pos() + sp = s + + local dist = vector.distance(p, s) + + -- aim higher to make looking up hills more realistic + p.y = p.y + 1 + sp.y = sp.y + 1 + + if dist < min_dist + and self:line_of_sight( sp, p, 2) == true then + min_dist = dist + min_player = obj.object + end + end + end + + if min_player then + self:do_attack(min_player) + end +end + + + +-- dogshoot attack switch and counter function +function mob_class:dogswitch(dtime) + + -- switch mode not activated + if not self.dogshoot_switch + or not dtime then + return 0 + end + + self.dogshoot_count = self.dogshoot_count + dtime + + if (self.dogshoot_switch == 1 + and self.dogshoot_count > self.dogshoot_count_max) + or (self.dogshoot_switch == 2 + and self.dogshoot_count > self.dogshoot_count2_max) then + + self.dogshoot_count = 0 + + if self.dogshoot_switch == 1 then + self.dogshoot_switch = 2 + else + self.dogshoot_switch = 1 + end + end + + return self.dogshoot_switch +end + +-- no damage to nodes explosion +function mob_class:safe_boom(pos, strength) + minetest.sound_play(self.sounds and self.sounds.explode or "tnt_explode", { + pos = pos, + gain = 1.0, + max_hear_distance = self.sounds and self.sounds.distance or 32 + }, true) + local radius = strength + entity_physics(pos, radius) + mcl_mobs.effect(pos, 32, "mcl_particles_smoke.png", radius * 3, radius * 5, radius, 1, 0) +end + + +-- make explosion with protection and tnt mod check +function mob_class:boom(pos, strength, fire) + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, strength, { drop_chance = 1.0, fire = fire }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, strength) --need to call it this way bc self is the "arrow" object here + end + + -- delete the object after it punched the player to avoid nil entities in e.g. mcl_shields!! + self.object:remove() +end + +-- deal damage and effects when mob punched +function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) + + -- custom punch function + if self.do_punch then + + -- when false skip going any further + if self.do_punch(self, hitter, tflp, tool_capabilities, dir) == false then + return + end + end + + -- error checking when mod profiling is enabled + if not tool_capabilities then + minetest.log("warning", "[mobs] Mod profiling enabled, damage not enabled") + return + end + + local is_player = hitter:is_player() + + if is_player then + -- is mob protected? + if self.protected and minetest.is_protected(self.object:get_pos(), hitter:get_player_name()) then + return + end + + if minetest.is_creative_enabled(hitter:get_player_name()) then + self.health = 0 + end + + -- set/update 'drop xp' timestamp if hitted by player + self.xp_timestamp = minetest.get_us_time() + end + + + -- punch interval + local weapon = hitter:get_wielded_item() + local punch_interval = 1.4 + + -- exhaust attacker + if is_player then + mcl_hunger.exhaust(hitter:get_player_name(), mcl_hunger.EXHAUST_ATTACK) + end + + -- calculate mob damage + local damage = 0 + local armor = self.object:get_armor_groups() or {} + local tmp + + -- quick error check incase it ends up 0 (serialize.h check test) + if tflp == 0 then + tflp = 0.2 + end + + + for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do + + tmp = tflp / (tool_capabilities.full_punch_interval or 1.4) + + if tmp < 0 then + tmp = 0.0 + elseif tmp > 1 then + tmp = 1.0 + end + + damage = damage + (tool_capabilities.damage_groups[group] or 0) + * tmp * ((armor[group] or 0) / 100.0) + end + + if weapon then + local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect") + if fire_aspect_level > 0 then + mcl_burning.set_on_fire(self.object, fire_aspect_level * 4) + end + end + + -- check for tool immunity or special damage + for n = 1, #self.immune_to do + + if self.immune_to[n][1] == weapon:get_name() then + + damage = self.immune_to[n][2] or 0 + break + end + end + + -- healing + if damage <= -1 then + self.health = self.health - math.floor(damage) + return + end + + if tool_capabilities then + punch_interval = tool_capabilities.full_punch_interval or 1.4 + end + + -- add weapon wear manually + -- Required because we have custom health handling ("health" property) + if minetest.is_creative_enabled("") ~= true + and tool_capabilities then + if tool_capabilities.punch_attack_uses then + -- Without this delay, the wear does not work. Quite hacky ... + minetest.after(0, function(name) + local player = minetest.get_player_by_name(name) + if not player then return end + local weapon = hitter:get_wielded_item(player) + local def = weapon:get_definition() + if def.tool_capabilities and def.tool_capabilities.punch_attack_uses then + local wear = math.floor(65535/tool_capabilities.punch_attack_uses) + weapon:add_wear(wear) + hitter:set_wielded_item(weapon) + end + end, hitter:get_player_name()) + end + end + + local die = false + + + if damage >= 0 then + -- only play hit sound and show blood effects if damage is 1 or over; lower to 0.1 to ensure armor works appropriately. + if damage >= 0.1 then + -- weapon sounds + if weapon:get_definition().sounds ~= nil then + + local s = math.random(0, #weapon:get_definition().sounds) + + minetest.sound_play(weapon:get_definition().sounds[s], { + object = self.object, --hitter, + max_hear_distance = 8 + }, true) + else + minetest.sound_play("default_punch", { + object = self.object, + max_hear_distance = 5 + }, true) + end + + self:damage_effect(damage) + + -- do damage + self.health = self.health - damage + + -- skip future functions if dead, except alerting others + if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then + die = true + end + end + -- knock back effect (only on full punch) + if self.knock_back + and tflp >= punch_interval then + -- direction error check + dir = dir or {x = 0, y = 0, z = 0} + + local v = self.object:get_velocity() + if not v then return end + local r = 1.4 - math.min(punch_interval, 1.4) + local kb = r * (math.abs(v.x)+math.abs(v.z)) + local up = 2 + + if die==true then + kb=kb*2 + end + + -- if already in air then dont go up anymore when hit + if math.abs(v.y) > 0.1 + or self.fly then + up = 0 + end + + + -- check if tool already has specific knockback value + if tool_capabilities.damage_groups["knockback"] then + kb = tool_capabilities.damage_groups["knockback"] + else + kb = kb * 1.5 + end + + + local luaentity + if hitter then + luaentity = hitter:get_luaentity() + end + if hitter and is_player then + local wielditem = hitter:get_wielded_item() + kb = kb + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback") + elseif luaentity and luaentity._knockback then + kb = kb + luaentity._knockback + end + self._kb_turn = true + self._turn_to=self.object:get_yaw()-1.57 + self.frame_speed_multiplier=2.3 + if self.animation.run_end then + self:set_animation( "run") + elseif self.animation.walk_end then + self:set_animation( "walk") + end + minetest.after(0.2, function() + if self and self.object then + self.frame_speed_multiplier=1 + self._kb_turn = false + end + end) + self.object:add_velocity({ + x = dir.x * kb, + y = up*2, + z = dir.z * kb + }) + + self.pause_timer = 0.25 + end + end -- END if damage + + -- if skittish then run away + if hitter and is_player and hitter:get_pos() and not die and self.runaway == true and self.state ~= "flop" then + + local yaw = self:set_yaw( minetest.dir_to_yaw(vector.direction(hitter:get_pos(), self.object:get_pos()))) + minetest.after(0.2,function() + if self and self.object and self.object:get_pos() and hitter and is_player and hitter:get_pos() then + yaw = self:set_yaw( minetest.dir_to_yaw(vector.direction(hitter:get_pos(), self.object:get_pos()))) + self:set_velocity( self.run_velocity) + end + end) + self.state = "runaway" + self.runaway_timer = 0 + self.following = nil + end + + local name = hitter:get_player_name() or "" + + -- attack puncher 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 mcl_mobs.invis[ name ] then + if not die then + -- attack whoever punched mob + self.state = "" + self:do_attack(hitter) + self._aggro= true + end + + -- alert others to the attack + local objs = minetest.get_objects_inside_radius(hitter:get_pos(), self.view_range) + local obj = nil + + for n = 1, #objs do + + obj = objs[n]:get_luaentity() + + if obj then + -- only alert members of same mob or friends + if obj.group_attack + and obj.state ~= "attack" + and obj.owner ~= name then + if obj.name == self.name then + obj:do_attack(hitter) + elseif type(obj.group_attack) == "table" then + for i=1, #obj.group_attack do + if obj.name == obj.group_attack[i] then + obj._aggro = true + obj:do_attack(hitter) + break + end + end + end + end + + -- have owned mobs attack player threat + if obj.owner == name and obj.owner_loyal then + obj:do_attack(self.object) + end + end + end + end +end + +function mob_class:check_aggro(dtime) + if not self._aggro or not self.attack then return end + if not self._check_aggro_timer or self._check_aggro_timer > 5 then + self._check_aggro_timer = 0 + if not self.attack:get_pos() or vector.distance(self.attack:get_pos(),self.object:get_pos()) > 128 then + self._aggro = nil + self.attack = nil + self.state = "stand" + end + end + self._check_aggro_timer = self._check_aggro_timer + dtime +end + +function mob_class:do_states_attack (dtime) + local yaw = self.object:get_yaw() or 0 + + local s = self.object:get_pos() + local p = self.attack:get_pos() or s + + -- stop attacking if player invisible or out of range + if not self.attack + or not self.attack:get_pos() + or not self:object_in_range(self.attack) + or self.attack:get_hp() <= 0 + or (self.attack:is_player() and mcl_mobs.invis[ self.attack:get_player_name() ]) then + + self.state = "stand" + self:set_velocity( 0) + self:set_animation( "stand") + self.attack = nil + self.v_start = false + self.timer = 0 + self.blinktimer = 0 + self.path.way = nil + + return + end + + -- calculate distance from mob and enemy + local dist = vector.distance(p, s) + + if self.attack_type == "explode" then + + local vec = { + x = p.x - s.x, + z = p.z - s.z + } + + yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + + if p.x > s.x then yaw = yaw +math.pi end + + yaw = self:set_yaw( yaw, 0, dtime) + + local node_break_radius = self.explosion_radius or 1 + local entity_damage_radius = self.explosion_damage_radius + or (node_break_radius * 2) + + -- start timer when in reach and line of sight + if not self.v_start + and dist <= self.reach + and self:line_of_sight( s, p, 2) then + + self.v_start = true + self.timer = 0 + self.blinktimer = 0 + self:mob_sound("fuse", nil, false) + + -- stop timer if out of reach or direct line of sight + elseif self.allow_fuse_reset + and self.v_start + and (dist >= self.explosiontimer_reset_radius + or not self:line_of_sight( s, p, 2)) then + self.v_start = false + self.timer = 0 + self.blinktimer = 0 + self.blinkstatus = false + self:remove_texture_mod("^[brighten") + end + + -- walk right up to player unless the timer is active + if self.v_start and (self.stop_to_explode or dist < self.reach) then + self:set_velocity( 0) + else + self:set_velocity( self.run_velocity) + end + + if self.animation and self.animation.run_start then + self:set_animation( "run") + else + self:set_animation( "walk") + end + + if self.v_start then + + self.timer = self.timer + dtime + self.blinktimer = (self.blinktimer or 0) + dtime + + if self.blinktimer > 0.2 then + + self.blinktimer = 0 + + if self.blinkstatus then + self:remove_texture_mod("^[brighten") + else + self:add_texture_mod("^[brighten") + end + + self.blinkstatus = not self.blinkstatus + end + + if self.timer > self.explosion_timer then + + local pos = self.object:get_pos() + + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { drop_chance = 1.0 }, self.object) + else + minetest.sound_play(self.sounds.explode, { + pos = pos, + gain = 1.0, + max_hear_distance = self.sounds.distance or 32 + }, true) + self:entity_physics(pos,entity_damage_radius) + mcl_mobs.effect(pos, 32, "mcl_particles_smoke.png", nil, nil, node_break_radius, 1, 0) + end + mcl_burning.extinguish(self.object) + self.object:remove() + + return true + end + end + + elseif self.attack_type == "dogfight" + or (self.attack_type == "dogshoot" and self:dogswitch(dtime) == 2) and (dist >= self.avoid_distance or not self.shooter_avoid_enemy) + or (self.attack_type == "dogshoot" and dist <= self.reach and self:dogswitch() == 0) then + + if self.fly + and dist > self.reach then + + local p1 = s + local me_y = math.floor(p1.y) + local p2 = p + local p_y = math.floor(p2.y + 1) + local v = self.object:get_velocity() + + if self:flight_check( s) then + + if me_y < p_y then + + self.object:set_velocity({ + x = v.x, + y = 1 * self.walk_velocity, + z = v.z + }) + + elseif me_y > p_y then + + self.object:set_velocity({ + x = v.x, + y = -1 * self.walk_velocity, + z = v.z + }) + end + else + if me_y < p_y then + + self.object:set_velocity({ + x = v.x, + y = 0.01, + z = v.z + }) + + elseif me_y > p_y then + + self.object:set_velocity({ + x = v.x, + y = -0.01, + z = v.z + }) + end + end + + end + + -- rnd: new movement direction + if self.path.following + and self.path.way + and self.attack_type ~= "dogshoot" then + + -- no paths longer than 50 + if #self.path.way > 50 + or dist < self.reach then + self.path.following = false + return + end + + local p1 = self.path.way[1] + + if not p1 then + self.path.following = false + return + end + + if math.abs(p1.x-s.x) + math.abs(p1.z - s.z) < 0.6 then + -- reached waypoint, remove it from queue + table.remove(self.path.way, 1) + end + + -- set new temporary target + p = {x = p1.x, y = p1.y, z = p1.z} + end + + local vec = { + x = p.x - s.x, + z = p.z - s.z + } + + yaw = (atan(vec.z / vec.x) + math.pi / 2) - self.rotate + + if p.x > s.x then yaw = yaw + math.pi end + + yaw = self:set_yaw( yaw, 0, dtime) + + -- move towards enemy if beyond mob reach + if dist > self.reach then + + -- path finding by rnd + if self.pathfinding -- only if mob has pathfinding enabled + and enable_pathfinding then + + self:smart_mobs(s, p, dist, dtime) + end + + if self:is_at_cliff_or_danger() then + + self:set_velocity( 0) + self:set_animation( "stand") + local yaw = self.object:get_yaw() or 0 + yaw = self:set_yaw( yaw + 0.78, 8) + else + + if self.path.stuck then + self:set_velocity( self.walk_velocity) + else + self:set_velocity( self.run_velocity) + end + + if self.animation and self.animation.run_start then + self:set_animation( "run") + else + self:set_animation( "walk") + end + end + + else -- rnd: if inside reach range + + self.path.stuck = false + self.path.stuck_timer = 0 + self.path.following = false -- not stuck anymore + + self:set_velocity( 0) + + if not self.custom_attack then + + if self.timer > 1 then + + self.timer = 0 + + if self.double_melee_attack + and math.random(1, 2) == 1 then + self:set_animation( "punch2") + else + self:set_animation( "punch") + end + + local p2 = p + local s2 = s + + p2.y = p2.y + .5 + s2.y = s2.y + .5 + + if self:line_of_sight( p2, s2) == true then + + -- play attack sound + self:mob_sound("attack") + + -- punch player (or what player is attached to) + local attached = self.attack:get_attach() + if attached then + self.attack = attached + end + self.attack:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = self.damage} + }, nil) + end + end + else -- call custom attack every second + if self.custom_attack + and self.timer > 1 then + + self.timer = 0 + + self.custom_attack(self, p) + end + end + end + + elseif self.attack_type == "shoot" + or (self.attack_type == "dogshoot" and self:dogswitch(dtime) == 1) + or (self.attack_type == "dogshoot" and (dist > self.reach or dist < self.avoid_distance and self.shooter_avoid_enemy) and self:dogswitch() == 0) then + + p.y = p.y - .5 + s.y = s.y + .5 + + local dist = vector.distance(p, s) + local vec = { + x = p.x - s.x, + y = p.y - s.y, + z = p.z - s.z + } + + yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + + if p.x > s.x then yaw = yaw +math.pi end + + yaw = self:set_yaw( yaw, 0, dtime) + + local stay_away_from_player = vector.new(0,0,0) + + --strafe back and fourth + + --stay away from player so as to shoot them + if dist < self.avoid_distance and self.shooter_avoid_enemy then + self:set_animation( "shoot") + stay_away_from_player=vector.multiply(vector.direction(p, s), 0.33) + end + + if self.strafes then + if not self.strafe_direction then + self.strafe_direction = 1.57 + end + if math.random(40) == 1 then + self.strafe_direction = self.strafe_direction*-1 + end + self.acc = vector.add(vector.multiply(vector.rotate_around_axis(vector.direction(s, p), vector.new(0,1,0), self.strafe_direction), 0.3*self.walk_velocity), stay_away_from_player) + else + self:set_velocity( 0) + end + + local p = self.object:get_pos() + p.y = p.y + (self.collisionbox[2] + self.collisionbox[5]) / 2 + + if self.shoot_interval + and self.timer > self.shoot_interval + and not minetest.raycast(vector.add(p, vector.new(0,self.shoot_offset,0)), vector.add(self.attack:get_pos(), vector.new(0,1.5,0)), false, false):next() + and math.random(1, 100) <= 60 then + + self.timer = 0 + self:set_animation( "shoot") + + -- play shoot attack sound + self:mob_sound("shoot_attack") + + -- Shoot arrow + if minetest.registered_entities[self.arrow] then + + local arrow, ent + local v = 1 + if not self.shoot_arrow then + self.firing = true + minetest.after(1, function() + self.firing = false + end) + arrow = minetest.add_entity(p, self.arrow) + ent = arrow:get_luaentity() + if ent.velocity then + v = ent.velocity + end + ent.switch = 1 + ent.owner_id = tostring(self.object) -- add unique owner id to arrow + + -- important for mcl_shields + ent._shooter = self.object + ent._saved_shooter_pos = self.object:get_pos() + end + + local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5 + -- offset makes shoot aim accurate + vec.y = vec.y + self.shoot_offset + vec.x = vec.x * (v / amount) + vec.y = vec.y * (v / amount) + vec.z = vec.z * (v / amount) + if self.shoot_arrow then + vec = vector.normalize(vec) + self:shoot_arrow(p, vec) + else + arrow:set_velocity(vec) + end + end + end + else + + end +end diff --git a/mods/ENTITIES/mcl_mobs/compat.lua b/mods/ENTITIES/mcl_mobs/compat.lua new file mode 100644 index 000000000..020a089b2 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/compat.lua @@ -0,0 +1,32 @@ + +-- this is to make the register_mob and register egg functions commonly used by mods not break +-- when they use the weird old : notation AND self as first argument +local oldregmob = mcl_mobs.register_mob +function mcl_mobs.register_mob(self,name,def) + if type(self) == "string" then + def = name + name = self + end + return oldregmob(name,def) +end +local oldregegg = mcl_mobs.register_egg +function mcl_mobs.register_egg(self, mob, desc, background_color, overlay_color, addegg, no_creative) + if type(self) == "string" then + no_creative = addegg + addegg = overlay_color + overlay_color = background_color + background_color = desc + desc = mob + mob = self + end + return oldregegg(mob, desc, background_color, overlay_color, addegg, no_creative) +end + +local oldregarrow = mcl_mobs.register_mob +function mcl_mobs.register_mob(self,name,def) + if type(self) == "string" then + def = name + name = self + end + return oldregarrow(name,def) +end diff --git a/mods/ENTITIES/mcl_mobs/effects.lua b/mods/ENTITIES/mcl_mobs/effects.lua new file mode 100644 index 000000000..81ebdbd2e --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/effects.lua @@ -0,0 +1,385 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class +local active_particlespawners = {} +local disable_blood = minetest.settings:get_bool("mobs_disable_blood") +local DEFAULT_FALL_SPEED = -9.81*1.5 + +local player_transfer_distance = tonumber(minetest.settings:get("player_transfer_distance")) or 128 +if player_transfer_distance == 0 then player_transfer_distance = math.huge end + + +-- custom particle effects +function mcl_mobs.effect(pos, amount, texture, min_size, max_size, radius, gravity, glow, go_down) + + radius = radius or 2 + min_size = min_size or 0.5 + max_size = max_size or 1 + gravity = gravity or DEFAULT_FALL_SPEED + glow = glow or 0 + go_down = go_down or false + + local ym + if go_down then + ym = 0 + else + ym = -radius + end + + minetest.add_particlespawner({ + amount = amount, + time = 0.25, + minpos = pos, + maxpos = pos, + minvel = {x = -radius, y = ym, z = -radius}, + maxvel = {x = radius, y = radius, z = radius}, + minacc = {x = 0, y = gravity, z = 0}, + maxacc = {x = 0, y = gravity, z = 0}, + minexptime = 0.1, + maxexptime = 1, + minsize = min_size, + maxsize = max_size, + texture = texture, + glow = glow, + }) +end + +function mcl_mobs.death_effect(pos, yaw, collisionbox, rotate) + local min, max + if collisionbox then + min = {x=collisionbox[1], y=collisionbox[2], z=collisionbox[3]} + max = {x=collisionbox[4], y=collisionbox[5], z=collisionbox[6]} + else + min = { x = -0.5, y = 0, z = -0.5 } + max = { x = 0.5, y = 0.5, z = 0.5 } + end + if rotate then + min = vector.rotate(min, {x=0, y=yaw, z=math.pi/2}) + max = vector.rotate(max, {x=0, y=yaw, z=math.pi/2}) + min, max = vector.sort(min, max) + min = vector.multiply(min, 0.5) + max = vector.multiply(max, 0.5) + end + + minetest.add_particlespawner({ + amount = 50, + time = 0.001, + minpos = vector.add(pos, min), + maxpos = vector.add(pos, max), + minvel = vector.new(-5,-5,-5), + maxvel = vector.new(5,5,5), + minexptime = 1.1, + maxexptime = 1.5, + minsize = 1, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_mob_death.png^[colorize:#000000:255", + }) + + minetest.sound_play("mcl_mobs_mob_poof", { + pos = pos, + gain = 1.0, + max_hear_distance = 8, + }, true) +end + + +-- play sound +function mob_class:mob_sound(soundname, is_opinion, fixed_pitch) + + local soundinfo + if self.sounds_child and self.child then + soundinfo = self.sounds_child + elseif self.sounds then + soundinfo = self.sounds + end + if not soundinfo then + return + end + local sound = soundinfo[soundname] + if sound then + if is_opinion and self.opinion_sound_cooloff > 0 then + return + end + local pitch + if not fixed_pitch then + local base_pitch = soundinfo.base_pitch + if not base_pitch then + base_pitch = 1 + end + if self.child and (not self.sounds_child) then + -- Children have higher pitch + pitch = base_pitch * 1.5 + else + pitch = base_pitch + end + -- randomize the pitch a bit + pitch = pitch + math.random(-10, 10) * 0.005 + end + -- Should be 0.1 to 0.2 for mobs. Cow and zombie farms loud. At least have cool down. + minetest.sound_play(sound, { + object = self.object, + gain = 1.0, + max_hear_distance = self.sounds.distance, + pitch = pitch, + }, true) + self.opinion_sound_cooloff = 1 + end +end + +function mob_class:add_texture_mod(mod) + local full_mod = "" + local already_added = false + for i=1, #self.texture_mods do + if mod == self.texture_mods[i] then + already_added = true + end + full_mod = full_mod .. self.texture_mods[i] + end + if not already_added then + full_mod = full_mod .. mod + table.insert(self.texture_mods, mod) + end + self.object:set_texture_mod(full_mod) +end + +function mob_class:remove_texture_mod(mod) + local full_mod = "" + local remove = {} + for i=1, #self.texture_mods do + if self.texture_mods[i] ~= mod then + full_mod = full_mod .. self.texture_mods[i] + else + table.insert(remove, i) + end + end + for i=#remove, 1 do + table.remove(self.texture_mods, remove[i]) + end + self.object:set_texture_mod(full_mod) +end + +function mob_class:damage_effect(damage) + -- damage particles + if (not disable_blood) and damage > 0 then + + local amount_large = math.floor(damage / 2) + local amount_small = damage % 2 + + local pos = self.object:get_pos() + + pos.y = pos.y + (self.collisionbox[5] - self.collisionbox[2]) * .5 + + local texture = "mobs_blood.png" + -- full heart damage (one particle for each 2 HP damage) + if amount_large > 0 then + mcl_mobs.effect(pos, amount_large, texture, 2, 2, 1.75, 0, nil, true) + end + -- half heart damage (one additional particle if damage is an odd number) + if amount_small > 0 then + -- TODO: Use "half heart" + mcl_mobs.effect(pos, amount_small, texture, 1, 1, 1.75, 0, nil, true) + end + end +end + +function mob_class:remove_particlespawners(pn) + if not active_particlespawners[pn] then return end + if not active_particlespawners[pn][self.object] then return end + for k,v in pairs(active_particlespawners[pn][self.object]) do + minetest.delete_particlespawner(v) + end +end + +function mob_class:add_particlespawners(pn) + if not active_particlespawners[pn] then active_particlespawners[pn] = {} end + if not active_particlespawners[pn][self.object] then active_particlespawners[pn][self.object] = {} end + for _,ps in pairs(self.particlespawners) do + ps.attached = self.object + ps.playername = pn + table.insert(active_particlespawners[pn][self.object],minetest.add_particlespawner(ps)) + end +end + +function mob_class:check_particlespawners(dtime) + if not self.particlespawners then return end + --minetest.log(dump(active_particlespawners)) + if self._particle_timer and self._particle_timer >= 1 then + self._particle_timer = 0 + local players = {} + for _,player in pairs(minetest.get_connected_players()) do + local pn = player:get_player_name() + table.insert(players,pn) + if not active_particlespawners[pn] then + active_particlespawners[pn] = {} end + + local dst = vector.distance(player:get_pos(),self.object:get_pos()) + if dst < player_transfer_distance and not active_particlespawners[pn][self.object] then + self:add_particlespawners(pn) + elseif dst >= player_transfer_distance and active_particlespawners[pn][self.object] then + self:remove_particlespawners(pn) + end + end + elseif not self._particle_timer then + self._particle_timer = 0 + end + self._particle_timer = self._particle_timer + dtime +end + + +-- set defined animation +function mob_class:set_animation(anim, fixed_frame) + if not self.animation or not anim then + return + end + if self.state == "die" and anim ~= "die" and anim ~= "stand" then + return + end + + if self.jockey then + anim = "jockey" + end + + + if self:flight_check() and self.fly and anim == "walk" then anim = "fly" end + + self._current_animation = self._current_animation or "" + + if (anim == self._current_animation + or not self.animation[anim .. "_start"] + or not self.animation[anim .. "_end"]) and self.state ~= "die" then + return + end + + self._current_animation = anim + + local a_start = self.animation[anim .. "_start"] + local a_end + if fixed_frame then + a_end = a_start + else + a_end = self.animation[anim .. "_end"] + end + if a_start and a_end then + self.object:set_animation({ + x = a_start, + y = a_end}, + self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, + 0, self.animation[anim .. "_loop"] ~= false) + end +end + +-- above function exported for mount.lua +function mcl_mobs:set_animation(self, anim) + self:set_animation(anim) +end + +local function dir_to_pitch(dir) + --local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +function mob_class:check_head_swivel(dtime) + if not self.head_swivel or type(self.head_swivel) ~= "string" then return end + local final_rotation = vector.new(0,0,0) + local oldp,oldr = self.object:get_bone_position(self.head_swivel) + + local pos = self.object:get_pos() + + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 10)) do + if obj:is_player() and not self.attack or obj:get_luaentity() and obj:get_luaentity().name == self.name and self ~= obj:get_luaentity() then + if not self._locked_object then + if math.random(5000/self.curiosity) == 1 or vector.distance(pos,obj:get_pos())<4 and obj:is_player() then + self._locked_object = obj + end + else + if math.random(10000/self.curiosity) == 1 then + self._locked_object = nil + end + end + end + end + + if self.attack or self.following then + self._locked_object = self.attack or self.following + end + + if self._locked_object and (self._locked_object:is_player() or self._locked_object:get_luaentity()) and self._locked_object:get_hp() > 0 then + local _locked_object_eye_height = 1.5 + if self._locked_object:get_luaentity() then + _locked_object_eye_height = self._locked_object:get_luaentity().head_eye_height + end + if self._locked_object:is_player() then + _locked_object_eye_height = self._locked_object:get_properties().eye_height + end + if _locked_object_eye_height then + local self_rot = self.object:get_rotation() + if self.object:get_attach() then + self_rot = self.object:get_attach():get_rotation() + end + if self.rot then + local player_pos = self._locked_object:get_pos() + local direction_player = vector.direction(vector.add(self.object:get_pos(), vector.new(0, self.head_eye_height*.7, 0)), vector.add(player_pos, vector.new(0, _locked_object_eye_height, 0))) + local mob_yaw = math.deg(-(-(self_rot.y)-(-minetest.dir_to_yaw(direction_player))))+self.head_yaw_offset + local mob_pitch = math.deg(-dir_to_pitch(direction_player))*self.head_pitch_multiplier + + if (mob_yaw < -60 or mob_yaw > 60) and not (self.attack and self.state == "attack" and not self.runaway) then + final_rotation = vector.multiply(oldr, 0.9) + elseif self.attack and self.state == "attack" and not self.runaway then + if self.head_yaw == "y" then + final_rotation = vector.new(mob_pitch, mob_yaw, 0) + elseif self.head_yaw == "z" then + final_rotation = vector.new(mob_pitch, 0, -mob_yaw) + end + + else + + if self.head_yaw == "y" then + final_rotation = vector.new(((mob_pitch-oldr.x)*.3)+oldr.x, ((mob_yaw-oldr.y)*.3)+oldr.y, 0) + elseif self.head_yaw == "z" then + final_rotation = vector.new(((mob_pitch-oldr.x)*.3)+oldr.x, 0, -(((mob_yaw-oldr.y)*.3)+oldr.y)*3) + end + end + end + end + elseif not self._locked_object and math.abs(oldr.y) > 3 and math.abs(oldr.x) < 3 then + final_rotation = vector.multiply(oldr, 0.9) + else + final_rotation = vector.new(0,0,0) + end + + mcl_util.set_bone_position(self.object,self.head_swivel, vector.new(0,self.bone_eye_height,self.horrizonatal_head_height), final_rotation) +end + +function mob_class:set_animation_speed() + local v = self.object:get_velocity() + if v then + if self.frame_speed_multiplier then + local v2 = math.abs(v.x)+math.abs(v.z)*.833 + if not self.animation.walk_speed then + self.animation.walk_speed = 25 + end + if math.abs(v.x)+math.abs(v.z) > 0.5 then + self.object:set_animation_frame_speed((v2/math.max(1,self.run_velocity))*self.animation.walk_speed*self.frame_speed_multiplier) + else + self.object:set_animation_frame_speed(25) + end + end + --set_speed + if self.acc then + self.object:add_velocity(self.acc) + end + end +end + +minetest.register_on_leaveplayer(function(player) + local pn = player:get_player_name() + if not active_particlespawners[pn] then return end + for _,m in pairs(active_particlespawners[pn]) do + for k,v in pairs(m) do + minetest.delete_particlespawner(v) + end + end + active_particlespawners[pn] = nil +end) diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index 69246b470..ed3641dc5 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -1,14 +1,566 @@ - -local path = minetest.get_modpath(minetest.get_current_modname()) - --- Mob API +mcl_mobs = {} +mcl_mobs.mob_class = {} +mcl_mobs.mob_class_meta = {__index = mcl_mobs.mob_class} +mcl_mobs.registered_mobs = {} +local modname = minetest.get_current_modname() +local path = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) +mcl_mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt" +--api and helpers +-- effects: sounds and particles mostly +dofile(path .. "/effects.lua") +-- physics: involuntary mob movement - particularly falling and death +dofile(path .. "/physics.lua") +-- movement: general voluntary mob movement, walking avoiding cliffs etc. +dofile(path .. "/movement.lua") +-- items: item management for mobs +dofile(path .. "/items.lua") +-- pathfinding: pathfinding to target positions +dofile(path .. "/pathfinding.lua") +-- combat: attack logic +dofile(path .. "/combat.lua") +-- the enity functions themselves dofile(path .. "/api.lua") --- Spawning Algorithm + +--utility functions +dofile(path .. "/breeding.lua") dofile(path .. "/spawning.lua") - --- Rideable Mobs dofile(path .. "/mount.lua") +dofile(path .. "/crafts.lua") +dofile(path .. "/compat.lua") --- Mob Items -dofile(path .. "/crafts.lua") \ No newline at end of file +local DEFAULT_FALL_SPEED = -9.81*1.5 +local MAX_MOB_NAME_LENGTH = 30 + +local old_spawn_icons = minetest.settings:get_bool("mcl_old_spawn_icons",false) +local extended_pet_control = minetest.settings:get_bool("mcl_extended_pet_control",true) +local difficulty = tonumber(minetest.settings:get("mob_difficulty")) or 1.0 + +-- get node but use fallback for nil or unknown +local node_ok = function(pos, fallback) + fallback = fallback or mcl_mobs.fallback_node + local node = minetest.get_node_or_nil(pos) + if node and minetest.registered_nodes[node.name] then + return node + end + return minetest.registered_nodes[fallback] +end + +--#### REGISTER FUNCS + +-- Code to execute before custom on_rightclick handling +local on_rightclick_prefix = function(self, clicker) + if not clicker:is_player() then return end + local item = clicker:get_wielded_item() + if extended_pet_control and self.tamed and self.owner == clicker:get_player_name() then + self:toggle_sit(clicker) + end + -- Name mob with nametag + if not self.ignores_nametag and item:get_name() == "mcl_mobs:nametag" then + + local tag = item:get_meta():get_string("name") + if tag ~= "" then + if string.len(tag) > MAX_MOB_NAME_LENGTH then + tag = string.sub(tag, 1, MAX_MOB_NAME_LENGTH) + end + self.nametag = tag + + self:update_tag() + + if not minetest.is_creative_enabled(clicker:get_player_name()) then + item:take_item() + clicker:set_wielded_item(item) + end + return true + end + + end + + return false +end + +local create_mob_on_rightclick = function(on_rightclick) + return function(self, clicker) + local stop = on_rightclick_prefix(self, clicker) + if (not stop) and (on_rightclick) then + on_rightclick(self, clicker) + end + end +end + +-- check if within physical map limits (-30911 to 30927) +local function within_limits(pos, radius) + local wmin, wmax = -30912, 30928 + if mcl_vars then + if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then + wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max + end + end + if radius then + wmin = wmin - radius + wmax = wmax + radius + end + for _,v in pairs(pos) do + if v < wmin or v > wmax then return false end + end + return true +end + +mcl_mobs.spawning_mobs = {} +-- register mob entity +function mcl_mobs.register_mob(name, def) + + mcl_mobs.spawning_mobs[name] = true + mcl_mobs.registered_mobs[name] = def + + local can_despawn + if def.can_despawn ~= nil then + can_despawn = def.can_despawn + elseif def.spawn_class == "passive" then + can_despawn = false + else + can_despawn = true + end + + local function scale_difficulty(value, default, min, special) + if (not value) or (value == default) or (value == special) then + return default + else + return math.max(min, value * difficulty) + end + end + + local collisionbox = def.collisionbox or {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25} + -- Workaround for : + -- Increase upper Y limit to avoid mobs glitching through solid nodes. + -- FIXME: Remove workaround if it's no longer needed. + if collisionbox[5] < 0.79 then + collisionbox[5] = 0.79 + end + local final_def = { + use_texture_alpha = def.use_texture_alpha, + head_swivel = def.head_swivel or nil, -- bool to activate this function + head_yaw_offset = def.head_yaw_offset or 0, -- for wonkey model bones + head_pitch_multiplier = def.head_pitch_multiplier or 1, --for inverted pitch + bone_eye_height = def.bone_eye_height or 1.4, -- head bone offset + head_eye_height = def.head_eye_height or def.bone_eye_height or 0, -- how hight aproximatly the mobs head is fromm the ground to tell the mob how high to look up at the player + curiosity = def.curiosity or 1, -- how often mob will look at player on idle + head_yaw = def.head_yaw or "y", -- axis to rotate head on + horrizonatal_head_height = def.horrizonatal_head_height or 0, + wears_armor = def.wears_armor, -- a number value used to index texture slot for armor + stepheight = def.stepheight or 0.6, + name = name, + description = def.description, + type = def.type, + attack_type = def.attack_type, + fly = def.fly or false, + fly_in = def.fly_in or {"air", "__airlike"}, + owner = def.owner or "", + order = def.order or "", + on_die = def.on_die, + spawn_small_alternative = def.spawn_small_alternative, + do_custom = def.do_custom, + detach_child = def.detach_child, + jump_height = def.jump_height or 4, -- was 6 + rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2 + lifetimer = def.lifetimer or 57.73, + hp_min = scale_difficulty(def.hp_min, 5, 1), + hp_max = scale_difficulty(def.hp_max, 10, 1), + xp_min = def.xp_min or 0, + xp_max = def.xp_max or 0, + xp_timestamp = 0, + breath_max = def.breath_max or 15, + breathes_in_water = def.breathes_in_water or false, + physical = true, + collisionbox = collisionbox, + selectionbox = def.selectionbox or def.collisionbox, + visual = def.visual, + visual_size = def.visual_size or {x = 1, y = 1}, + mesh = def.mesh, + makes_footstep_sound = def.makes_footstep_sound or false, + view_range = def.view_range or 16, + walk_velocity = def.walk_velocity or 1, + run_velocity = def.run_velocity or 2, + damage = scale_difficulty(def.damage, 0, 0), + light_damage = def.light_damage or 0, + sunlight_damage = def.sunlight_damage or 0, + water_damage = def.water_damage or 0, + lava_damage = def.lava_damage or 8, + fire_damage = def.fire_damage or 1, + suffocation = def.suffocation or true, + fall_damage = def.fall_damage or 1, + fall_speed = def.fall_speed or DEFAULT_FALL_SPEED, -- must be lower than -2 + drops = def.drops or {}, + armor = def.armor or 100, + on_rightclick = create_mob_on_rightclick(def.on_rightclick), + arrow = def.arrow, + shoot_interval = def.shoot_interval, + sounds = def.sounds or {}, + animation = def.animation or {}, + follow = def.follow, + nofollow = def.nofollow, + can_open_doors = def.can_open_doors, + jump = def.jump ~= false, + automatic_face_movement_max_rotation_per_sec = 300, + walk_chance = def.walk_chance or 50, + attacks_monsters = def.attacks_monsters or false, + group_attack = def.group_attack or false, + passive = def.passive or false, + knock_back = def.knock_back ~= false, + shoot_offset = def.shoot_offset or 0, + floats = def.floats or 1, -- floats in water by default + floats_on_lava = def.floats_on_lava or 0, + replace_rate = def.replace_rate, + replace_what = def.replace_what, + replace_with = def.replace_with, + replace_offset = def.replace_offset or 0, + on_replace = def.on_replace, + timer = 0, + env_damage_timer = 0, + tamed = false, + pause_timer = 0, + horny = false, + hornytimer = 0, + gotten = false, + health = 0, + frame_speed_multiplier = 1, + reach = def.reach or 3, + htimer = 0, + texture_list = def.textures, + child_texture = def.child_texture, + docile_by_day = def.docile_by_day or false, + time_of_day = 0.5, + fear_height = def.fear_height or 0, + runaway = def.runaway, + runaway_timer = 0, + pathfinding = def.pathfinding, + immune_to = def.immune_to or {}, + explosion_radius = def.explosion_radius, -- LEGACY + explosion_damage_radius = def.explosion_damage_radius, -- LEGACY + explosiontimer_reset_radius = def.explosiontimer_reset_radius, + explosion_timer = def.explosion_timer or 3, + allow_fuse_reset = def.allow_fuse_reset ~= false, + stop_to_explode = def.stop_to_explode ~= false, + custom_attack = def.custom_attack, + double_melee_attack = def.double_melee_attack, + dogshoot_switch = def.dogshoot_switch, + dogshoot_count = 0, + dogshoot_count_max = def.dogshoot_count_max or 5, + dogshoot_count2_max = def.dogshoot_count2_max or (def.dogshoot_count_max or 5), + attack_animals = def.attack_animals or false, + attack_npcs = def.attack_npcs or false, + specific_attack = def.specific_attack, + runaway_from = def.runaway_from, + owner_loyal = def.owner_loyal, + facing_fence = false, + is_mob = true, + pushable = def.pushable or true, + + -- MCL2 extensions + shooter_avoid_enemy = def.shooter_avoid_enemy, + strafes = def.strafes, + avoid_distance = def.avoid_distance or 9, + do_teleport = def.do_teleport, + spawn_class = def.spawn_class, + can_spawn = def.can_spawn, + ignores_nametag = def.ignores_nametag or false, + rain_damage = def.rain_damage or 0, + glow = def.glow, + can_despawn = can_despawn, + child = def.child or false, + texture_mods = {}, + shoot_arrow = def.shoot_arrow, + sounds_child = def.sounds_child, + _child_animations = def.child_animations, + pick_up = def.pick_up, + explosion_strength = def.explosion_strength, + suffocation_timer = 0, + follow_velocity = def.follow_velocity or 2.4, + instant_death = def.instant_death or false, + fire_resistant = def.fire_resistant or false, + fire_damage_resistant = def.fire_damage_resistant or false, + ignited_by_sunlight = def.ignited_by_sunlight or false, + spawn_in_group = def.spawn_in_group, + spawn_in_group_min = def.spawn_in_group_min, + noyaw = def.noyaw or false, + particlespawners = def.particlespawners, + -- End of MCL2 extensions + on_spawn = def.on_spawn, + on_blast = def.on_blast or function(self,damage) + self.object:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = damage}, + }, nil) + return false, true, {} + end, + do_punch = def.do_punch, + on_breed = def.on_breed, + on_grown = def.on_grown, + on_pick_up = def.on_pick_up, + on_activate = function(self, staticdata, dtime) + --this is a temporary hack so mobs stop + --glitching and acting really weird with the + --default built in engine collision detection + self.is_mob = true + self.object:set_properties({ + collide_with_objects = false, + }) + + return self:mob_activate(staticdata, def, dtime) + end, + harmed_by_heal = def.harmed_by_heal, + on_lightning_strike = def.on_lightning_strike + } + minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta)) + + if minetest.get_modpath("doc_identifier") ~= nil then + doc.sub.identifier.register_object(name, "basics", "mobs") + end + +end -- END mcl_mobs.register_mob function + + +-- register arrow for shoot attack +function mcl_mobs.register_arrow(name, def) + + if not name or not def then return end -- errorcheck + + minetest.register_entity(name, { + + physical = false, + visual = def.visual, + visual_size = def.visual_size, + textures = def.textures, + velocity = def.velocity, + hit_player = def.hit_player, + hit_node = def.hit_node, + hit_mob = def.hit_mob, + hit_object = def.hit_object, + drop = def.drop or false, -- drops arrow as registered item when true + collisionbox = {0, 0, 0, 0, 0, 0}, -- remove box around arrows + timer = 0, + switch = 0, + owner_id = def.owner_id, + rotate = def.rotate, + on_punch = function(self) + local vel = self.object:get_velocity() + self.object:set_velocity({x=vel.x * -1, y=vel.y * -1, z=vel.z * -1}) + end, + collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0}, + automatic_face_movement_dir = def.rotate + and (def.rotate - (math.pi / 180)) or false, + + on_activate = def.on_activate, + + on_step = def.on_step or function(self, dtime) + + self.timer = self.timer + 1 + + local pos = self.object:get_pos() + + if self.switch == 0 + or self.timer > 150 + or not within_limits(pos, 0) then + mcl_burning.extinguish(self.object) + self.object:remove(); + + return + end + + -- does arrow have a tail (fireball) + if def.tail + and def.tail == 1 + and def.tail_texture then + + minetest.add_particle({ + pos = pos, + velocity = {x = 0, y = 0, z = 0}, + acceleration = {x = 0, y = 0, z = 0}, + expirationtime = def.expire or 0.25, + collisiondetection = false, + texture = def.tail_texture, + size = def.tail_size or 5, + glow = def.glow or 0, + }) + end + + if self.hit_node then + + local node = node_ok(pos).name + + if minetest.registered_nodes[node].walkable then + + self.hit_node(self, pos, node) + + if self.drop == true then + + pos.y = pos.y + 1 + + self.lastpos = (self.lastpos or pos) + + minetest.add_item(self.lastpos, self.object:get_luaentity().name) + end + + self.object:remove(); + + return + end + end + + if self.hit_player or self.hit_mob or self.hit_object then + + for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do + + if self.hit_player + and player:is_player() then + + self.hit_player(self, player) + self.object:remove(); + return + end + + local entity = player:get_luaentity() + + if entity + and self.hit_mob + and entity.is_mob == true + and tostring(player) ~= self.owner_id + and entity.name ~= self.object:get_luaentity().name then + self.hit_mob(self, player) + self.object:remove(); + return + end + + if entity + and self.hit_object + and (not entity.is_mob) + and tostring(player) ~= self.owner_id + and entity.name ~= self.object:get_luaentity().name then + self.hit_object(self, player) + self.object:remove(); + return + end + end + end + + self.lastpos = pos + end + }) +end + +-- Register spawn eggs + +-- Note: This also introduces the “spawn_egg” group: +-- * spawn_egg=1: Spawn egg (generic mob, no metadata) +-- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata) +function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addegg, no_creative) + + local grp = {spawn_egg = 1} + + -- do NOT add this egg to creative inventory (e.g. dungeon master) + if no_creative == true then + grp.not_in_creative_inventory = 1 + end + + local invimg = "(spawn_egg.png^[multiply:" .. background_color ..")^(spawn_egg_overlay.png^[multiply:" .. overlay_color .. ")" + if old_spawn_icons then + local mobname = mob:gsub("mobs_mc:","") + local fn = "mobs_mc_spawn_icon_"..mobname..".png" + if mcl_util.file_exists(minetest.get_modpath("mobs_mc").."/textures/"..fn) then + invimg = fn + end + end + if addegg == 1 then + invimg = "mobs_chicken_egg.png^(" .. invimg .. + "^[mask:mobs_chicken_egg_overlay.png)" + end + + -- register old stackable mob egg + minetest.register_craftitem(mob, { + + description = desc, + inventory_image = invimg, + groups = grp, + + _doc_items_longdesc = S("This allows you to place a single mob."), + _doc_items_usagehelp = S("Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns."), + + on_place = function(itemstack, placer, pointed_thing) + + local pos = pointed_thing.above + + -- am I clicking on something with existing on_rightclick function? + local under = minetest.get_node(pointed_thing.under) + local def = minetest.registered_nodes[under.name] + if def and def.on_rightclick then + return def.on_rightclick(pointed_thing.under, under, placer, itemstack) + end + + if pos + and within_limits(pos, 0) + and not minetest.is_protected(pos, placer:get_player_name()) then + + local name = placer:get_player_name() + local privs = minetest.get_player_privs(name) + if under.name == "mcl_mobspawners:spawner" then + if minetest.is_protected(pointed_thing.under, name) then + minetest.record_protection_violation(pointed_thing.under, name) + return itemstack + end + if not privs.maphack then + minetest.chat_send_player(name, S("You need the “maphack” privilege to change the mob spawner.")) + return itemstack + end + mcl_mobspawners.setup_spawner(pointed_thing.under, itemstack:get_name()) + if not minetest.is_creative_enabled(name) then + itemstack:take_item() + end + return itemstack + end + + if not minetest.registered_entities[mob] then + return itemstack + end + + if minetest.settings:get_bool("only_peaceful_mobs", false) + and minetest.registered_entities[mob].type == "monster" then + minetest.chat_send_player(name, S("Only peaceful mobs allowed!")) + return itemstack + end + + pos.y = pos.y - 0.5 + + local mob = minetest.add_entity(pos, mob) + local entityname = itemstack:get_name() + minetest.log("action", "Player " ..name.." spawned "..entityname.." at "..minetest.pos_to_string(pos)) + local ent = mob:get_luaentity() + + -- don't set owner if monster or sneak pressed + if ent.type ~= "monster" + and not placer:get_player_control().sneak then + ent.owner = placer:get_player_name() + ent.tamed = true + end + + -- set nametag + local nametag = itemstack:get_meta():get_string("name") + if nametag ~= "" then + if string.len(nametag) > MAX_MOB_NAME_LENGTH then + nametag = string.sub(nametag, 1, MAX_MOB_NAME_LENGTH) + end + ent.nametag = nametag + update_tag(ent) + end + + -- if not in creative then take item + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + end + + return itemstack + end, + }) + +end diff --git a/mods/ENTITIES/mcl_mobs/items.lua b/mods/ENTITIES/mcl_mobs/items.lua new file mode 100644 index 000000000..267dd8595 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/items.lua @@ -0,0 +1,103 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class +--- Item and armor management + +local function player_near(pos) + for _,o in pairs(minetest.get_objects_inside_radius(pos,2)) do + if o:is_player() then return true end + end +end + +local function get_armor_texture(armor_name) + if armor_name == "" then + return "" + end + if armor_name=="blank.png" then + return "blank.png" + end + local seperator = string.find(armor_name, ":") + return "mcl_armor_"..string.sub(armor_name, seperator+1, -1)..".png^" +end + +function mob_class:set_armor_texture() + if self.armor_list then + local chestplate=minetest.registered_items[self.armor_list.chestplate] or {name=""} + local boots=minetest.registered_items[self.armor_list.boots] or {name=""} + local leggings=minetest.registered_items[self.armor_list.leggings] or {name=""} + local helmet=minetest.registered_items[self.armor_list.helmet] or {name=""} + + if helmet.name=="" and chestplate.name=="" and leggings.name=="" and boots.name=="" then + helmet={name="blank.png"} + end + local texture = get_armor_texture(chestplate.name)..get_armor_texture(helmet.name)..get_armor_texture(boots.name)..get_armor_texture(leggings.name) + if string.sub(texture, -1,-1) == "^" then + texture=string.sub(texture,1,-2) + end + if self.textures[self.wears_armor] then + self.textures[self.wears_armor]=texture + end + self.object:set_properties({textures=self.textures}) + + local armor_ + if type(self.armor) == "table" then + armor_ = table.copy(self.armor) + armor_.immortal = 1 + else + armor_ = {immortal=1, fleshy = self.armor} + end + + for _,item in pairs(self.armor_list) do + if not item then return end + if type(minetest.get_item_group(item, "mcl_armor_points")) == "number" then + armor_.fleshy=armor_.fleshy-(minetest.get_item_group(item, "mcl_armor_points")*3.5) + end + end + self.object:set_armor_groups(armor_) + end +end + +function mob_class:check_item_pickup() + if self.pick_up and #self.pick_up > 0 or self.wears_armor then + local p = self.object:get_pos() + if not p then return end + for _,o in pairs(minetest.get_objects_inside_radius(p,2)) do + local l=o:get_luaentity() + if l and l.name == "__builtin:item" then + if not player_near(p) and l.itemstring:find("mcl_armor") and self.wears_armor then + local armor_type + if l.itemstring:find("chestplate") then + armor_type = "chestplate" + elseif l.itemstring:find("boots") then + armor_type = "boots" + elseif l.itemstring:find("leggings") then + armor_type = "leggings" + elseif l.itemstring:find("helmet") then + armor_type = "helmet" + end + if not armor_type then + return + end + if not self.armor_list then + self.armor_list={helmet="",chestplate="",boots="",leggings=""} + elseif self.armor_list[armor_type] and self.armor_list[armor_type] ~= "" then + return + end + self.armor_list[armor_type]=ItemStack(l.itemstring):get_name() + o:remove() + end + if self.pick_up then + for k,v in pairs(self.pick_up) do + if not player_near(p) and self.on_pick_up and l.itemstring:find(v) then + local r = self.on_pick_up(self,l) + if r and r.is_empty and not r:is_empty() then + l.itemstring = r:to_string() + elseif r and r.is_empty and r:is_empty() then + o:remove() + end + end + end + end + end + end + end +end diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ja.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ja.tr new file mode 100644 index 000000000..a97d3e545 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ja.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_mobs +Peaceful mode active! No monsters will spawn.=ピースフルモード有効! モンスターは出現しません。 +This allows you to place a single mob.=これにより、1体のMOBを配置できます。 +Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=MOBを出現させたい場所に、置くだけです。スニークキーを押しながら配置しない限り、動物は飼いならされた状態でスポーンします。MOBスポナーに設置すると、スポーンするMOBが変わります。 +You need the “maphack” privilege to change the mob spawner.=MOBスポナーを変更するには、"maphack"権限が必要です。 +Name Tag=名札 +A name tag is an item to name a mob.=名札は、MOBに名前をつけるためのアイテムです。 +Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=名札を使用する前に、金床で名前の設定をする必要があります。その後、MOBに名前をつけるために名札が使えます。これで名札は使い切ります。 +Only peaceful mobs allowed!=平和的なMOBのみ許可! +Give names to mobs=MOBに名前を付与 +Set name at anvil=金床で名前の設定 diff --git a/mods/ENTITIES/mcl_mobs/mount.lua b/mods/ENTITIES/mcl_mobs/mount.lua index 3944613a5..21c52157a 100644 --- a/mods/ENTITIES/mcl_mobs/mount.lua +++ b/mods/ENTITIES/mcl_mobs/mount.lua @@ -1,4 +1,5 @@ - +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class -- lib_mount by Blert2112 (edited by TenPlus1) local enable_crash = false @@ -206,7 +207,7 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) -- move forwards if ctrl.up then - entity.v = entity.v + entity.accel / 10 + entity.v = entity.v + entity.accel / 10 * entity.run_velocity / 2.6 -- move backwards elseif ctrl.down then @@ -385,7 +386,6 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) entity.v2 = v end - -- directional flying routine by D00Med (edited by TenPlus1) function mcl_mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim) @@ -446,3 +446,18 @@ function mcl_mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_an mcl_mobs:set_animation(entity, moving_anim) end end + +mcl_mobs.mob_class.drive = mcl_mobs.drive +mcl_mobs.mob_class.fly = mcl_mobs.fly +mcl_mobs.mob_class.attach = mcl_mobs.attach + +function mob_class:on_detach_child(child) + if self.detach_child then + if self.detach_child(self, child) then + return + end + end + if self.driver == child then + self.driver = nil + end +end diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua new file mode 100644 index 000000000..df00a42a7 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -0,0 +1,1026 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class +local DEFAULT_FALL_SPEED = -9.81*1.5 +local FLOP_HEIGHT = 6 +local FLOP_HOR_SPEED = 1.5 +local PATHFINDING = "gowp" + +local node_ice = "mcl_core:ice" +local node_snowblock = "mcl_core:snowblock" +local node_snow = "mcl_core:snow" + + +local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false + +local atann = math.atan +local function atan(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + +-- get node but use fallback for nil or unknown +local node_ok = function(pos, fallback) + fallback = fallback or mcl_mobs.fallback_node + local node = minetest.get_node_or_nil(pos) + if node and minetest.registered_nodes[node.name] then + return node + end + return minetest.registered_nodes[fallback] +end + +-- Returns true is node can deal damage to self +function mob_class:is_node_dangerous(nodename) + local nn = nodename + if self.lava_damage > 0 then + if minetest.get_item_group(nn, "lava") ~= 0 then + return true + end + end + if self.fire_damage > 0 then + if minetest.get_item_group(nn, "fire") ~= 0 then + return true + end + end + if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].damage_per_second and minetest.registered_nodes[nn].damage_per_second > 0 then + return true + end + return false +end + + +-- Returns true if node is a water hazard +function mob_class:is_node_waterhazard(nodename) + local nn = nodename + if self.water_damage > 0 then + if minetest.get_item_group(nn, "water") ~= 0 then + return true + end + end + if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].drowning and minetest.registered_nodes[nn].drowning > 0 then + if self.breath_max ~= -1 then + -- check if the mob is water-breathing _and_ the block is water; only return true if neither is the case + -- this will prevent water-breathing mobs to classify water or e.g. sand below them as dangerous + if not self.breathes_in_water and minetest.get_item_group(nn, "water") ~= 0 then + return true + end + end + end + return false +end + +-- check line of sight (BrunoMine) +function mob_class:line_of_sight(pos1, pos2, stepsize) + + stepsize = stepsize or 1 + + local s, pos = minetest.line_of_sight(pos1, pos2, stepsize) + + -- normal walking and flying mobs can see you through air + if s == true then + return true + end + + -- New pos1 to be analyzed + local npos1 = {x = pos1.x, y = pos1.y, z = pos1.z} + + local r, pos = minetest.line_of_sight(npos1, pos2, stepsize) + + -- Checks the return + if r == true then return true end + + -- Nodename found + local nn = minetest.get_node(pos).name + + -- Target Distance (td) to travel + local td = vector.distance(pos1, pos2) + + -- Actual Distance (ad) traveled + local ad = 0 + + -- It continues to advance in the line of sight in search of a real + -- obstruction which counts as 'normal' nodebox. + while minetest.registered_nodes[nn] + and minetest.registered_nodes[nn].walkable == false do + + -- Check if you can still move forward + if td < ad + stepsize then + return true -- Reached the target + end + + -- Moves the analyzed pos + local d = vector.distance(pos1, pos2) + + npos1.x = ((pos2.x - pos1.x) / d * stepsize) + pos1.x + npos1.y = ((pos2.y - pos1.y) / d * stepsize) + pos1.y + npos1.z = ((pos2.z - pos1.z) / d * stepsize) + pos1.z + + -- NaN checks + if d == 0 + or npos1.x ~= npos1.x + or npos1.y ~= npos1.y + or npos1.z ~= npos1.z then + return false + end + + ad = ad + stepsize + + -- scan again + r, pos = minetest.line_of_sight(npos1, pos2, stepsize) + + if r == true then return true end + + -- New Nodename found + nn = minetest.get_node(pos).name + + end + + return false +end + +function mob_class:can_jump_cliff() + local yaw = self.object:get_yaw() + local pos = self.object:get_pos() + local v = self.object:get_velocity() + + local v2 = math.abs(v.x)+math.abs(v.z)*.833 + local jump_c_multiplier = 1 + if v2/self.walk_velocity/2>1 then + jump_c_multiplier = v2/self.walk_velocity/2 + end + + -- where is front + local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5)*jump_c_multiplier+0.6 + local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5)*jump_c_multiplier+0.6 + + --is there nothing under the block in front? if so jump the gap. + local nodLow = node_ok({ + x = pos.x + dir_x-0.6, + y = pos.y - 0.5, + z = pos.z + dir_z-0.6 + }, "air") + + local nodFar = node_ok({ + x = pos.x + dir_x*2, + y = pos.y - 0.5, + z = pos.z + dir_z*2 + }, "air") + + local nodFar2 = node_ok({ + x = pos.x + dir_x*2.5, + y = pos.y - 0.5, + z = pos.z + dir_z*2.5 + }, "air") + + + if minetest.registered_nodes[nodLow.name] + and minetest.registered_nodes[nodLow.name].walkable ~= true + + + and (minetest.registered_nodes[nodFar.name] + and minetest.registered_nodes[nodFar.name].walkable == true + + or minetest.registered_nodes[nodFar2.name] + and minetest.registered_nodes[nodFar2.name].walkable == true) + + then + --disable fear heigh while we make our jump + self._jumping_cliff = true + minetest.after(1, function() + if self and self.object then + self._jumping_cliff = false + end + end) + return true + else + return false + end +end + +-- is mob facing a cliff or danger +function mob_class:is_at_cliff_or_danger() + if self.fear_height == 0 or self:can_jump_cliff() or self._jumping_cliff or not self.object:get_luaentity() then -- 0 for no falling protection! + return false + end + + local yaw = self.object:get_yaw() + local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5) + local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5) + local pos = self.object:get_pos() + local ypos = pos.y + self.collisionbox[2] -- just above floor + + local free_fall, blocker = minetest.line_of_sight( + {x = pos.x + dir_x, y = ypos, z = pos.z + dir_z}, + {x = pos.x + dir_x, y = ypos - self.fear_height, z = pos.z + dir_z}) + if free_fall then + return true + else + local bnode = minetest.get_node(blocker) + local danger = self:is_node_dangerous(bnode.name) + if danger then + return true + else + local def = minetest.registered_nodes[bnode.name] + if def and def.walkable then + return false + end + end + end + + return false +end + + +-- copy the 'mob facing cliff_or_danger check' from above, and rework to avoid water +function mob_class:is_at_water_danger() + if not self.object:get_luaentity() or self:can_jump_cliff() or self._jumping_cliff then + return false + end + local yaw = self.object:get_yaw() + local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5) + local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5) + local pos = self.object:get_pos() + local ypos = pos.y + self.collisionbox[2] -- just above floor + + local free_fall, blocker = minetest.line_of_sight( + {x = pos.x + dir_x, y = ypos, z = pos.z + dir_z}, + {x = pos.x + dir_x, y = ypos - 3, z = pos.z + dir_z}) + if free_fall then + return true + else + local bnode = minetest.get_node(blocker) + local waterdanger = self:is_node_waterhazard(bnode.name) + if + waterdanger and (self:is_node_waterhazard(self.standing_in) or self:is_node_waterhazard( self.standing_on)) then + return false + elseif waterdanger and (self:is_node_waterhazard(self.standing_in) or self:is_node_waterhazard(self.standing_on)) == false then + return true + else + local def = minetest.registered_nodes[bnode.name] + if def and def.walkable then + return false + end + end + end + + return false +end + +function mob_class:env_danger_movement_checks(dtime) + local yaw = 0 + if self:is_at_water_danger() and self.state ~= "attack" then + if math.random(1, 10) <= 6 then + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + yaw = yaw + math.random(-0.5, 0.5) + yaw = self:set_yaw( yaw, 8) + end + else + if self.move_in_group ~= false then + self:check_herd(dtime) + end + end + + if self:is_at_cliff_or_danger() then + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + local yaw = self.object:get_yaw() or 0 + yaw = self:set_yaw( yaw + 0.78, 8) + end +end + +-- jump if facing a solid node (not fences or gates) +function mob_class:do_jump() + if not self.jump + or self.jump_height == 0 + or self.fly + or self.order == "stand" then + return false + end + + self.facing_fence = false + + -- something stopping us while moving? + if self.state ~= "stand" + and self:get_velocity() > 0.5 + and self.object:get_velocity().y ~= 0 then + return false + end + + local pos = self.object:get_pos() + local yaw = self.object:get_yaw() + + -- what is mob standing on? + pos.y = pos.y + self.collisionbox[2] - 0.2 + + local nod = node_ok(pos) + + if minetest.registered_nodes[nod.name].walkable == false then + return false + end + + local v = self.object:get_velocity() + local v2 = math.abs(v.x)+math.abs(v.z)*.833 + local jump_c_multiplier = 1 + if v2/self.walk_velocity/2>1 then + jump_c_multiplier = v2/self.walk_velocity/2 + end + + -- where is front + local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5)*jump_c_multiplier+0.6 + local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5)*jump_c_multiplier+0.6 + + -- what is in front of mob? + nod = node_ok({ + x = pos.x + dir_x, + y = pos.y + 0.5, + z = pos.z + dir_z + }) + + -- this is used to detect if there's a block on top of the block in front of the mob. + -- If there is, there is no point in jumping as we won't manage. + local nodTop = node_ok({ + x = pos.x + dir_x, + y = pos.y + 1.5, + z = pos.z + dir_z + }, "air") + + + -- we don't attempt to jump if there's a stack of blocks blocking + if minetest.registered_nodes[nodTop.name].walkable == true and not (self.attack and self.state == "attack") then + return false + end + + -- thin blocks that do not need to be jumped + if nod.name == node_snow then + return false + end + + local ndef = minetest.registered_nodes[nod.name] + if self.walk_chance == 0 or ndef and ndef.walkable or self:can_jump_cliff() then + + if minetest.get_item_group(nod.name, "fence") == 0 + and minetest.get_item_group(nod.name, "fence_gate") == 0 + and minetest.get_item_group(nod.name, "wall") == 0 then + + local v = self.object:get_velocity() + + v.y = self.jump_height + 0.1 * 3 + + if self:can_jump_cliff() then + v=vector.multiply(v, vector.new(2.8,1,2.8)) + end + + self:set_animation( "jump") -- only when defined + + self.object:set_velocity(v) + + -- when in air move forward + minetest.after(0.3, function(self, v) + if (not self.object) or (not self.object:get_luaentity()) or (self.state == "die") then + return + end + self.object:set_acceleration({ + x = v.x * 2, + y = DEFAULT_FALL_SPEED, + z = v.z * 2, + }) + end, self, v) + + if self.jump_sound_cooloff <= 0 then + self:mob_sound("jump") + self.jump_sound_cooloff = 0.5 + end + else + self.facing_fence = true + end + + -- if we jumped against a block/wall 4 times then turn + if self.object:get_velocity().x ~= 0 + and self.object:get_velocity().z ~= 0 then + + self.jump_count = (self.jump_count or 0) + 1 + + if self.jump_count == 4 then + + local yaw = self.object:get_yaw() or 0 + + yaw = self:set_yaw( yaw + 1.35, 8) + + self.jump_count = 0 + end + end + + return true + end + + return false +end + +-- should mob follow what I'm holding ? +function mob_class:follow_holding(clicker) + if self.nofollow then return false end + + if mcl_mobs.invis[clicker:get_player_name()] then + return false + end + + local item = clicker:get_wielded_item() + local t = type(self.follow) + + -- single item + if t == "string" + and item:get_name() == self.follow then + return true + + -- multiple items + elseif t == "table" then + + for no = 1, #self.follow do + + if self.follow[no] == item:get_name() then + return true + end + end + end + + return false +end + + +-- find and replace what mob is looking for (grass, wheat etc.) +function mob_class:replace(pos) + + if not self.replace_rate + or not self.replace_what + or self.child == true + or self.object:get_velocity().y ~= 0 + or math.random(1, self.replace_rate) > 1 then + return + end + + local what, with, y_offset + + if type(self.replace_what[1]) == "table" then + + local num = math.random(#self.replace_what) + + what = self.replace_what[num][1] or "" + with = self.replace_what[num][2] or "" + y_offset = self.replace_what[num][3] or 0 + else + what = self.replace_what + with = self.replace_with or "" + y_offset = self.replace_offset or 0 + end + + pos.y = pos.y + y_offset + + local node = minetest.get_node(pos) + if node.name == what then + + local oldnode = {name = what, param2 = node.param2} + local newnode = {name = with, param2 = node.param2} + local on_replace_return + + if self.on_replace then + on_replace_return = self.on_replace(self, pos, oldnode, newnode) + end + + if on_replace_return ~= false then + + if mobs_griefing then + minetest.set_node(pos, newnode) + end + + end + end +end + +-- specific runaway +local specific_runaway = function(list, what) + if type(list) ~= "table" then + list = {} + end + + -- no list so do not run + if list == nil then + return false + end + + -- found entity on list to attack? + for no = 1, #list do + + if list[no] == what then + return true + end + end + + return false +end + + +-- find someone to runaway from +function mob_class:check_runaway_from() + if not self.runaway_from and self.state ~= "flop" then + return + end + + local s = self.object:get_pos() + local p, sp, dist + local player, obj, min_player + local type, name = "", "" + local min_dist = self.view_range + 1 + local objs = minetest.get_objects_inside_radius(s, self.view_range) + + for n = 1, #objs do + + if objs[n]:is_player() then + + if mcl_mobs.invis[ objs[n]:get_player_name() ] + or self.owner == objs[n]:get_player_name() + or (not self:object_in_range(objs[n])) then + type = "" + else + player = objs[n] + type = "player" + name = "player" + end + else + obj = objs[n]:get_luaentity() + + if obj then + player = obj.object + type = obj.type + name = obj.name or "" + end + end + + -- find specific mob to runaway from + if name ~= "" and name ~= self.name + and specific_runaway(self.runaway_from, name) then + + p = player:get_pos() + sp = s + + -- aim higher to make looking up hills more realistic + p.y = p.y + 1 + sp.y = sp.y + 1 + + dist = vector.distance(p, s) + + + -- choose closest player/mpb to runaway from + if dist < min_dist + and self:line_of_sight(sp, p, 2) == true then + min_dist = dist + min_player = player + end + end + end + + if min_player then + + local lp = player:get_pos() + local vec = { + x = lp.x - s.x, + y = lp.y - s.y, + z = lp.z - s.z + } + + local yaw = (atan(vec.z / vec.x) + 3 *math.pi/ 2) - self.rotate + + if lp.x > s.x then + yaw = yaw + math.pi + end + + yaw = self:set_yaw( yaw, 4) + self.state = "runaway" + self.runaway_timer = 3 + self.following = nil + end +end + + +-- follow player if owner or holding item, if fish outta water then flop +function mob_class:follow_flop() + + -- find player to follow + if (self.follow ~= "" + or self.order == "follow") + and not self.following + and self.state ~= "attack" + and self.order ~= "sit" + and self.state ~= "runaway" then + + local s = self.object:get_pos() + local players = minetest.get_connected_players() + + for n = 1, #players do + + if (self:object_in_range(players[n])) + and not mcl_mobs.invis[ players[n]:get_player_name() ] then + + self.following = players[n] + + break + end + end + end + + if self.type == "npc" + and self.order == "follow" + and self.state ~= "attack" + and self.order ~= "sit" + and self.owner ~= "" then + + -- 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 (self:follow_holding(self.following) == false or + self.horny or self.state == "runaway") then + self.following = nil + end + + end + + -- follow that thing + if self.following then + + local s = self.object:get_pos() + local p + + if self.following:is_player() then + + p = self.following:get_pos() + + elseif self.following.object then + + p = self.following.object:get_pos() + end + + if p then + + local dist = vector.distance(p, s) + + -- dont follow if out of range + if (not self:object_in_range(self.following)) then + self.following = nil + else + local vec = { + x = p.x - s.x, + z = p.z - s.z + } + + local yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + + if p.x > s.x then yaw = yaw +math.pi end + + self:set_yaw( yaw, 2.35) + + -- anyone but standing npc's can move along + if dist > 3 + and self.order ~= "stand" then + + self:set_velocity(self.follow_velocity) + + if self.walk_chance ~= 0 then + self:set_animation( "run") + end + else + self:set_velocity(0) + self:set_animation( "stand") + end + + return + end + end + end + + -- swimmers flop when out of their element, and swim again when back in + if self.fly then + local s = self.object:get_pos() + if self:flight_check( s) == false then + + self.state = "flop" + self.object:set_acceleration({x = 0, y = DEFAULT_FALL_SPEED, z = 0}) + + local p = self.object:get_pos() + local sdef = minetest.registered_nodes[node_ok(vector.add(p, vector.new(0,self.collisionbox[2]-0.2,0))).name] + -- Flop on ground + if sdef and sdef.walkable then + if self.object:get_velocity().y < 0.1 then + self:mob_sound("flop") + self.object:set_velocity({ + x = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED), + y = FLOP_HEIGHT, + z = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED), + }) + end + end + + self:set_animation( "stand", true) + + return + elseif self.state == "flop" then + self.state = "stand" + self.object:set_acceleration({x = 0, y = 0, z = 0}) + self:set_velocity(0) + end + end +end + +function mob_class:go_to_pos(b) + if not self then return end + local s=self.object:get_pos() + if not b then + --self.state = "stand" + return end + if vector.distance(b,s) < 1 then + --self:set_velocity(0) + return true + end + local v = { x = b.x - s.x, z = b.z - s.z } + local yaw = (atann(v.z / v.x) +math.pi/ 2) - self.rotate + if b.x > s.x then yaw = yaw +math.pi end + self.object:set_yaw(yaw) + self:set_velocity(self.follow_velocity) + self:set_animation("walk") +end + +local check_herd_timer = 0 +function mob_class:check_herd(dtime) + local pos = self.object:get_pos() + if not pos then return end + check_herd_timer = check_herd_timer + dtime + if check_herd_timer < 4 then return end + check_herd_timer = 0 + for _,o in pairs(minetest.get_objects_inside_radius(pos,self.view_range)) do + local l = o:get_luaentity() + local p,y + if l and l.is_mob and l.name == self.name then + if self.horny and l.horny then + p = l.object:get_pos() + else + y = o:get_yaw() + end + if p then + self:go_to_pos(p) + elseif y then + self:set_yaw(y) + end + end + end +end + +function mob_class:teleport(target) + if self.do_teleport then + if self.do_teleport(self, target) == false then + return + end + end +end + +function mob_class:do_states_walk() + local yaw = self.object:get_yaw() or 0 + + local s = self.object:get_pos() + local lp = nil + + -- is there something I need to avoid? + if (self.water_damage > 0 + and self.lava_damage > 0) + or self.breath_max ~= -1 then + lp = minetest.find_node_near(s, 1, {"group:water", "group:lava"}) + elseif self.water_damage > 0 then + lp = minetest.find_node_near(s, 1, {"group:water"}) + elseif self.lava_damage > 0 then + lp = minetest.find_node_near(s, 1, {"group:lava"}) + elseif self.fire_damage > 0 then + lp = minetest.find_node_near(s, 1, {"group:fire"}) + end + + local is_in_danger = false + if lp then + -- If mob in or on dangerous block, look for land + if (self:is_node_dangerous(self.standing_in) or + self:is_node_dangerous(self.standing_on)) or (self:is_node_waterhazard(self.standing_in) or self:is_node_waterhazard(self.standing_on)) and (not self.fly) then + is_in_danger = true + + -- If mob in or on dangerous block, look for land + if is_in_danger then + -- Better way to find shore - copied from upstream + lp = minetest.find_nodes_in_area_under_air( + {x = s.x - 5, y = s.y - 0.5, z = s.z - 5}, + {x = s.x + 5, y = s.y + 1, z = s.z + 5}, + {"group:solid"}) + + lp = #lp > 0 and lp[math.random(#lp)] + + -- did we find land? + if lp then + + local vec = { + x = lp.x - s.x, + z = lp.z - s.z + } + + yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + + + if lp.x > s.x then yaw = yaw +math.pi end + + -- look towards land and move in that direction + yaw = self:set_yaw( yaw, 6) + self:set_velocity(self.walk_velocity) + + end + end + + -- A danger is near but mob is not inside + else + + -- Randomly turn + if math.random(1, 100) <= 30 then + yaw = yaw + math.random(-0.5, 0.5) + yaw = self:set_yaw( yaw, 8) + end + end + + yaw = self:set_yaw( yaw, 8) + + -- otherwise randomly turn + elseif math.random(1, 100) <= 30 then + yaw = yaw + math.random(-0.5, 0.5) + yaw = self:set_yaw( yaw, 8) + end + + -- stand for great fall or danger or fence in front + local cliff_or_danger = false + if is_in_danger then + cliff_or_danger = self:is_at_cliff_or_danger() + end + if self.facing_fence == true + or cliff_or_danger + or math.random(1, 100) <= 30 then + + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + local yaw = self.object:get_yaw() or 0 + yaw = self:set_yaw( yaw + 0.78, 8) + else + + self:set_velocity(self.walk_velocity) + + if self:flight_check() + and self.animation + and self.animation.fly_start + and self.animation.fly_end then + self:set_animation( "fly") + else + self:set_animation( "walk") + end + end +end + +function mob_class:do_states_stand() + local yaw = self.object:get_yaw() or 0 + + if math.random(1, 4) == 1 then + + local s = self.object:get_pos() + local objs = minetest.get_objects_inside_radius(s, 3) + local lp + for n = 1, #objs do + if objs[n]:is_player() then + lp = objs[n]:get_pos() + break + end + end + + -- look at any players nearby, otherwise turn randomly + if lp and self.look_at_players then + + local vec = { + x = lp.x - s.x, + z = lp.z - s.z + } + + yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + + if lp.x > s.x then yaw = yaw +math.pi end + else + yaw = yaw + math.random(-0.5, 0.5) + end + + yaw = self:set_yaw( yaw, 8) + end + if self.order == "sit" then + self:set_animation( "sit") + self:set_velocity(0) + else + self:set_animation( "stand") + self:set_velocity(0) + end + + -- npc's ordered to stand stay standing + if self.order == "stand" or self.order == "sleep" or self.order == "work" then + + else + if self.walk_chance ~= 0 + and self.facing_fence ~= true + and math.random(1, 100) <= self.walk_chance + and self:is_at_cliff_or_danger() == false then + + self:set_velocity(self.walk_velocity) + self.state = "walk" + self:set_animation( "walk") + end + end +end + +function mob_class:do_states_runaway() + local yaw = self.object:get_yaw() or 0 + + self.runaway_timer = self.runaway_timer + 1 + + -- stop after 5 seconds or when at cliff + if self.runaway_timer > 5 + or self:is_at_cliff_or_danger() then + self.runaway_timer = 0 + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + local yaw = self.object:get_yaw() or 0 + yaw = self:set_yaw( yaw + 0.78, 8) + else + self:set_velocity( self.run_velocity) + self:set_animation( "run") + end +end + + + + + + +function mob_class:check_smooth_rotation(dtime) + -- smooth rotation by ThomasMonroe314 + if self._turn_to then + self:set_yaw( self._turn_to, .1) + end + + if self.delay and self.delay > 0 then + + local yaw = self.object:get_yaw() or 0 + + if self.delay == 1 then + yaw = self.target_yaw + else + local dif = math.abs(yaw - self.target_yaw) + + if yaw > self.target_yaw then + + if dif > math.pi then + dif = 2 * math.pi - dif -- need to add + yaw = yaw + dif / self.delay + else + yaw = yaw - dif / self.delay -- need to subtract + end + + elseif yaw < self.target_yaw then + + if dif >math.pi then + dif = 2 * math.pi - dif + yaw = yaw - dif / self.delay -- need to subtract + else + yaw = yaw + dif / self.delay -- need to add + end + end + + if yaw > (math.pi * 2) then yaw = yaw - (math.pi * 2) end + if yaw < 0 then yaw = yaw + (math.pi * 2) end + end + + self.delay = self.delay - 1 + if self.shaking then + yaw = yaw + (math.random() * 2 - 1) * 5 * dtime + end + self.object:set_yaw(yaw) + --self:update_roll() + end + -- end rotation +end diff --git a/mods/ENTITIES/mcl_mobs/pathfinding.lua b/mods/ENTITIES/mcl_mobs/pathfinding.lua new file mode 100644 index 000000000..ee39d28ad --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/pathfinding.lua @@ -0,0 +1,444 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +local PATHFINDING_FAIL_THRESHOLD = 100 -- no. of ticks to fail before giving up. 20p/s. 5s helps them get through door +local PATHFINDING_FAIL_WAIT = 30 -- how long to wait before trying to path again + +local PATHFINDING = "gowp" + +local one_down = vector.new(0,-1,0) +local one_up = vector.new(0,1,0) + +local plane_adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_pathfinding",false) + +local LOG_MODULE = "[Mobs Pathfinding]" +local function mcl_log (message) + if LOGGING_ON and message then + minetest.log(LOG_MODULE .. " " .. message) + end +end + +function output_table (wp) + if not wp then return end + mcl_log("wp items: ".. tostring(#wp)) + for a,b in pairs(wp) do + mcl_log(a.. ": ".. tostring(b)) + end +end + +function append_paths (wp1, wp2) + --mcl_log("Start append") + if not wp1 or not wp2 then + mcl_log("Cannot append wp's") + return + end + output_table(wp1) + output_table(wp2) + for _,a in pairs (wp2) do + table.insert(wp1, a) + end + --mcl_log("End append") +end + +local function output_enriched (wp_out) + mcl_log("Output enriched path") + local i = 0 + for _,outy in pairs (wp_out) do + i = i + 1 + mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"])) + + local action = outy["action"] + if action then + --mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"])) + mcl_log("type: " .. action["type"]) + mcl_log("action: " .. action["action"]) + mcl_log("target: " .. minetest.pos_to_string(action["target"])) + end + --mcl_log("failed attempts: " .. outy["failed_attempts"]) + end +end + +-- This function will take a list of paths, and enrich it with: +-- a var for failed attempts +-- an action, such as to open or close a door where we know that pos requires that action +local function generate_enriched_path(wp_in, door_open_pos, door_close_pos, cur_door_pos) + local wp_out = {} + + -- TODO Just pass in door position and the index before is open, the index after is close + local current_door_index = -1 + + for i, cur_pos in pairs(wp_in) do + local action = nil + + local cur_pos_to_add = vector.add(cur_pos, one_down) + if door_open_pos and vector.equals (cur_pos, door_open_pos) then + mcl_log ("Door open match") + action = {type = "door", action = "open", target = cur_door_pos} + cur_pos_to_add = vector.add(cur_pos, one_down) + elseif door_close_pos and vector.equals(cur_pos, door_close_pos) then + mcl_log ("Door close match") + action = {type = "door", action = "close", target = cur_door_pos} + cur_pos_to_add = vector.add(cur_pos, one_down) + elseif cur_door_pos and vector.equals(cur_pos, cur_door_pos) then + mcl_log("Current door pos") + action = {type = "door", action = "open", target = cur_door_pos} + cur_pos_to_add = vector.add(cur_pos, one_down) + else + cur_pos_to_add = cur_pos + --mcl_log ("Pos doesn't match") + end + + wp_out[i] = {} + wp_out[i]["pos"] = cur_pos_to_add + wp_out[i]["failed_attempts"] = 0 + wp_out[i]["action"] = action + + --wp_out[i] = {"pos" = cur_pos, "failed_attempts" = 0, "action" = action} + --output_pos(cur_pos, i) + end + output_enriched(wp_out) + return wp_out +end + +function mob_class:ready_to_path() + mcl_log("Check ready to path") + if self._pf_last_failed and (os.time() - self._pf_last_failed) < PATHFINDING_FAIL_WAIT then + mcl_log("Not ready to path as last fail is less than threshold: " .. (os.time() - self._pf_last_failed)) + return false + else + mcl_log("We are ready to pathfind, no previous fail or we are past threshold") + return true + end +end + +-- This function is used to see if we can path. We could use to check a route, rather than making people move. +local function calculate_path_through_door (p, cur_door_pos, t) + if t then + mcl_log("Plot route through door from pos: " .. minetest.pos_to_string(p) .. ", to target: " .. minetest.pos_to_string(t)) + else + mcl_log("Plot route through door from pos: " .. minetest.pos_to_string(p)) + end + + local enriched_path = nil + local wp, prospective_wp + + local pos_closest_to_door = nil + local other_side_of_door = nil + + if cur_door_pos then + mcl_log("Found a door near: " .. minetest.pos_to_string(cur_door_pos)) + + for _,v in pairs(plane_adjacents) do + pos_closest_to_door = vector.add(cur_door_pos,v) + other_side_of_door = vector.add(cur_door_pos,-v) + + local n = minetest.get_node(pos_closest_to_door) + + if n.name == "air" then + mcl_log("We have air space next to door at: " .. minetest.pos_to_string(pos_closest_to_door)) + + prospective_wp = minetest.find_path(p,pos_closest_to_door,150,1,4) + + if prospective_wp then + mcl_log("Found a path to next to door".. minetest.pos_to_string(pos_closest_to_door)) + mcl_log("Opposite is: ".. minetest.pos_to_string(other_side_of_door)) + + table.insert(prospective_wp, cur_door_pos) + + if t then + mcl_log("We have t, lets go from door to target") + local wp_otherside_door_to_target = minetest.find_path(other_side_of_door,t,150,1,4) + + if wp_otherside_door_to_target and #wp_otherside_door_to_target > 0 then + append_paths (prospective_wp, wp_otherside_door_to_target) + + wp = prospective_wp + mcl_log("We have a path from outside door to target") + else + mcl_log("We cannot path from outside door to target") + end + else + mcl_log("No t, just add other side of door") + table.insert(prospective_wp, other_side_of_door) + wp = prospective_wp + end + + if wp then + enriched_path = generate_enriched_path(wp, pos_closest_to_door, other_side_of_door, cur_door_pos) + break + end + else + mcl_log("Cannot path to this air block next to door.") + end + end + end + else + mcl_log("No door found") + end + + if wp and not enriched_path then + mcl_log("Wp but not enriched") + enriched_path = generate_enriched_path(wp) + end + return enriched_path +end + +function mob_class:gopath(target,callback_arrived) + if self.state == PATHFINDING then mcl_log("Already pathfinding, don't set another until done.") return end + if not self:ready_to_path() then return end + + self.order = nil + + local p = self.object:get_pos() + local t = vector.offset(target,0,1,0) + + --Check direct route + local wp = minetest.find_path(p,t,150,1,4) + + if not wp then + mcl_log("### No direct path. Path through door closest to target.") + local door_near_target = minetest.find_node_near(target, 16, {"group:door"}) + wp = calculate_path_through_door(p, door_near_target, t) + + if not wp then + mcl_log("### No path though door closest to target. Try door closest to origin.") + local door_closest = minetest.find_node_near(p, 16, {"group:door"}) + wp = calculate_path_through_door(p, door_closest, t) + + -- Path through 2 doors + if not wp then + mcl_log("### Still not wp. Need to path through 2 doors.") + local path_through_closest_door = calculate_path_through_door(p, door_closest) + + if path_through_closest_door and #path_through_closest_door > 0 then + mcl_log("We have path through first door") + mcl_log("Number of pos in path through door: " .. tostring(#path_through_closest_door)) + + local pos_after_door_entry = path_through_closest_door[#path_through_closest_door] + if pos_after_door_entry then + local pos_after_door = vector.add(pos_after_door_entry["pos"], one_up) + mcl_log("pos_after_door: " .. minetest.pos_to_string(pos_after_door)) + local path_after_door = calculate_path_through_door(pos_after_door, door_near_target, t) + if path_after_door and #path_after_door > 1 then + mcl_log("We have path after first door") + table.remove(path_after_door, 1) -- Remove duplicate + wp = path_through_closest_door + append_paths (wp, path_after_door) + else + mcl_log("Path after door is not good") + end + else + mcl_log("No pos after door") + end + else + mcl_log("Path through closest door empty or null") + end + else + mcl_log("ok, we have a path through 1 door") + end + end + else + wp = generate_enriched_path(wp) + mcl_log("We have a direct route") + end + + if not wp then + mcl_log("Could not calculate path") + self._pf_last_failed = os.time() + -- If cannot path, don't immediately try again + end + + if wp and #wp > 0 then + --output_table(wp) + self._target = t + self.callback_arrived = callback_arrived + local current_location = table.remove(wp,1) + if current_location and current_location["pos"] then + mcl_log("Removing first co-ord? " .. tostring(current_location["pos"])) + else + mcl_log("Nil pos") + end + self.current_target = current_location + self.waypoints = wp + self.state = PATHFINDING + return true + else + self.state = "walk" + self.waypoints = nil + self.current_target = nil + -- minetest.log("no path found") + end +end + +function mob_class:interact_with_door(action, target) + local p = self.object:get_pos() + --local t = minetest.get_timeofday() + --local dd = minetest.find_nodes_in_area(vector.offset(p,-1,-1,-1),vector.offset(p,1,1,1),{"group:door"}) + --for _,d in pairs(dd) do + if target then + mcl_log("Door target is: ".. minetest.pos_to_string(target)) + + local n = minetest.get_node(target) + if n.name:find("_b_") or n.name:find("_t_") then + mcl_log("Door") + local def = minetest.registered_nodes[n.name] + local closed = n.name:find("_b_1") or n.name:find("_t_1") + --if self.state == PATHFINDING then + if closed and action == "open" and def.on_rightclick then + mcl_log("Open door") + def.on_rightclick(target,n,self) + end + if not closed and action == "close" and def.on_rightclick then + mcl_log("Close door") + def.on_rightclick(target,n,self) + end + --else + else + mcl_log("Not door") + end + else + mcl_log("no target. cannot try and open or close door") + end + --end +end + +function mob_class:do_pathfind_action(action) + if action then + mcl_log("Action present") + local type = action["type"] + local action_val = action["action"] + local target = action["target"] + if target then + mcl_log("Target: ".. minetest.pos_to_string(target)) + end + if type and type == "door" then + mcl_log("Type is door") + self:interact_with_door(action_val, target) + end + end +end + +function mob_class:check_gowp(dtime) + local p = self.object:get_pos() + + -- no destination + if not p or not self._target then + mcl_log("p: ".. tostring(p)) + mcl_log("self._target: ".. tostring(self._target)) + return + end + + -- arrived at location, finish gowp + local distance_to_targ = vector.distance(p,self._target) + --mcl_log("Distance to targ: ".. tostring(distance_to_targ)) + if distance_to_targ < 1.8 then + mcl_log("Arrived at _target") + self.waypoints = nil + self._target = nil + self.current_target = nil + self.state = "stand" + self.order = "stand" + self.object:set_velocity({x = 0, y = 0, z = 0}) + self.object:set_acceleration({x = 0, y = 0, z = 0}) + if self.callback_arrived then return self.callback_arrived(self) end + return true + elseif not self.current_target then + mcl_log("Not close enough to targ: ".. tostring(distance_to_targ)) + end + + -- More pathing to be done + local distance_to_current_target = 50 + if self.current_target and self.current_target["pos"] then + distance_to_current_target = vector.distance(p,self.current_target["pos"]) + end + + -- 0.6 is working but too sensitive. sends villager back too frequently. 0.7 is quite good, but not with heights + -- 0.8 is optimal for 0.025 frequency checks and also 1... Actually. 0.8 is winning + -- 0.9 and 1.0 is also good. Stick with unless door open or closing issues + if self.waypoints and #self.waypoints > 0 and ( not self.current_target or not self.current_target["pos"] or distance_to_current_target < 0.9 ) then + -- We have waypoints, and are at current_target or have no current target. We need a new current_target. + self:do_pathfind_action (self.current_target["action"]) + + local failed_attempts = self.current_target["failed_attempts"] + mcl_log("There after " .. failed_attempts .. " failed attempts. current target:".. minetest.pos_to_string(self.current_target["pos"]) .. ". Distance: " .. distance_to_current_target) + + self.current_target = table.remove(self.waypoints, 1) + self:go_to_pos(self.current_target["pos"]) + return + elseif self.current_target and self.current_target["pos"] then + -- No waypoints left, but have current target and not close enough. Potentially last waypoint to go to. + + self.current_target["failed_attempts"] = self.current_target["failed_attempts"] + 1 + local failed_attempts = self.current_target["failed_attempts"] + if failed_attempts >= PATHFINDING_FAIL_THRESHOLD then + mcl_log("Failed to reach position (" .. minetest.pos_to_string(self.current_target["pos"]) .. ") too many times. Abandon route. Times tried: " .. failed_attempts) + self.state = "stand" + self.current_target = nil + self.waypoints = nil + self._target = nil + self._pf_last_failed = os.time() + self.object:set_velocity({x = 0, y = 0, z = 0}) + self.object:set_acceleration({x = 0, y = 0, z = 0}) + return + end + + --mcl_log("Not at pos with failed attempts ".. failed_attempts ..": ".. minetest.pos_to_string(p) .. "self.current_target: ".. minetest.pos_to_string(self.current_target["pos"]) .. ". Distance: ".. distance_to_current_target) + self:go_to_pos(self.current_target["pos"]) + -- Do i just delete current_target, and return so we can find final path. + else + -- Not at target, no current waypoints or current_target. Through the door and should be able to path to target. + -- Is a little sensitive and could take 1 - 7 times. A 10 fail count might be a good exit condition. + + mcl_log("We don't have waypoints or a current target. Let's try to path to target") + + if self.waypoints then + mcl_log("WP: " .. tostring(self.waypoints)) + mcl_log("WP num: " .. tostring(#self.waypoints)) + else + mcl_log("No wp set") + end + if self.current_target then + mcl_log("Current target: " .. tostring(self.current_target)) + else + mcl_log("No current target") + end + + local final_wp = minetest.find_path(p,self._target,150,1,4) + if final_wp then + mcl_log("We can get to target here.") + -- self.waypoints = final_wp + self:go_to_pos(self._target) + else + -- Abandon route? + mcl_log("Cannot plot final route to target") + end + end + + -- I don't think we need the following anymore, but test first. + -- Maybe just need something to path to target if no waypoints left + if self.current_target and self.current_target["pos"] and (self.waypoints and #self.waypoints == 0) then + local updated_p = self.object:get_pos() + local distance_to_cur_targ = vector.distance(updated_p,self.current_target["pos"]) + + mcl_log("Distance to current target: ".. tostring(distance_to_cur_targ)) + mcl_log("Current p: ".. minetest.pos_to_string(updated_p)) + + -- 1.6 is good. is 1.9 better? It could fail less, but will it path to door when it isn't after door + if distance_to_cur_targ > 1.9 then + mcl_log("not close to current target: ".. minetest.pos_to_string(self.current_target["pos"])) + self:go_to_pos(self._current_target) + else + mcl_log("close to current target: ".. minetest.pos_to_string(self.current_target["pos"])) + mcl_log("target is: ".. minetest.pos_to_string(self._target)) + self.current_target = nil + end + return + end +end diff --git a/mods/ENTITIES/mcl_mobs/physics.lua b/mods/ENTITIES/mcl_mobs/physics.lua new file mode 100644 index 000000000..0617fd1e8 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/physics.lua @@ -0,0 +1,1005 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +local ENTITY_CRAMMING_MAX = 24 +local CRAMMING_DAMAGE = 3 +local DEATH_DELAY = 0.5 +local DEFAULT_FALL_SPEED = -9.81*1.5 + +local PATHFINDING = "gowp" +local mobs_debug = minetest.settings:get_bool("mobs_debug", false) +local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false +local mob_active_range = tonumber(minetest.settings:get("mcl_mob_active_range")) or 48 +local show_health = false + +-- get node but use fallback for nil or unknown +local node_ok = function(pos, fallback) + + fallback = fallback or mcl_mobs.fallback_node + + local node = minetest.get_node_or_nil(pos) + + if node and minetest.registered_nodes[node.name] then + return node + end + + return minetest.registered_nodes[fallback] +end + +-- check if within physical map limits (-30911 to 30927) +local function within_limits(pos, radius) + local wmin, wmax = -30912, 30928 + if mcl_vars then + if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then + wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max + end + end + if radius then + wmin = wmin - radius + wmax = wmax + radius + end + if not pos then return true end + for _,v in pairs(pos) do + if v < wmin or v > wmax then return false end + end + return true +end + +function mob_class:player_in_active_range() + for _,p in pairs(minetest.get_connected_players()) do + if vector.distance(self.object:get_pos(),p:get_pos()) <= mob_active_range then return true end + -- slightly larger than the mc 32 since mobs spawn on that circle and easily stand still immediately right after spawning. + end +end + +-- Return true if object is in view_range +function mob_class:object_in_range(object) + if not object then + return false + end + local factor + -- Apply view range reduction for special player armor + if object:is_player() then + local factors = mcl_armor.player_view_range_factors[object] + factor = factors and factors[self.name] + end + -- Distance check + local dist + if factor and factor == 0 then + return false + elseif factor then + dist = self.view_range * factor + else + dist = self.view_range + end + + local p1, p2 = self.object:get_pos(), object:get_pos() + return p1 and p2 and (vector.distance(p1, p2) <= dist) +end + +function mob_class:item_drop(cooked, looting_level) + + if not mobs_drop_items then return end + + looting_level = looting_level or 0 + + if (self.child and self.type ~= "monster") then + return + end + + local obj, item, num + local pos = self.object:get_pos() + + self.drops = self.drops or {} + + for n = 1, #self.drops do + local dropdef = self.drops[n] + local chance = 1 / dropdef.chance + local looting_type = dropdef.looting + + if looting_level > 0 then + local chance_function = dropdef.looting_chance_function + if chance_function then + chance = chance_function(looting_level) + elseif looting_type == "rare" then + chance = chance + (dropdef.looting_factor or 0.01) * looting_level + end + end + + local num = 0 + local do_common_looting = (looting_level > 0 and looting_type == "common") + if math.random() < chance then + num = math.random(dropdef.min or 1, dropdef.max or 1) + elseif not dropdef.looting_ignore_chance then + do_common_looting = false + end + + if do_common_looting then + num = num + math.floor(math.random(0, looting_level) + 0.5) + end + + if num > 0 then + item = dropdef.name + + if cooked then + + local output = minetest.get_craft_result({ + method = "cooking", width = 1, items = {item}}) + + if output and output.item and not output.item:is_empty() then + item = output.item:get_name() + end + end + + for x = 1, num do + obj = minetest.add_item(pos, ItemStack(item .. " " .. 1)) + end + + if obj and obj:get_luaentity() then + + obj:set_velocity({ + x = math.random(-10, 10) / 9, + y = 6, + z = math.random(-10, 10) / 9, + }) + elseif obj then + obj:remove() -- item does not exist + end + end + end + + self.drops = {} +end + +-- collision function borrowed amended from jordan4ibanez open_ai mod +function mob_class:collision() + local pos = self.object:get_pos() + if not pos then return {0,0} end + local vel = self.object:get_velocity() + local x = 0 + local z = 0 + local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 + for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do + + local ent = object:get_luaentity() + if object:is_player() or (ent and ent.is_mob and object ~= self.object) then + + if object:is_player() and mcl_burning.is_burning(self.object) then + mcl_burning.set_on_fire(object, 4) + end + + local pos2 = object:get_pos() + local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} + local force = (width + 0.5) - vector.distance( + {x = pos.x, y = 0, z = pos.z}, + {x = pos2.x, y = 0, z = pos2.z}) + + x = x + (vec.x * force) + z = z + (vec.z * force) + end + end + + return({x,z}) +end + +function mob_class:slow_mob() + local d = 0.85 + if self:check_dying() then d = 0.92 end + + local v = self.object:get_velocity() + if v then + --diffuse object velocity + self.object:set_velocity({x = v.x*d, y = v.y, z = v.z*d}) + end +end + +-- move mob in facing direction +function mob_class:set_velocity(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(self:collision()) + end + + -- halt mob if it has been ordered to stay + if self.order == "stand" or self.order == "sit" then + self.acc=vector.new(0,0,0) + return + end + + local yaw = (self.object:get_yaw() or 0) + self.rotate + local vv = self.object:get_velocity() + if vv then + self.acc={ + x = ((math.sin(yaw) * -v) + c_x)*.27, + y = 0, + z = ((math.cos(yaw) * v) + c_y)*.27, + } + end +end + +-- calculate mob velocity +function mob_class:get_velocity() + local v = self.object:get_velocity() + if v then + return (v.x * v.x + v.z * v.z) ^ 0.5 + end + + return 0 +end + +function mob_class:update_roll() + local is_Fleckenstein = self.nametag == "Fleckenstein" + local was_Fleckenstein = false + + local rot = self.object:get_rotation() + rot.z = is_Fleckenstein and pi or 0 + self.object:set_rotation(rot) + + local cbox = table.copy(self.collisionbox) + local acbox = self.object:get_properties().collisionbox + + if math.abs(cbox[2] - acbox[2]) > 0.1 then + was_Fleckenstein = true + end + + if is_Fleckenstein ~= was_Fleckenstein then + local pos = self.object:get_pos() + pos.y = pos.y + (acbox[2] + acbox[5]) + self.object:set_pos(pos) + end + + if is_Fleckenstein then + cbox[2], cbox[5] = -cbox[5], -cbox[2] + self.object:set_properties({collisionbox = cbox}) + -- This leads to child mobs having the wrong collisionbox + -- and seeing as it seems to be nothing but an easter egg + -- i've put it inside the if. Which just makes it be upside + -- down lol. + end + +end + +local function shortest_term_of_yaw_rotation(self, rot_origin, rot_target, nums) + + if not rot_origin or not rot_target then + return + end + + rot_origin = math.deg(rot_origin) + rot_target = math.deg(rot_target) + + if rot_origin < rot_target then + if math.abs(rot_origin-rot_target)<180 then + if nums then + return rot_target-rot_origin + else + return 1 + end + else + if nums then + return -(rot_origin-(rot_target-360)) + else + return -1 + end + end + else + if math.abs(rot_origin-rot_target)<180 then + if nums then + return rot_target-rot_origin + else + return -1 + end + else + if nums then + return (rot_target-(rot_origin-360)) + else + return 1 + end + end + end + +end + + + +-- set and return valid yaw +function mob_class:set_yaw(yaw, delay, dtime) + if self.noyaw then return end + + if self.state ~= PATHFINDING then + self._turn_to = yaw + end + + --mcl_log("Yaw is: \t\t" .. tostring(math.deg(yaw))) + --mcl_log("self.object:get_yaw() is: \t" .. tostring(math.deg(self.object:get_yaw()))) + + --clamp our yaw to a 360 range + if math.deg(self.object:get_yaw()) > 360 then + self.object:set_yaw(math.rad(0)) + elseif math.deg(self.object:get_yaw()) < 0 then + self.object:set_yaw(math.rad(360)) + end + + if math.deg(yaw) > 360 then + yaw=yaw%360 + elseif math.deg(yaw) < 0 then + yaw=((360*5)-yaw)%360 + end + + --calculate the shortest way to turn to find our target + local target_shortest_path = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), yaw, false) + local target_shortest_path_nums = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), yaw, true) + + --turn in the shortest path possible toward our target. if we are attacking, don't dance. + if (math.abs(target_shortest_path) > 50 and not self._kb_turn) and (self.attack and self.attack:get_pos() or self.following and self.following:get_pos()) then + if self.following then + target_shortest_path = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.following:get_pos())), true) + target_shortest_path_nums = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.following:get_pos())), false) + else + target_shortest_path = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos())), true) + target_shortest_path_nums = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos())), false) + end + end + + local ddtime = 0.05 --set_tick_rate + + if dtime then + ddtime = dtime + end + + if math.abs(target_shortest_path_nums) > 5 then + self.object:set_yaw(self.object:get_yaw()+(target_shortest_path*(3.6*ddtime))) + if self.acc then + self.acc=vector.rotate_around_axis(self.acc,vector.new(0,1,0), target_shortest_path*(3.6*ddtime)) + end + end + + delay = delay or 0 + + yaw = self.object:get_yaw() + + if delay == 0 then + if self.shaking and dtime then + yaw = yaw + (math.random() * 2 - 1) * 5 * dtime + end + --self:update_roll() + return yaw + end + + self.target_yaw = yaw + self.delay = delay + + return self.target_yaw +end + +-- global function to set mob yaw +function mcl_mobs.yaw(self, yaw, delay, dtime) + return mob_class.set_yaw(self, yaw, delay, dtime) +end + +-- are we flying in what we are suppose to? (taikedz) +function mob_class:flight_check() + + local nod = self.standing_in + local def = minetest.registered_nodes[nod] + + if not def then return false end -- nil check + + local fly_in + if type(self.fly_in) == "string" then + fly_in = { self.fly_in } + elseif type(self.fly_in) == "table" then + fly_in = self.fly_in + else + return false + end + + for _,checknode in pairs(fly_in) do + if nod == checknode or nod == "ignore" then + return true + end + end + + return false +end + +-- check if mob is dead or only hurt +function mob_class:check_for_death(cause, cmi_cause) + + if self.state == "die" then + return true + end + + -- has health actually changed? + if self.health == self.old_health and self.health > 0 then + return false + end + + local damaged = self.health < self.old_health + self.old_health = self.health + + -- still got some health? + if self.health > 0 then + + -- make sure health isn't higher than max + if self.health > self.hp_max then + self.health = self.hp_max + end + + -- play damage sound if health was reduced and make mob flash red. + if damaged then + self:add_texture_mod("^[colorize:#d42222:175") + minetest.after(1, function(self) + if self and self.object then + self:remove_texture_mod("^[colorize:#d42222:175") + end + end, self) + self:mob_sound("damage") + end + + -- backup nametag so we can show health stats + if not self.nametag2 then + self.nametag2 = self.nametag or "" + end + + if show_health + and (cmi_cause and cmi_cause.type == "punch") then + + self.htimer = 2 + self.nametag = "♥ " .. self.health .. " / " .. self.hp_max + + self:update_tag() + end + + return false + end + + self:mob_sound("death") + + local function death_handle(self) + -- dropped cooked item if mob died in fire or lava + if cause == "lava" or cause == "fire" then + self:item_drop(true, 0) + else + local wielditem = ItemStack() + if cause == "hit" then + local puncher = cmi_cause.puncher + if puncher then + wielditem = puncher:get_wielded_item() + end + end + local cooked = mcl_burning.is_burning(self.object) or mcl_enchanting.has_enchantment(wielditem, "fire_aspect") + local looting = mcl_enchanting.get_enchantment(wielditem, "looting") + self:item_drop(cooked, looting) + + if ((not self.child) or self.type ~= "animal") and (minetest.get_us_time() - self.xp_timestamp <= math.huge) then + mcl_experience.throw_xp(self.object:get_pos(), math.random(self.xp_min, self.xp_max)) + end + end + end + + -- execute custom death function + if self.on_die then + + local pos = self.object:get_pos() + local on_die_exit = self.on_die(self, pos, cmi_cause) + if on_die_exit ~= true then + death_handle(self) + end + + if on_die_exit == true then + self.state = "die" + mcl_burning.extinguish(self.object) + self.object:remove() + return true + end + end + + local collisionbox + if self.collisionbox then + collisionbox = table.copy(self.collisionbox) + end + + self.state = "die" + self.attack = nil + self.v_start = false + self.fall_speed = DEFAULT_FALL_SPEED + self.timer = 0 + self.blinktimer = 0 + self:remove_texture_mod("^[colorize:#FF000040") + self:remove_texture_mod("^[brighten") + self.passive = true + + self.object:set_properties({ + pointable = false, + collide_with_objects = false, + }) + + self:set_velocity(0) + local acc = self.object:get_acceleration() + acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0 + self.object:set_acceleration(acc) + + local length + -- default death function and die animation (if defined) + if self.instant_death then + length = 0 + elseif self.animation + and self.animation.die_start + and self.animation.die_end then + + local frames = self.animation.die_end - self.animation.die_start + local speed = self.animation.die_speed or 15 + length = math.max(frames / speed, 0) + DEATH_DELAY + self:set_animation( "die") + else + length = 1 + DEATH_DELAY + self:set_animation( "stand", true) + end + + + -- Remove body after a few seconds and drop stuff + local kill = function(self) + if not self.object:get_luaentity() then + return + end + + death_handle(self) + local dpos = self.object:get_pos() + local cbox = self.collisionbox + local yaw = self.object:get_rotation().y + mcl_burning.extinguish(self.object) + self.object:remove() + mcl_mobs.death_effect(dpos, yaw, cbox, not self.instant_death) + end + if length <= 0 then + kill(self) + else + minetest.after(length, kill, self) + end + + return true +end + +-- Deal light damage to mob, returns true if mob died +function mob_class:deal_light_damage(pos, damage) + if not ((mcl_weather.rain.raining or mcl_weather.state == "snow") and mcl_weather.is_outdoor(pos)) then + self.health = self.health - damage + + mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png") + + if self:check_for_death("light", {type = "light"}) then + return true + end + end +end + +-- environmental damage (water, lava, fire, light etc.) +function mob_class:do_env_damage() + -- feed/tame text timer (so mob 'full' messages dont spam chat) + if self.htimer > 0 then + self.htimer = self.htimer - 1 + end + + -- reset nametag after showing health stats + if self.htimer < 1 and self.nametag2 then + + self.nametag = self.nametag2 + self.nametag2 = nil + + self:update_tag() + end + + local pos = self.object:get_pos() + if not pos then return end + + self.time_of_day = minetest.get_timeofday() + + -- remove mob if beyond map limits + if not within_limits(pos, 0) then + mcl_burning.extinguish(self.object) + self.object:remove() + return true + end + + local sunlight = minetest.get_natural_light(pos, self.time_of_day) + + -- bright light harms mob + if self.light_damage ~= 0 and (sunlight or 0) > 12 then + if self:deal_light_damage(pos, self.light_damage) then + return true + end + end + local _, dim = mcl_worlds.y_to_layer(pos.y) + if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (sunlight or 0) >= minetest.LIGHT_MAX and dim == "overworld" then + if self.armor_list and not self.armor_list.helmet or not self.armor_list or self.armor_list and self.armor_list.helmet and self.armor_list.helmet == "" then + if self.ignited_by_sunlight then + mcl_burning.set_on_fire(self.object, 10) + else + self:deal_light_damage(pos, self.sunlight_damage) + return true + end + end + end + + local y_level = self.collisionbox[2] + + if self.child then + y_level = self.collisionbox[2] * 0.5 + end + + -- what is mob standing in? + pos.y = pos.y + y_level + 0.25 -- foot level + local pos2 = {x=pos.x, y=pos.y-1, z=pos.z} + self.standing_in = node_ok(pos, "air").name + self.standing_on = node_ok(pos2, "air").name + + -- don't fall when on ignore, just stand still + if self.standing_in == "ignore" then + self.object:set_velocity({x = 0, y = 0, z = 0}) + end + + local nodef = minetest.registered_nodes[self.standing_in] + + -- rain + if self.rain_damage > 0 then + if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then + + self.health = self.health - self.rain_damage + + if self:check_for_death("rain", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + end + + pos.y = pos.y + 1 -- for particle effect position + + -- water damage + if self.water_damage > 0 + and nodef.groups.water then + + if self.water_damage ~= 0 then + + self.health = self.health - self.water_damage + + mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png", nil, nil, 1, nil) + + if self:check_for_death("water", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + + -- lava damage + elseif self.lava_damage > 0 + and (nodef.groups.lava) then + + if self.lava_damage ~= 0 then + + self.health = self.health - self.lava_damage + + mcl_mobs.effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) + mcl_burning.set_on_fire(self.object, 10) + + if self:check_for_death("lava", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + + -- fire damage + elseif self.fire_damage > 0 + and (nodef.groups.fire) then + + if self.fire_damage ~= 0 then + + self.health = self.health - self.fire_damage + + mcl_mobs.effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) + mcl_burning.set_on_fire(self.object, 5) + + if self:check_for_death("fire", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + + -- damage_per_second node check + elseif nodef.damage_per_second ~= 0 and not nodef.groups.lava and not nodef.groups.fire then + + self.health = self.health - nodef.damage_per_second + + mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png") + + if self:check_for_death("dps", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + + -- Drowning damage + if self.breath_max ~= -1 then + local drowning = false + if self.breathes_in_water then + if minetest.get_item_group(self.standing_in, "water") == 0 then + drowning = true + end + elseif nodef.drowning > 0 then + drowning = true + end + if drowning then + + self.breath = math.max(0, self.breath - 1) + + mcl_mobs.effect(pos, 2, "bubble.png", nil, nil, 1, nil) + if self.breath <= 0 then + local dmg + if nodef.drowning > 0 then + dmg = nodef.drowning + else + dmg = 4 + end + self:damage_effect(dmg) + self.health = self.health - dmg + end + if self:check_for_death("drowning", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + else + self.breath = math.min(self.breath_max, self.breath + 1) + end + end + + --- suffocation inside solid node + -- FIXME: Redundant with mcl_playerplus + if (self.suffocation == true) + and (nodef.walkable == nil or nodef.walkable == true) + and (nodef.collision_box == nil or nodef.collision_box.type == "regular") + and (nodef.node_box == nil or nodef.node_box.type == "regular") + and (nodef.groups.disable_suffocation ~= 1) + and (nodef.groups.opaque == 1) then + + -- Short grace period before starting to take suffocation damage. + -- This is different from players, who take damage instantly. + -- This has been done because mobs might briefly be inside solid nodes + -- when e.g. climbing up stairs. + -- This is a bit hacky because it assumes that do_env_damage + -- is called roughly every second only. + self.suffocation_timer = self.suffocation_timer + 1 + if self.suffocation_timer >= 3 then + -- 2 damage per second + -- TODO: Deal this damage once every 1/2 second + self.health = self.health - 2 + + if self:check_for_death("suffocation", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + else + self.suffocation_timer = 0 + end + + return self:check_for_death("", {type = "unknown"}) +end + +function mob_class:env_damage (dtime, pos) + -- environmental damage timer (every 1 second) + self.env_damage_timer = self.env_damage_timer + dtime + + if (self.state == "attack" and self.env_damage_timer > 1) + or self.state ~= "attack" then + self:check_entity_cramming() + self.env_damage_timer = 0 + + -- check for environmental damage (water, fire, lava etc.) + if self:do_env_damage() then + return true + end + + -- node replace check (cow eats grass etc.) + self:replace(pos) + end +end + +function mob_class:damage_mob(reason,damage) + if not self.health then return end + damage = math.floor(damage) + if damage > 0 then + self.health = self.health - damage + + mcl_mobs.effect(self.object:get_pos(), 5, "mcl_particles_smoke.png", 1, 2, 2, nil) + + if self:check_for_death(reason, {type = reason}) then + return true + end + end +end + +function mob_class:check_entity_cramming() + local p = self.object:get_pos() + if not p then return end + local oo = minetest.get_objects_inside_radius(p,1) + local mobs = {} + for _,o in pairs(oo) do + local l = o:get_luaentity() + if l and l.is_mob and l.health > 0 then table.insert(mobs,l) end + end + local clear = #mobs < ENTITY_CRAMMING_MAX + local ncram = {} + for _,l in pairs(mobs) do + if l then + if clear then + l.cram = nil + elseif l.cram == nil and not self.child then + table.insert(ncram,l) + elseif l.cram then + l:damage_mob("cramming",CRAMMING_DAMAGE) + end + end + end + for i,l in pairs(ncram) do + if i > ENTITY_CRAMMING_MAX then + l.cram = true + else + l.cram = nil + end + end +end + +-- falling and fall damage +-- returns true if mob died +function mob_class:falling(pos) + + if self.fly and self.state ~= "die" then + return + end + + if not self.fall_speed then self.fall_speed = DEFAULT_FALL_SPEED end + + if mcl_portals ~= nil then + if mcl_portals.nether_portal_cooloff(self.object) then + return false -- mob has teleported through Nether portal - it's 99% not falling + end + end + + -- floating in water (or falling) + local v = self.object:get_velocity() + + if v.y > 0 then + + -- apply gravity when moving up + self.object:set_acceleration({ + x = 0, + y = DEFAULT_FALL_SPEED, + 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 / (math.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 + + -- fall damage onto solid ground + if self.fall_damage == 1 + and self.object:get_velocity().y == 0 then + local n = node_ok(vector.offset(pos,0,-1,0)).name + local d = (self.old_y or 0) - self.object:get_pos().y + + if d > 5 and n ~= "air" and n ~= "ignore" then + local add = minetest.get_item_group(self.standing_on, "fall_damage_add_percent") + local damage = d - 5 + if add ~= 0 then + damage = damage + damage * (add/100) + end + self:damage_mob("fall",damage) + end + + self.old_y = self.object:get_pos().y + end + end +end + +function mob_class:check_water_flow() + -- Add water flowing for mobs from mcl_item_entity + local p, node, nn, def + p = self.object:get_pos() + node = minetest.get_node_or_nil(p) + if node then + nn = node.name + def = minetest.registered_nodes[nn] + end + + -- Move item around on flowing liquids + if def and def.liquidtype == "flowing" then + + --[[ Get flowing direction (function call from flowlib), if there's a liquid. + NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7. + Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]] + local vec = flowlib.quick_flow(p, node) + -- Just to make sure we don't manipulate the speed for no reason + if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then + -- Minecraft Wiki: Flowing speed is "about 1.39 meters per second" + local f = 1.39 + -- Set new item moving speed into the direciton of the liquid + local newv = vector.multiply(vec, f) + self.object:set_acceleration({x = 0, y = 0, z = 0}) + self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z}) + + self.physical_state = true + self._flowing = true + self.object:set_properties({ + physical = true + }) + return + end + elseif self._flowing == true then + -- Disable flowing physics if not on/in flowing liquid + self._flowing = false + return + end +end + +function mob_class:check_dying() + if ((self.state and self.state=="die") or self:check_for_death()) and not self.animation.die_end then + local rot = self.object:get_rotation() + rot.z = ((math.pi/2-rot.z)*.2)+rot.z + self.object:set_rotation(rot) + return true + end +end + +function mob_class:check_suspend() + if not self:player_in_active_range() then + local pos = self.object:get_pos() + local node_under = node_ok(vector.offset(pos,0,-1,0)).name + local acc = self.object:get_acceleration() + self:set_animation( "stand", true) + if acc.y > 0 or node_under ~= "air" then + self.object:set_acceleration(vector.new(0,0,0)) + self.object:set_velocity(vector.new(0,0,0)) + end + if acc.y == 0 and node_under == "air" then + self:falling(pos) + end + return true + end +end diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index 74fcc3255..01ef2a823 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -1,4 +1,7 @@ --lua locals +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + local get_node = minetest.get_node local get_item_group = minetest.get_item_group local get_node_light = minetest.get_node_light @@ -15,7 +18,7 @@ local math_cos = math.cos local math_sin = math.sin local math_round = function(x) return (x > 0) and math_floor(x + 0.5) or math_ceil(x - 0.5) end ---local vector_distance = vector.distance +local vector_distance = vector.distance local vector_new = vector.new local vector_floor = vector.floor @@ -23,13 +26,27 @@ local table_copy = table.copy local table_remove = table.remove local pairs = pairs - +local dbg_spawn_attempts = 0 +local dbg_spawn_succ = 0 +local dbg_spawn_counts = {} -- range for mob count -local aoc_range = 32 +local aoc_range = 136 +local remove_far = true + +local mob_cap = { + monster = tonumber(minetest.settings:get("mcl_mob_cap_monster")) or 70, + animal = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 10, + ambient = tonumber(minetest.settings:get("mcl_mob_cap_ambient")) or 15, + water = tonumber(minetest.settings:get("mcl_mob_cap_water")) or 5, --currently unused + water_ambient = tonumber(minetest.settings:get("mcl_mob_cap_water_ambient")) or 20, --currently unused + player = tonumber(minetest.settings:get("mcl_mob_cap_player")) or 75, + total = tonumber(minetest.settings:get("mcl_mob_cap_total")) or 500, +} --do mobs spawn? local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false - +local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false +local logging = minetest.settings:get_bool("mcl_logging_mobs_spawn",true) local noise_params = { offset = 0, @@ -63,6 +80,7 @@ local list_of_all_biomes = { "JungleM_underground", "ExtremeHillsM_underground", "JungleEdgeM_underground", + "MangroveSwamp_underground", -- ocean: @@ -126,6 +144,8 @@ local list_of_all_biomes = { "BirchForestM_deep_ocean", "Taiga_deep_ocean", "JungleM_ocean", + "MangroveSwamp_ocean", + "MangroveSwamp_deep_ocean", -- water or beach? @@ -149,10 +169,15 @@ local list_of_all_biomes = { "MushroomIslandShore", "JungleM_shore", "Jungle_shore", + "MangroveSwamp_shore", -- dimension biome: "Nether", + "BasaltDelta", + "CrimsonForest", + "WarpedForest", + "SoulsandValley", "End", -- Overworld regular: @@ -162,6 +187,8 @@ local list_of_all_biomes = { "Swampland", "Taiga", "ExtremeHills", + "ExtremeHillsM", + "ExtremeHills+_snowtop", "Jungle", "Savanna", "BirchForest", @@ -180,7 +207,6 @@ local list_of_all_biomes = { "ExtremeHills+_snowtop", "MesaPlateauFM_grasstop", "JungleEdgeM", - "ExtremeHillsM", "JungleM", "BirchForestM", "MesaPlateauF", @@ -189,19 +215,46 @@ local list_of_all_biomes = { "MesaBryce", "JungleEdge", "SavannaM", + "MangroveSwamp", } -- count how many mobs are in an area -local function count_mobs(pos) +local function count_mobs(pos,r,mob_type) 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().is_mob then - num = num + 1 + for _,l in pairs(minetest.luaentities) do + if l and l.is_mob and (mob_type == nil or l.type == mob_type) then + local p = l.object:get_pos() + if p and vector_distance(p,pos) < r then + num = num + 1 + end end end return num end +local function count_mobs_total(mob_type) + local num = 0 + for _,l in pairs(minetest.luaentities) do + if l.is_mob then + if mob_type == nil or l.type == mob_type then + num = num + 1 + end + end + end + return num +end + +local function count_mobs_total_cap(mob_type) + local num = 0 + for _,l in pairs(minetest.luaentities) do + if l.is_mob then + if ( mob_type == nil or l.type == mob_type ) and l.can_despawn and not l.nametag then + num = num + 1 + end + end + end + return num +end -- global functions @@ -289,7 +342,7 @@ function mcl_mobs:spawn_setup(def) spawn_dictionary[#spawn_dictionary + 1] = { name = name, dimension = dimension, - type_of_spawning = type_of_spawning, + type_of_spawning = type_of_spawning, biomes = biomes, min_light = min_light, max_light = max_light, @@ -349,11 +402,9 @@ local two_pi = 2 * math.pi local function get_next_mob_spawn_pos(pos) local distance = math_random(25, 32) local angle = math_random() * two_pi - return { - x = math_round(pos.x + distance * math_cos(angle)), - y = pos.y, - z = math_round(pos.z + distance * math_sin(angle)) - } + local xoff = math_round(distance * math_cos(angle)) + local yoff = math_round(distance * math_sin(angle)) + return vector.offset(pos, xoff, 0, yoff) end local function decypher_limits(posy) @@ -376,13 +427,214 @@ local function is_farm_animal(n) return n == "mobs_mc:pig" or n == "mobs_mc:cow" or n == "mobs_mc:sheep" or n == "mobs_mc:chicken" or n == "mobs_mc:horse" or n == "mobs_mc:donkey" end +local function get_water_spawn(p) + local nn = minetest.find_nodes_in_area(vector.offset(p,-2,-1,-2),vector.offset(p,2,-15,2),{"group:water"}) + if nn and #nn > 0 then + return nn[math.random(#nn)] + end +end + +local function has_room(self,pos) + local cb = self.collisionbox + local nodes = {} + if self.fly_in then + local t = type(self.fly_in) + if t == "table" then + nodes = table.copy(self.fly_in) + elseif t == "string" then + table.insert(nodes,self.fly_in) + end + end + table.insert(nodes,"air") + local x = cb[4] - cb[1] + local y = cb[5] - cb[2] + local z = cb[6] - cb[3] + local r = math.ceil(x * y * z) + local p1 = vector.offset(pos,cb[1],cb[2],cb[3]) + local p2 = vector.offset(pos,cb[4],cb[5],cb[6]) + local n = #minetest.find_nodes_in_area(p1,p2,nodes) or 0 + if r > n then + minetest.log("warning","[mcl_mobs] No room for mob "..self.name.." at "..minetest.pos_to_string(vector.round(pos))) + return false + end + return true +end + +local function spawn_check(pos,spawn_def,ignore_caps) + if not spawn_def then return end + dbg_spawn_attempts = dbg_spawn_attempts + 1 + local dimension = mcl_worlds.pos_to_dimension(pos) + local mob_def = minetest.registered_entities[spawn_def.name] + local mob_type = mob_def.type + local gotten_node = get_node(pos).name + local gotten_biome = minetest.get_biome_data(pos) + if not gotten_node or not gotten_biome then return end + gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with + + local is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0 + if not is_ground then + pos.y = pos.y - 1 + gotten_node = get_node(pos).name + is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0 + end + pos.y = pos.y + 1 + local is_water = get_item_group(gotten_node, "water") ~= 0 + local is_lava = get_item_group(gotten_node, "lava") ~= 0 + local is_leaf = get_item_group(gotten_node, "leaves") ~= 0 + local is_bedrock = gotten_node == "mcl_core:bedrock" + local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0 + local mob_count_wide = 0 + + local mob_count = 0 + if not ignore_caps then + mob_count = count_mobs(pos,32,mob_type) + mob_count_wide = count_mobs(pos,aoc_range,mob_type) + end + + if pos and spawn_def + and ( mob_count_wide < (mob_cap[mob_type] or 15) ) + and ( mob_count < 5 ) + and pos.y >= spawn_def.min_height + and pos.y <= spawn_def.max_height + and spawn_def.dimension == dimension + and biome_check(spawn_def.biomes, gotten_biome) + and (is_ground or spawn_def.type_of_spawning ~= "ground") + and (spawn_def.type_of_spawning ~= "ground" or not is_leaf) + and has_room(mob_def,pos) + and (spawn_def.check_position and spawn_def.check_position(pos) or true) + and (not is_farm_animal(spawn_def.name) or is_grass) + and (spawn_def.type_of_spawning ~= "water" or is_water) + and ( not spawn_protected or not minetest.is_protected(pos, "") ) + and not is_bedrock then + --only need to poll for node light if everything else worked + local gotten_light = get_node_light(pos) + if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then + return true + end + end + return false +end + +function mcl_mobs.spawn(pos,id) + local def = minetest.registered_entities[id] or minetest.registered_entities["mobs_mc:"..id] or minetest.registered_entities["extra_mobs:"..id] + if not def or (def.can_spawn and not def.can_spawn(pos)) or not def.is_mob then + return false + end + if not dbg_spawn_counts[def.name] then + dbg_spawn_counts[def.name] = 1 + else + dbg_spawn_counts[def.name] = dbg_spawn_counts[def.name] + 1 + end + return minetest.add_entity(pos, def.name) +end + + +local function spawn_group(p,mob,spawn_on,group_max,group_min) + if not group_min then group_min = 1 end + local nn= minetest.find_nodes_in_area_under_air(vector.offset(p,-5,-3,-5),vector.offset(p,5,3,5),spawn_on) + local o + table.shuffle(nn) + if not nn or #nn < 1 then + nn = {} + table.insert(nn,p) + end + for i = 1, math.random(group_min,group_max) do + local sp = vector.offset(nn[math.random(#nn)],0,1,0) + if spawn_check(nn[math.random(#nn)],mob,true) then + if mob.type_of_spawning == "water" then + sp = get_water_spawn(sp) + end + o = mcl_mobs.spawn(sp,mob.name) + if o then dbg_spawn_succ = dbg_spawn_succ + 1 end + end + end + return o +end + +mcl_mobs.spawn_group = spawn_group + +local S = minetest.get_translator("mcl_mobs") + +minetest.register_chatcommand("spawn_mob",{ + privs = { debug = true }, + description=S("spawn_mob is a chatcommand that allows you to type in the name of a mob without 'typing mobs_mc:' all the time like so; 'spawn_mob spider'. however, there is more you can do with this special command, currently you can edit any number, boolean, and string variable you choose with this format: spawn_mob 'any_mob:var:'. any_mob being your mob of choice, mobs_variable being the variable, and variable value being the value of the chosen variable. and example of this format: \n spawn_mob skeleton:var:\n this would spawn a skeleton that wouldn't attack you. REMEMBER-THIS> when changing a number value always prefix it with 'NUM', example: \n spawn_mob skeleton:var:\n this setting the skelly's jump height to 10. if you want to make multiple changes to a mob, you can, example: \n spawn_mob skeleton:var::var::var::var:\n etc."), + func = function(n,param) + local pos = minetest.get_player_by_name(n):get_pos() + + local modifiers = {} + for capture in string.gmatch(param, "%:(.-)%:") do + table.insert(modifiers, ":"..capture) + end + + local mod1 = string.find(param, ":") + + + + local mobname = param + if mod1 then + mobname = string.sub(param, 1, mod1-1) + end + + local mob = mcl_mobs.spawn(pos,mobname) + + if mob then + for c=1, #modifiers do + modifs = modifiers[c] + + local mod1 = string.find(modifs, ":") + local mod_start = string.find(modifs, "<") + local mod_vals = string.find(modifs, "=") + local mod_end = string.find(modifs, ">") + local mob_entity = mob:get_luaentity() + if string.sub(modifs, mod1+1, mod1+3) == "var" then + if mod1 and mod_start and mod_vals and mod_end then + local variable = string.sub(modifs, mod_start+1, mod_vals-1) + local value = string.sub(modifs, mod_vals+1, mod_end-1) + + number_tag = string.find(value, "NUM") + if number_tag then + value = tonumber(string.sub(value, 4, -1)) + end + + if value == "true" then + value = true + elseif value == "false" then + value = false + end + + if not mob_entity[variable] then + minetest.log("warning", n.." mob variable "..variable.." previously unset") + end + + mob_entity[variable] = value + + else + minetest.log("warning", n.." couldn't modify "..mobname.." at "..minetest.pos_to_string(pos).. ", missing paramaters") + end + else + minetest.log("warning", n.." couldn't modify "..mobname.." at "..minetest.pos_to_string(pos).. ", missing modification type") + end + end + + minetest.log("action", n.." spawned "..mobname.." at "..minetest.pos_to_string(pos)) + return true, mobname.." spawned at "..minetest.pos_to_string(pos) + else + return false, "Couldn't spawn "..mobname + end + end +}) + if mobs_spawn then local perlin_noise local function spawn_a_mob(pos, dimension, y_min, y_max) - local dimension = dimension or mcl_worlds.pos_to_dimension(pos) + --create a disconnected clone of the spawn dictionary + --prevents memory leak + local mob_library_worker_table = table_copy(spawn_dictionary) local goal_pos = get_next_mob_spawn_pos(pos) + --grab mob that fits into the spawning location + --randomly grab a mob, don't exclude any possibilities local spawning_position_list = find_nodes_in_area_under_air( {x = goal_pos.x, y = y_min, z = goal_pos.z}, {x = goal_pos.x, y = y_max, z = goal_pos.z}, @@ -391,41 +643,10 @@ if mobs_spawn then if #spawning_position_list <= 0 then return end local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)] - --hard code mob limit in area to 5 for now - if count_mobs(spawning_position) >= 5 then return end - - local gotten_node = get_node(spawning_position).name - local gotten_biome = minetest.get_biome_data(spawning_position) - if not gotten_node or not gotten_biome then return end - gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with - - --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 is_ground = not (is_water or is_lava) - local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0 - local has_bed = minetest.find_node_near(pos,25,{"group:bed"}) - - if not is_ground then - spawning_position.y = spawning_position.y - 1 - end - - local mob_def - - --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 perlin_noise = perlin_noise or minetest_get_perlin(noise_params) local noise = perlin_noise:get_3d(spawning_position) local current_summary_chance = summary_chance + table.shuffle(mob_library_worker_table) while #mob_library_worker_table > 0 do local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1 local mob_index = 1 @@ -437,24 +658,38 @@ if mobs_spawn then step_chance = step_chance + mob_chance end local mob_def = mob_library_worker_table[mob_index] - local mob_type = minetest.registered_entities[mob_def.name].type - if mob_def - and spawning_position.y >= mob_def.min_height - and spawning_position.y <= mob_def.max_height - and mob_def.dimension == dimension - and biome_check(mob_def.biomes, gotten_biome) - and gotten_light >= mob_def.min_light - and gotten_light <= mob_def.max_light - and (is_ground or mob_def.type_of_spawning ~= "ground") - and (mob_def.check_position and mob_def.check_position(spawning_position) or true) - and (not is_farm_animal(mob_def.name) or is_grass) - and (mob_type ~= "npc" or has_bed) - then - --everything is correct, spawn mob - local object = minetest.add_entity(spawning_position, mob_def.name) - if object then - return mob_def.on_spawn and mob_def.on_spawn(object, pos) + --minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance) + if mob_def and mob_def.name and minetest.registered_entities[mob_def.name] then + local spawn_in_group = minetest.registered_entities[mob_def.name].spawn_in_group or 4 + local spawn_in_group_min = minetest.registered_entities[mob_def.name].spawn_in_group_min or 1 + local mob_type = minetest.registered_entities[mob_def.name].type + if spawn_check(spawning_position,mob_def) then + if mob_def.type_of_spawning == "water" then + spawning_position = get_water_spawn(spawning_position) + if not spawning_position then + minetest.log("warning","[mcl_mobs] no water spawn for mob "..mob_def.name.." found at "..minetest.pos_to_string(vector.round(pos))) + return + end end + if minetest.registered_entities[mob_def.name].can_spawn and not minetest.registered_entities[mob_def.name].can_spawn(spawning_position) then + minetest.log("warning","[mcl_mobs] mob "..mob_def.name.." refused to spawn at "..minetest.pos_to_string(vector.round(spawning_position))) + return + end + --everything is correct, spawn mob + local object + if spawn_in_group and ( mob_type ~= "monster" or math.random(5) == 1 ) then + if logging then + minetest.log("action", "[mcl_mobs] A group of mob " .. mob_def.name .. " spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at " .. minetest.pos_to_string(spawning_position, 1)) + end + object = spawn_group(spawning_position,mob_def,{minetest.get_node(vector.offset(spawning_position,0,-1,0)).name},spawn_in_group,spawn_in_group_min) + + else + if logging then + minetest.log("action", "[mcl_mobs] Mob " .. mob_def.name .. " spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at ".. minetest.pos_to_string(spawning_position, 1)) + end + object = mcl_mobs.spawn(spawning_position, mob_def.name) + end + end end current_summary_chance = current_summary_chance - mob_chance table_remove(mob_library_worker_table, mob_index) @@ -469,16 +704,56 @@ if mobs_spawn then timer = timer + dtime if timer < 10 then return end timer = 0 - for _, player in pairs(get_connected_players()) do + local players = get_connected_players() + local total_mobs = count_mobs_total_cap() + if total_mobs > mob_cap.total or total_mobs > #players * mob_cap.player then + minetest.log("action","[mcl_mobs] global mob cap reached. no cycle spawning.") + return + end --mob cap per player + for _, player in pairs(players) do local pos = player:get_pos() local dimension = mcl_worlds.pos_to_dimension(pos) -- ignore void and unloaded area if dimension ~= "void" and dimension ~= "default" then local y_min, y_max = decypher_limits(pos.y) - for i = 1, math_random(1, 4) do - spawn_a_mob(pos, dimension, y_min, y_max) - end + spawn_a_mob(pos, dimension, y_min, y_max) end end end) end + +function mob_class:check_despawn(pos) + -- Despawning: when lifetimer expires, remove mob + if remove_far + and self.can_despawn == true + and ((not self.nametag) or (self.nametag == "")) + and self.state ~= "attack" + and self.following == nil then + if self.despawn_immediately or self.lifetimer <= 0 then + if logging then + minetest.log("action", "[mcl_mobs] Mob "..self.name.." despawns at "..minetest.pos_to_string(pos, 1) .. " lifetimer ran out") + end + mcl_burning.extinguish(self.object) + self.object:remove() + return true + elseif self.lifetimer <= 10 then + if math.random(10) < 4 then + self.despawn_immediately = true + else + self.lifetimer = 20 + end + end + end +end + +minetest.register_chatcommand("mobstats",{ + privs = { debug = true }, + func = function(n,param) + minetest.chat_send_player(n,dump(dbg_spawn_counts)) + local pos = minetest.get_player_by_name(n):get_pos() + minetest.chat_send_player(n,"mobs within 32 radius of player:"..count_mobs(pos,32)) + minetest.chat_send_player(n,"total mobs:"..count_mobs_total()) + minetest.chat_send_player(n,"spawning attempts since server start:"..dbg_spawn_attempts) + minetest.chat_send_player(n,"successful spawns since server start:"..dbg_spawn_succ) + end +}) diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ja.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ja.tr new file mode 100644 index 000000000..6b35b9edb --- /dev/null +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ja.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_paintings +Painting=絵画 diff --git a/mods/ENTITIES/mcl_wither_spawning/init.lua b/mods/ENTITIES/mcl_wither_spawning/init.lua index 2f1d744d8..74cd1e6e2 100644 --- a/mods/ENTITIES/mcl_wither_spawning/init.lua +++ b/mods/ENTITIES/mcl_wither_spawning/init.lua @@ -38,6 +38,12 @@ local function wither_spawn(pos) if check_schem(p, schem) then remove_schem(p, schem) minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither") + local objects = minetest.get_objects_inside_radius(pos, 20) + for _, players in ipairs(objects) do + if players:is_player() then + awards.unlock(players:get_player_name(), "mcl:witheringHeights") + end + end end end end @@ -46,6 +52,9 @@ end local wither_head = minetest.registered_nodes["mcl_heads:wither_skeleton"] local old_on_place = wither_head.on_place function wither_head.on_place(itemstack, placer, pointed) - minetest.after(0, wither_spawn, pointed.above) - old_on_place(itemstack, placer, pointed) + local n = minetest.get_node(vector.offset(pointed.above,0,-1,0)) + if n and n.name == "mcl_nether:soul_sand" then + minetest.after(0, wither_spawn, pointed.above) + end + return old_on_place(itemstack, placer, pointed) end diff --git a/mods/ENTITIES/mobs_mc/README.md b/mods/ENTITIES/mobs_mc/README.md index 4ee435d72..881f56619 100644 --- a/mods/ENTITIES/mobs_mc/README.md +++ b/mods/ENTITIES/mobs_mc/README.md @@ -58,6 +58,7 @@ This mod adds mobs which closely resemble the mobs from the game Minecraft, vers ### Peaceful mobs +* Axolotl * Chicken * Cow * Pig diff --git a/mods/ENTITIES/mobs_mc/axolotl.lua b/mods/ENTITIES/mobs_mc/axolotl.lua new file mode 100644 index 000000000..124f6bd3a --- /dev/null +++ b/mods/ENTITIES/mobs_mc/axolotl.lua @@ -0,0 +1,181 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local axolotl = { + type = "animal", + spawn_class = "water", + can_despawn = true, + passive = false, + hp_min = 14, + hp_max = 14, + xp_min = 1, + xp_max = 7, + + head_swivel = "head.control", + bone_eye_height = -1, + head_eye_height = -0.5, + horrizonatal_head_height = 0, + curiosity = 10, + head_yaw="z", + + armor = 100, + rotate = 180, + spawn_in_group_min = 1, + spawn_in_group = 4, + tilt_swim = true, + collisionbox = {-0.5, 0.0, -0.5, 0.5, 0.8, 0.5}, + visual = "mesh", + mesh = "mobs_mc_axolotl.b3d", + textures = { + {"mobs_mc_axolotl_brown.png"}, + {"mobs_mc_axolotl_yellow.png"}, + {"mobs_mc_axolotl_green.png"}, + {"mobs_mc_axolotl_pink.png"}, + {"mobs_mc_axolotl_black.png"}, + {"mobs_mc_axolotl_purple.png"}, + {"mobs_mc_axolotl_white.png"} + }, + sounds = { + random = "mobs_mc_axolotl", + damage = "mobs_mc_axolotl_hurt", + distance = 16, + }, + animation = {-- Stand: 1-20; Walk: 20-60; Swim: 61-81 + stand_start = 61, stand_end = 81, stand_speed = 15, + walk_start = 61, walk_end = 81, walk_speed = 15, + run_start = 61, run_end = 81, run_speed = 20, + }, + + follow = { + "mcl_fishing:clownfish_raw" + }, + + view_range = 16, + fear_height = 4, + + on_rightclick = function(self, clicker) + local bn = clicker:get_wielded_item():get_name() + if bn == "mcl_buckets:bucket_water" or bn == "mcl_buckets:bucket_river_water" then + if clicker:set_wielded_item("mcl_buckets:bucket_axolotl") then + local it = clicker:get_wielded_item() + local m = it:get_meta() + m:set_string("properties",minetest.serialize(self.object:get_properties())) + clicker:set_wielded_item(it) + self.object:remove() + end + awards.unlock(clicker:get_player_name(), "mcl:cutestPredator") + return + end + if self:feed_tame(clicker, 1, true, false) then return end + end, + makes_footstep_sound = false, + fly = true, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, + breathes_in_water = true, + jump = true, + damage = 2, + reach = 2, + attack_type = "dogfight", + attack_animals = true, + specific_attack = { + "extra_mobs_cod", + "mobs_mc:sheep", + "extra_mobs_glow_squid", + "extra_mobs_salmon", + "extra_mobs_tropical_fish", + "mobs_mc_squid" + }, + runaway = true, +} + +mcl_mobs.register_mob("mobs_mc:axolotl", axolotl) + +local water = 0 + +mcl_mobs:spawn_specific( +"mobs_mc:axolotl", +"overworld", +"water", +{ +"Swampland", +"MushroomIsland", +"RoofedForest", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"SunflowerPlains_ocean", +"Swampland_ocean", +"ExtremeHillsM_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"SavannaM_ocean", +"ExtremeHills_ocean", +"Forest_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"FlowerForest_ocean", +"Desert_ocean", +"Taiga_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"LushCaves", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +-- spawn eggs +mcl_mobs.register_egg("mobs_mc:axolotl", S("Axolotl"), "#e890bf", "#b83D7e", 0) diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index b41dabcba..b5532e2ee 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -2,11 +2,12 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:bat", { +mcl_mobs.register_mob("mobs_mc:bat", { description = S("Bat"), type = "animal", spawn_class = "ambient", can_despawn = true, + spawn_in_group = 8, passive = true, hp_min = 6, hp_max = 6, @@ -143,4 +144,4 @@ mobs_mc.water_level-1) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:bat", S("Bat"), "mobs_mc_spawn_icon_bat.png", 0) +mcl_mobs.register_egg("mobs_mc:bat", S("Bat"), "#4c3e30", "#0f0f0f", 0) diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index e0ff50909..18b7ea676 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -12,10 +12,12 @@ local mod_target = minetest.get_modpath("mcl_target") --################### -mcl_mobs:register_mob("mobs_mc:blaze", { +mcl_mobs.register_mob("mobs_mc:blaze", { description = S("Blaze"), type = "monster", spawn_class = "hostile", + spawn_in_group_min = 2, + spawn_in_group = 3, hp_min = 20, hp_max = 20, xp_min = 10, @@ -24,6 +26,12 @@ mcl_mobs:register_mob("mobs_mc:blaze", { rotate = -180, visual = "mesh", mesh = "mobs_mc_blaze.b3d", + head_swivel = "head.control", + bone_eye_height = 4, + head_eye_height = 3.5, + curiosity = 10, + head_yaw_offset = 180, + head_pitch_multiplier=-1, textures = { {"mobs_mc_blaze.png"}, }, @@ -145,7 +153,7 @@ mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) -- Blaze fireball -mcl_mobs:register_arrow("mobs_mc:blaze_fireball", { +mcl_mobs.register_arrow("mobs_mc:blaze_fireball", { visual = "sprite", visual_size = {x = 0.3, y = 0.3}, textures = {"mcl_fire_fire_charge.png"}, @@ -200,4 +208,4 @@ mcl_mobs:register_arrow("mobs_mc:blaze_fireball", { }) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:blaze", S("Blaze"), "mobs_mc_spawn_icon_blaze.png", 0) +mcl_mobs.register_egg("mobs_mc:blaze", S("Blaze"), "#f6b201", "#fff87e", 0) diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index a36b58502..399294390 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -8,7 +8,7 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:chicken", { +mcl_mobs.register_mob("mobs_mc:chicken", { description = S("Chicken"), type = "animal", spawn_class = "passive", @@ -20,12 +20,18 @@ mcl_mobs:register_mob("mobs_mc:chicken", { collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2}, runaway = true, floats = 1, + head_swivel = "head.control", + bone_eye_height = 4, + head_eye_height = 1.5, + horrizonatal_head_height = -.3, + curiosity = 10, + head_yaw="z", + visual_size = {x=1,y=1}, visual = "mesh", mesh = "mobs_mc_chicken.b3d", textures = { {"mobs_mc_chicken.png"}, }, - visual_size = {x=2.2, y=2.2}, makes_footstep_sound = true, walk_velocity = 1, @@ -58,12 +64,15 @@ mcl_mobs:register_mob("mobs_mc:chicken", { distance = 16, }, animation = { - stand_speed = 25, walk_speed = 25, run_speed = 50, - stand_start = 0, stand_end = 0, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 20, walk_speed = 25, + run_start = 0, run_end = 20, run_speed = 50, + }, + child_animations = { + stand_start = 31, stand_end = 31, + walk_start = 31, walk_end = 51, walk_speed = 37, + run_start = 31, run_end = 51, run_speed = 75, }, - follow = { "mcl_farming:wheat_seeds", "mcl_farming:melon_seeds", @@ -74,7 +83,7 @@ mcl_mobs:register_mob("mobs_mc:chicken", { fear_height = 4, on_rightclick = function(self, clicker) - if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end + if self:feed_tame(clicker, 1, true, false) then return end if mcl_mobs:protect(self, clicker) then return end if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end end, @@ -122,8 +131,6 @@ mcl_mobs:spawn_specific( "ExtremeHills_beach", "ExtremeHillsM", "ExtremeHills+", - "ExtremeHills+_snowtop", - "StoneBeach", "Plains", "Plains_beach", "SunflowerPlains", @@ -156,4 +163,4 @@ mobs_mc.water_level, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0) +mcl_mobs.register_egg("mobs_mc:chicken", S("Chicken"), "#a1a1a1", "#ff0000", 0) diff --git a/mods/ENTITIES/mobs_mc/cod.lua b/mods/ENTITIES/mobs_mc/cod.lua new file mode 100644 index 000000000..bc65faebe --- /dev/null +++ b/mods/ENTITIES/mobs_mc/cod.lua @@ -0,0 +1,275 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local pi = math.pi +local atann = math.atan +local atan = function(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + +local dir_to_pitch = function(dir) + local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +local function degrees(rad) + return rad * 180.0 / math.pi +end + +local S = minetest.get_translator(minetest.get_current_modname()) + +--################### +--################### cod +--################### + +local cod = { + type = "animal", + spawn_class = "water", + can_despawn = true, + passive = true, + hp_min = 3, + hp_max = 3, + xp_min = 1, + xp_max = 3, + armor = 100, + rotate = 180, + spawn_in_group_min = 3, + spawn_in_group = 8, + tilt_swim = true, + collisionbox = {-0.3, 0.0, -0.3, 0.3, 0.79, 0.3}, + visual = "mesh", + mesh = "extra_mobs_cod.b3d", + textures = { + {"extra_mobs_cod.png"} + }, + sounds = { + }, + animation = { + stand_start = 1, + stand_end = 20, + walk_start = 1, + walk_end = 20, + run_start = 1, + run_end = 20, + }, + drops = { + {name = "mcl_fishing:fish_raw", + chance = 1, + min = 1, + max = 1,}, + {name = "mcl_bone_meal:bone_meal", + chance = 20, + min = 1, + max = 1,}, + }, + visual_size = {x=3, y=3}, + makes_footstep_sound = false, + fly = true, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, + breathes_in_water = true, + jump = false, + view_range = 16, + runaway = true, + fear_height = 4, + do_custom = function(self) + --[[ this is supposed to make them jump out the water but doesn't appear to work very well + self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0)) + if minetest.get_item_group(self.standing_in, "water") ~= 0 then + if self.object:get_velocity().y < 5 then + self.object:add_velocity({ x = 0 , y = math.random(-.007, .007), z = 0 }) + end + end +--]] + for _,object in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 10)) do + local lp = object:get_pos() + local s = self.object:get_pos() + local vec = { + x = lp.x - s.x, + y = lp.y - s.y, + z = lp.z - s.z + } + if object and not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mobs_mc:cod" then + self.state = "runaway" + self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0}) + end + end + end, + on_rightclick = function(self, clicker) + local bn = clicker:get_wielded_item():get_name() + if bn == "mcl_buckets:bucket_water" or bn == "mcl_buckets:bucket_river_water" then + self.object:remove() + clicker:set_wielded_item("mcl_buckets:bucket_cod") + awards.unlock(clicker:get_player_name(), "mcl:tacticalFishing") + end + end +} + +mcl_mobs.register_mob("mobs_mc:cod", cod) + + +--spawning TODO: in schools + +local water = 0 + +mcl_mobs:spawn_specific( +"mobs_mc:cod", +"overworld", +"water", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +--spawn egg +mcl_mobs.register_egg("mobs_mc:cod", S("Cod"), "#c1a76a", "#e5c48b", 0) diff --git a/mods/ENTITIES/mobs_mc/common.lua b/mods/ENTITIES/mobs_mc/common.lua deleted file mode 100644 index e69de29bb..000000000 diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index b2d6158bc..9de5d1cce 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -6,18 +6,26 @@ local cow_def = { description = S("Cow"), type = "animal", spawn_class = "passive", + passive = true, hp_min = 10, hp_max = 10, xp_min = 1, xp_max = 3, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45}, + spawn_in_group = 4, + spawn_in_group_min = 3, visual = "mesh", mesh = "mobs_mc_cow.b3d", textures = { { "mobs_mc_cow.png", "blank.png", }, }, - visual_size = {x=2.8, y=2.8}, + head_swivel = "head.control", + bone_eye_height = 10, + head_eye_height = 1.1, + horrizonatal_head_height=-1.8, + curiosity = 2, + head_yaw="z", makes_footstep_sound = true, walk_velocity = 1, drops = { @@ -41,14 +49,17 @@ local cow_def = { distance = 16, }, animation = { - stand_speed = 25, walk_speed = 40, - run_speed = 60, stand_start = 0, - stand_end = 0, walk_start = 0, - walk_end = 40, run_start = 0, - run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 30, + run_start = 0, run_end = 40, run_speed = 40, + }, + child_animations = { + stand_start = 41, stand_end = 41, + walk_start = 41, walk_end = 81, walk_speed = 45, + run_start = 41, run_end = 81, run_speed = 60, }, on_rightclick = function(self, clicker) - if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end + if self:feed_tame(clicker, 1, true, false) then return end if mcl_mobs:protect(self, clicker) then return end if self.child then @@ -77,15 +88,16 @@ local cow_def = { fear_height = 4, } -mcl_mobs:register_mob("mobs_mc:cow", cow_def) +mcl_mobs.register_mob("mobs_mc:cow", cow_def) -- Mooshroom local mooshroom_def = table.copy(cow_def) mooshroom_def.description = S("Mooshroom") -mooshroom_def.mesh = "mobs_mc_cow.b3d" +mooshroom_def.spawn_in_group_min = 4 +mooshroom_def.spawn_in_group = 8 mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } } mooshroom_def.on_rightclick = function(self, clicker) - if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end + if self:feed_tame(clicker, 1, true, false) then return end if mcl_mobs:protect(self, clicker) then return end if self.child then @@ -141,7 +153,17 @@ mooshroom_def.on_rightclick = function(self, clicker) end mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) end -mcl_mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) + +mooshroom_def.on_lightning_strike = function(self, pos, pos2, objects) + if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then + self.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" } + else + self.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } + end + self.object:set_properties({ textures = self.base_texture }) + return true +end +mcl_mobs.register_mob("mobs_mc:mooshroom", mooshroom_def) -- Spawning @@ -151,17 +173,12 @@ mcl_mobs:spawn_specific( "ground", { "flat", - "IcePlainsSpikes", - "ColdTaiga", - "ColdTaiga_beach", - "ColdTaiga_beach_water", "MegaTaiga", "MegaSpruceTaiga", "ExtremeHills", "ExtremeHills_beach", "ExtremeHillsM", "ExtremeHills+", - "ExtremeHills+_snowtop", "StoneBeach", "Plains", "Plains_beach", @@ -214,5 +231,5 @@ mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn egg -mcl_mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0) -mcl_mobs:register_egg("mobs_mc:mooshroom", S("Mooshroom"), "mobs_mc_spawn_icon_mooshroom.png", 0) +mcl_mobs.register_egg("mobs_mc:cow", S("Cow"), "#443626", "#a1a1a1", 0) +mcl_mobs.register_egg("mobs_mc:mooshroom", S("Mooshroom"), "#a00f10", "#b7b7b7", 0) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 8d50c6755..6bbb37d5a 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -9,9 +9,10 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:creeper", { +mcl_mobs.register_mob("mobs_mc:creeper", { type = "monster", spawn_class = "hostile", + spawn_in_group = 1, hp_min = 20, hp_max = 20, xp_min = 5, @@ -20,6 +21,9 @@ mcl_mobs:register_mob("mobs_mc:creeper", { pathfinding = 1, visual = "mesh", mesh = "mobs_mc_creeper.b3d", + head_swivel = "Head_Control", + bone_eye_height = 2.35, + curiosity = 2, textures = { {"mobs_mc_creeper.png", "mobs_mc_empty.png"}, @@ -77,7 +81,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", { if self._forced_explosion_countdown_timer ~= nil then self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime if self._forced_explosion_countdown_timer <= 0 then - mcl_mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength) + self:boom(mcl_util.get_object_center(self.object), self.explosion_strength) end end end, @@ -129,7 +133,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", { view_range = 16, }) -mcl_mobs:register_mob("mobs_mc:creeper_charged", { +mcl_mobs.register_mob("mobs_mc:creeper_charged", { description = S("Creeper"), type = "monster", spawn_class = "hostile", @@ -199,7 +203,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", { if self._forced_explosion_countdown_timer ~= nil then self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime if self._forced_explosion_countdown_timer <= 0 then - mcl_mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength) + self:boom(mcl_util.get_object_center(self.object), self.explosion_strength) end end end, @@ -215,6 +219,10 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", { end end end, + on_lightning_strike = function(self, pos, pos2, objects) + mcl_util.replace_mob(self.object, "mobs_mc:creeper_charged") + return true + end, maxdrops = 2, drops = { {name = "mcl_mobitems:gunpowder", @@ -274,7 +282,6 @@ mcl_mobs:spawn_specific( "Plains", "Desert", "ColdTaiga", -"MushroomIsland", "IcePlainsSpikes", "SunflowerPlains", "IcePlains", @@ -301,7 +308,6 @@ mcl_mobs:spawn_specific( "ExtremeHills_beach", "ColdTaiga_beach", "Swampland_shore", -"MushroomIslandShore", "JungleM_shore", "Jungle_shore", "MesaPlateauFM_sandlevel", @@ -340,7 +346,6 @@ mcl_mobs:spawn_specific( "Forest_deep_ocean", "JungleM_deep_ocean", "FlowerForest_deep_ocean", -"MushroomIsland_ocean", "MegaTaiga_ocean", "StoneBeach_deep_ocean", "IcePlainsSpikes_deep_ocean", @@ -350,7 +355,6 @@ mcl_mobs:spawn_specific( "MesaBryce_deep_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills_ocean", -"MushroomIsland_deep_ocean", "Forest_ocean", "MegaTaiga_deep_ocean", "JungleEdge_ocean", @@ -376,7 +380,6 @@ mcl_mobs:spawn_specific( "RoofedForest_underground", "Jungle_underground", "Swampland_underground", -"MushroomIsland_underground", "BirchForest_underground", "Plains_underground", "MesaPlateauF_underground", @@ -408,4 +411,4 @@ mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0) +mcl_mobs.register_egg("mobs_mc:creeper", S("Creeper"), "#0da70a", "#000000", 0) diff --git a/mods/ENTITIES/mobs_mc/depends.txt b/mods/ENTITIES/mobs_mc/depends.txt deleted file mode 100644 index 674eb8094..000000000 --- a/mods/ENTITIES/mobs_mc/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_mobs \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/dolphin.lua b/mods/ENTITIES/mobs_mc/dolphin.lua new file mode 100644 index 000000000..0e5c8e7ee --- /dev/null +++ b/mods/ENTITIES/mobs_mc/dolphin.lua @@ -0,0 +1,253 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local pi = math.pi +local atann = math.atan +local atan = function(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + +local dir_to_pitch = function(dir) + local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +local function degrees(rad) + return rad * 180.0 / math.pi +end + +local S = minetest.get_translator(minetest.get_current_modname()) + +--################### +--################### dolphin +--################### + +local dolphin = { + type = "animal", + spawn_class = "water", + can_despawn = true, + passive = true, + hp_min = 10, + hp_max = 10, + xp_min = 1, + xp_max = 3, + armor = 100, + walk_chance = 100, + breath_max = 120, + rotate = 180, + spawn_in_group_min = 3, + spawn_in_group = 5, + tilt_swim = true, + collisionbox = {-0.3, 0.0, -0.3, 0.3, 0.79, 0.3}, + visual = "mesh", + mesh = "extra_mobs_dolphin.b3d", + textures = { + {"extra_mobs_dolphin.png"} + }, + sounds = { + }, + animation = { + stand_start = 20, + stand_end = 20, + walk_start = 0, + walk_end = 15, + run_start = 30, + run_end = 45, + }, + drops = { + {name = "mcl_fishing:fish_raw", + chance = 1, + min = 0, + max = 1,}, + }, + visual_size = {x=3, y=3}, + makes_footstep_sound = false, + fly = true, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, + breathes_in_water = true, + jump = false, + view_range = 16, + fear_height = 4, + walk_velocity = 3, + run_velocity = 6, + reach = 2, + damage = 2.5, + attack_type = "dogfight", + do_custom = function(self,dtime) + --[[ this is supposed to make them jump out the water but doesn't appear to work very well + self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0)) + if minetest.get_item_group(self.standing_in, "water") ~= 0 then + if self.object:get_velocity().y < 5 then + self.object:add_velocity({ x = 0 , y = math.random(-.007, .007), z = 0 }) + end + end + --]] + end, +} + +mcl_mobs.register_mob("mobs_mc:dolphin", dolphin) + + +--spawning TO DO: in schools +local water = 0 +mcl_mobs:spawn_specific( +"mobs_mc:dolphin", +"overworld", +"water", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +--spawn egg +mcl_mobs.register_egg("mobs_mc:dolphin", S("Dolphin"), "#223b4d", "#f9f9f9", 0) diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index d2f971f79..ef4c8f811 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -4,7 +4,51 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:enderdragon", { +local BEAM_CHECK_FREQUENCY = 2 +local POS_CHECK_FREQUENCY = 15 +local HEAL_AMMOUNT = 37 + +local function heal(self) + local o = self.object + self.health = math.min(self.hp_max,self.health + HEAL_AMMOUNT) +end +local function check_beam(self) + for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do + local luaentity = obj:get_luaentity() + if luaentity and luaentity.name == "mcl_end:crystal" then + if luaentity.beam then + if luaentity.beam == self.beam then + heal(self) + break + end + else + if self.beam then + self.beam:remove() + end + minetest.add_entity(self.object:get_pos(), "mcl_end:crystal_beam"):get_luaentity():init(self.object, obj) + break + end + end + end +end + +local function check_pos(self) + if self._portal_pos then + -- migrate old format + if type(self._portal_pos) == "string" then + self._portal_pos = minetest.string_to_pos(self._portal_pos) + end + local portal_center = vector.add(self._portal_pos, vector.new(0, 11, 0)) + local pos = self.object:get_pos() + if vector.distance(pos, portal_center) > 50 then + self.object:set_pos(self._last_good_pos or portal_center) + else + self._last_good_pos = pos + end + end +end + +mcl_mobs.register_mob("mobs_mc:enderdragon", { description = S("Ender Dragon"), type = "monster", spawn_class = "hostile", @@ -23,7 +67,7 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", { {"mobs_mc_dragon.png"}, }, visual_size = {x=3, y=3}, - view_range = 35, + view_range = 64, walk_velocity = 6, run_velocity = 6, can_despawn = false, @@ -35,6 +79,7 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", { }, physical = true, damage = 10, + knock_back = false, jump = true, jump_height = 14, fly = true, @@ -60,45 +105,33 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", { run_start = 0, run_end = 20, }, ignores_nametag = true, - do_custom = function(self) + do_custom = function(self,dtime) mcl_bossbars.update_boss(self.object, "Ender Dragon", "light_purple") - for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do - local luaentity = obj:get_luaentity() - if luaentity and luaentity.name == "mcl_end:crystal" then - if luaentity.beam then - if luaentity.beam == self.beam then - break - end - else - if self.beam then - self.beam:remove() - end - minetest.add_entity(self.object:get_pos(), "mcl_end:crystal_beam"):get_luaentity():init(self.object, obj) - break - end - end + if self._pos_timer == nil or self._pos_timer > POS_CHECK_FREQUENCY then + self._pos_timer = 0 + check_pos(self) end - if self._portal_pos then - -- migrate old format - if type(self._portal_pos) == "string" then - self._portal_pos = minetest.string_to_pos(self._portal_pos) - end - local portal_center = vector.add(self._portal_pos, vector.new(3, 11, 3)) - local pos = self.object:get_pos() - if vector.distance(pos, portal_center) > 50 then - self.object:set_pos(self._last_good_pos or portal_center) - else - self._last_good_pos = pos - end + if self._beam_timer == nil or self._beam_timer > BEAM_CHECK_FREQUENCY then + self._beam_timer = 0 + check_beam(self) end + self._beam_timer = self._beam_timer + dtime + self._pos_timer = self._pos_timer + dtime end, - on_die = function(self, pos) + on_die = function(self, pos, cmi_cause) if self._portal_pos then mcl_portals.spawn_gateway_portal() - mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open") + mcl_structures.place_structure(self._portal_pos,mcl_structures.registered_structures["end_exit_portal_open"],PseudoRandom(minetest.get_mapgen_setting("seed")),-1) if self._initial then mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000 - minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = "mcl_end:dragon_egg"}) + minetest.set_node(vector.add(self._portal_pos, vector.new(0, 5, 0)), {name = "mcl_end:dragon_egg"}) + end + end + + -- Free The End Advancement + for _,players in pairs(minetest.get_objects_inside_radius(pos,64)) do + if players:is_player() then + awards.unlock(players:get_player_name(), "mcl:freeTheEnd") end end end, @@ -109,7 +142,7 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", { local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false -- dragon fireball (projectile) -mcl_mobs:register_arrow("mobs_mc:dragon_fireball", { +mcl_mobs.register_arrow("mobs_mc:dragon_fireball", { visual = "sprite", visual_size = {x = 1.25, y = 1.25}, textures = {"mobs_mc_dragon_fireball.png"}, @@ -133,10 +166,11 @@ mcl_mobs:register_arrow("mobs_mc:dragon_fireball", { -- node hit, explode hit_node = function(self, pos, node) - mcl_mobs:boom(self, pos, 2) + mcl_mobs.mob_class.boom(self,pos, 2) end }) -mcl_mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true) +mcl_mobs.register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "#252525", "#b313c9", 0, true) + mcl_wip.register_wip_item("mobs_mc:enderdragon") diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 9ed59bb1f..2688977fe 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -24,7 +24,25 @@ -- added rain damage. -- fixed the grass_with_dirt issue. +minetest.register_entity("mobs_mc:ender_eyes", { + visual = "mesh", + mesh = "mobs_mc_spider.b3d", + visual_size = {x=1.01/3, y=1.01/3}, + textures = { + "mobs_mc_enderman_eyes.png", + }, + on_step = function(self) + if self and self.object then + if not self.object:get_attach() then + self.object:remove() + end + end + end, + glow = 50, +}) + local S = minetest.get_translator("mobs_mc") +local enable_damage = minetest.settings:get_bool("enable_damage") local telesound = function(pos, is_source) local snd @@ -219,8 +237,25 @@ local select_enderman_animation = function(animation_type) end local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false +local psdefs = {{ + amount = 5, + minpos = vector.new(-0.6,0,-0.6), + maxpos = vector.new(0.6,3,0.6), + minvel = vector.new(-0.25,-0.25,-0.25), + maxvel = vector.new(0.25,0.25,0.25), + minacc = vector.new(-0.5,-0.5,-0.5), + maxacc = vector.new(0.5,0.5,0.5), + minexptime = 0.2, + maxexptime = 3, + minsize = 0.2, + maxsize = 1.2, + collisiondetection = true, + vertical = false, + time = 0, + texture = "mcl_portals_particle"..math.random(1, 5)..".png", +}} -mcl_mobs:register_mob("mobs_mc:enderman", { +mcl_mobs.register_mob("mobs_mc:enderman", { description = S("Enderman"), type = "monster", spawn_class = "passive", @@ -236,6 +271,19 @@ mcl_mobs:register_mob("mobs_mc:enderman", { textures = create_enderman_textures(), visual_size = {x=3, y=3}, makes_footstep_sound = true, + on_spawn = function(self) + local spider_eyes=false + for n = 1, #self.object:get_children() do + local obj = self.object:get_children()[n] + if obj:get_luaentity() and self.object:get_luaentity().name == "mobs_mc:ender_eyes" then + spider_eyes = true + end + end + if not spider_eyes then + minetest.add_entity(self.object:get_pos(), "mobs_mc:ender_eyes"):set_attach(self.object, "head.top", vector.new(0,2.54,-1.99), vector.new(90,0,180)) + minetest.add_entity(self.object:get_pos(), "mobs_mc:ender_eyes"):set_attach(self.object, "head.top", vector.new(1,2.54,-1.99), vector.new(90,0,180)) + end + end, sounds = { -- TODO: Custom war cry sound war_cry = "mobs_sandmonster", @@ -248,6 +296,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", { run_velocity = 3.4, damage = 7, reach = 2, + particlespawners = psdefs, drops = { {name = "mcl_throwing:ender_pearl", chance = 1, @@ -257,23 +306,12 @@ mcl_mobs:register_mob("mobs_mc:enderman", { }, animation = select_enderman_animation("normal"), _taken_node = "", + can_spawn = function(pos) + return #minetest.find_nodes_in_area(vector.offset(pos,0,1,0),vector.offset(pos,0,3,0),{"air"}) > 2 + end, do_custom = function(self, dtime) - -- PARTICLE BEHAVIOUR HERE. - local enderpos = self.object:get_pos() - local chanceOfParticle = math.random(0, 1) - if chanceOfParticle == 1 then - minetest.add_particle({ - pos = {x=enderpos.x+math.random(-1,1)*math.random()/2,y=enderpos.y+math.random(0,3),z=enderpos.z+math.random(-1,1)*math.random()/2}, - velocity = {x=math.random(-.25,.25), y=math.random(-.25,.25), z=math.random(-.25,.25)}, - acceleration = {x=math.random(-.5,.5), y=math.random(-.5,.5), z=math.random(-.5,.5)}, - expirationtime = math.random(), - size = math.random(), - collisiondetection = true, - vertical = false, - texture = "mcl_portals_particle"..math.random(1, 5)..".png", - }) - end -- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE. + local enderpos = self.object:get_pos() local dim = mcl_worlds.pos_to_dimension(enderpos) if dim == "overworld" then if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then @@ -309,24 +347,25 @@ mcl_mobs:register_mob("mobs_mc:enderman", { else return end -- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE. if self.state == "attack" then - --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then - --self:teleport(nil) - --self.state = "" - --else - if self.attack then - local target = self.attack - local pos = target:get_pos() - if pos ~= nil then - if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then - self:teleport(target) - end + if self.attack then + local target = self.attack + local pos = target:get_pos() + if pos ~= nil then + if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then + self:teleport(target) end end - --end + end + else --if not attacking try to tp to the dark + local light = minetest.get_node_light(enderpos) + if light and light > minetest.LIGHT_MAX then + self:teleport(nil) + end end -- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE. -- Check for arrows and people nearby. - local enderpos = self.object:get_pos() + + enderpos = self.object:get_pos() enderpos.y = enderpos.y + 1.5 local objs = minetest.get_objects_inside_radius(enderpos, 2) for n = 1, #objs do @@ -355,7 +394,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", { -- self:teleport(nil) -- self.state = "" --else - if self.attack ~= nil and not minetest.settings:get_bool("creative_mode") then + if self.attack ~= nil and enable_damage then self.state = 'attack' end --end @@ -458,7 +497,7 @@ mcl_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") - mcl_mobs:set_animation(self, self.animation.current) + self:set_animation(self.animation.current) if def.sounds and def.sounds.dug then minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}, true) end @@ -481,7 +520,7 @@ mcl_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") - mcl_mobs:set_animation(self, self.animation.current) + self:set_animation(self.animation.current) if def.sounds and def.sounds.place then minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}, true) end @@ -590,14 +629,18 @@ mcl_mobs:register_mob("mobs_mc:enderman", { attack_type = "dogfight", }) - -- End spawn mcl_mobs:spawn_specific( "mobs_mc:enderman", "end", "ground", { -"End" +"End", +"EndIsland", +"EndMidlands", +"EndBarrens", +"EndBorder", +"EndSmallIslands" }, 0, minetest.LIGHT_MAX+1, @@ -627,7 +670,6 @@ mcl_mobs:spawn_specific( "Plains", "Desert", "ColdTaiga", -"MushroomIsland", "IcePlainsSpikes", "SunflowerPlains", "IcePlains", @@ -654,7 +696,6 @@ mcl_mobs:spawn_specific( "ExtremeHills_beach", "ColdTaiga_beach", "Swampland_shore", -"MushroomIslandShore", "JungleM_shore", "Jungle_shore", "MesaPlateauFM_sandlevel", @@ -693,7 +734,6 @@ mcl_mobs:spawn_specific( "Forest_deep_ocean", "JungleM_deep_ocean", "FlowerForest_deep_ocean", -"MushroomIsland_ocean", "MegaTaiga_ocean", "StoneBeach_deep_ocean", "IcePlainsSpikes_deep_ocean", @@ -703,7 +743,6 @@ mcl_mobs:spawn_specific( "MesaBryce_deep_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills_ocean", -"MushroomIsland_deep_ocean", "Forest_ocean", "MegaTaiga_deep_ocean", "JungleEdge_ocean", @@ -729,7 +768,6 @@ mcl_mobs:spawn_specific( "RoofedForest_underground", "Jungle_underground", "Swampland_underground", -"MushroomIsland_underground", "BirchForest_underground", "Plains_underground", "MesaPlateauF_underground", @@ -766,15 +804,32 @@ mcl_mobs:spawn_specific( "nether", "ground", { -"Nether" +"Nether", +"SoulsandValley", }, 0, -7, +11, 30, 27500, 4, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) +-- Warped Forest spawn (common) +mcl_mobs:spawn_specific( +"mobs_mc:enderman", +"nether", +"ground", +{ +"WarpedForest" +}, +0, +11, +30, +5000, +4, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) + -- spawn eggs -mcl_mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0) +mcl_mobs.register_egg("mobs_mc:enderman", S("Enderman"), "#252525", "#151515", 0) diff --git a/mods/ENTITIES/mobs_mc/endermite.lua b/mods/ENTITIES/mobs_mc/endermite.lua index 53200da70..612054be8 100644 --- a/mods/ENTITIES/mobs_mc/endermite.lua +++ b/mods/ENTITIES/mobs_mc/endermite.lua @@ -4,7 +4,7 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:endermite", { +mcl_mobs.register_mob("mobs_mc:endermite", { description = S("Endermite"), type = "monster", spawn_class = "hostile", @@ -38,4 +38,4 @@ mcl_mobs:register_mob("mobs_mc:endermite", { reach = 1, }) -mcl_mobs:register_egg("mobs_mc:endermite", S("Endermite"), "mobs_mc_spawn_icon_endermite.png", 0) +mcl_mobs.register_egg("mobs_mc:endermite", S("Endermite"), "#161616", "#6d6d6d", 0) diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index fd77b9ed8..0f7e73344 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -10,7 +10,7 @@ local S = minetest.get_translator("mobs_mc") --################### -mcl_mobs:register_mob("mobs_mc:ghast", { +mcl_mobs.register_mob("mobs_mc:ghast", { description = S("Ghast"), type = "monster", spawn_class = "hostile", @@ -23,6 +23,7 @@ mcl_mobs:register_mob("mobs_mc:ghast", { collisionbox = {-2, 5, -2, 2, 9, 2}, visual = "mesh", mesh = "mobs_mc_ghast.b3d", + spawn_in_group = 1, textures = { {"mobs_mc_ghast.png"}, }, @@ -64,6 +65,14 @@ mcl_mobs:register_mob("mobs_mc:ghast", { makes_footstep_sound = false, instant_death = true, fire_resistant = true, + can_spawn = function(pos) + if not minetest.get_item_group(minetest.get_node(pos).name,"solid") then return false end + local p1=vector.offset(pos,-2,1,-2) + local p2=vector.offset(pos,2,5,2) + local nn = minetest.find_nodes_in_area(p1,p2,{"air"}) + if #nn< 41 then return false end + return true + end, do_custom = function(self) if self.firing == true then self.base_texture = {"mobs_mc_ghast_firing.png"} @@ -81,18 +90,20 @@ mcl_mobs:spawn_specific( "nether", "ground", { -"Nether" +"Nether", +"SoulsandValley", +"BasaltDelta", }, 0, -minetest.LIGHT_MAX+1, +7, 30, -18000, +72000, 2, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) -- fireball (projectile) -mcl_mobs:register_arrow("mobs_mc:fireball", { +mcl_mobs.register_arrow("mobs_mc:fireball", { visual = "sprite", visual_size = {x = 1, y = 1}, textures = {"mcl_fire_fire_charge.png"}, @@ -105,7 +116,12 @@ mcl_mobs:register_arrow("mobs_mc:fireball", { full_punch_interval = 1.0, damage_groups = {fleshy = 6}, }, nil) - mcl_mobs:boom(self, self.object:get_pos(), 1, true) + local p = self.object:get_pos() + if p then + mcl_mobs.mob_class.boom(self,p, 1, true) + else + mcl_mobs.mob_class.boom(self,player:get_pos(), 1, true) + end end, hit_mob = function(self, mob) @@ -113,11 +129,11 @@ mcl_mobs:register_arrow("mobs_mc:fireball", { full_punch_interval = 1.0, damage_groups = {fleshy = 6}, }, nil) - mcl_mobs:boom(self, self.object:get_pos(), 1, true) + mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1, true) end, hit_node = function(self, pos, node) - mcl_mobs:boom(self, pos, 1, true) + mcl_mobs.mob_class.boom(self,pos, 1, true) end }) @@ -125,4 +141,4 @@ mcl_mobs:register_arrow("mobs_mc:fireball", { -- spawn eggs -mcl_mobs:register_egg("mobs_mc:ghast", S("Ghast"), "mobs_mc_spawn_icon_ghast.png", 0) +mcl_mobs.register_egg("mobs_mc:ghast", S("Ghast"), "#f9f9f9", "#bcbcbc", 0) diff --git a/mods/ENTITIES/mobs_mc/glow_squid.lua b/mods/ENTITIES/mobs_mc/glow_squid.lua new file mode 100644 index 000000000..9f3a45e34 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/glow_squid.lua @@ -0,0 +1,246 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local S = minetest.get_translator("mobs_mc") + +local base_psdef = { + amount = 8, + time=0, + minpos = vector.new(-1,-1,-1), + maxpos = vector.new(1,1,1), + minvel = vector.new(-0.25,-0.25,-0.25), + maxvel = vector.new(0.25,0.25,0.25), + minacc = vector.new(-0.5,-0.5,-0.5), + maxacc = vector.new(0.5,0.5,0.5), + minexptime = 1, + maxexptime = 2, + minsize = 0.8, + maxsize= 1.5, + glow = 5, + collisiondetection = true, + collision_removal = true, +} +local psdefs = {} +for i=1,4 do + local p = table.copy(base_psdef) + p.texture = "extra_mobs_glow_squid_glint"..i..".png" + table.insert(psdefs,p) +end + +mcl_mobs.register_mob("mobs_mc:glow_squid", { + type = "animal", + spawn_class = "water", + can_despawn = true, + passive = true, + hp_min = 10, + hp_max = 10, + xp_min = 1, + xp_max = 3, + armor = 100, + rotate = 0, + -- tilt_swim breaks the animations. + --tilt_swim = true, + -- FIXME: If the qlow squid is near the floor, it turns black + collisionbox = { -0.4, 0.0, -0.4, 0.4, 0.9, 0.4 }, + visual = "mesh", + mesh = "extra_mobs_glow_squid.b3d", + textures = { + { "extra_mobs_glow_squid.png" } + }, + sounds = { + damage = { name = "mobs_mc_squid_hurt", gain = 0.3 }, + death = { name = "mobs_mc_squid_death", gain = 0.4 }, + flop = "mobs_mc_squid_flop", + distance = 16, + }, + animation = { + stand_start = 1, + stand_end = 60, + walk_start = 1, + walk_end = 60, + run_start = 1, + run_end = 60, + }, + drops = { + { name = "mcl_mobitems:glow_ink_sac", + chance = 1, + min = 1, + max = 3, + looting = "common", }, + }, + visual_size = { x = 3, y = 3 }, + makes_footstep_sound = false, + swim = true, + breathes_in_water = true, + jump = false, + view_range = 16, + runaway = true, + fear_height = 4, + fly = true, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, + -- don't add "mcl_core:water_flowing", or it won't move vertically. + + glow = minetest.LIGHT_MAX, + particlespawners = psdefs, +}) + +-- spawning +local water = mobs_mc.water_level - 1 +-- local water = mobs_mc.spawn_height.water + 1 +mcl_mobs:spawn_specific( + "mobs_mc:glow_squid", + "overworld", + "water", + { + "Mesa", + "FlowerForest", + "Swampland", + "Taiga", + "ExtremeHills", + "Jungle", + "Savanna", + "BirchForest", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "Forest", + "Plains", + "Desert", + "ColdTaiga", + "MushroomIsland", + "IcePlainsSpikes", + "SunflowerPlains", + "IcePlains", + "RoofedForest", + "ExtremeHills+_snowtop", + "MesaPlateauFM_grasstop", + "JungleEdgeM", + "ExtremeHillsM", + "JungleM", + "BirchForestM", + "MesaPlateauF", + "MesaPlateauFM", + "MesaPlateauF_grasstop", + "MesaBryce", + "JungleEdge", + "SavannaM", + "FlowerForest_beach", + "Forest_beach", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "Savanna_beach", + "Plains_beach", + "ExtremeHills_beach", + "ColdTaiga_beach", + "Swampland_shore", + "MushroomIslandShore", + "JungleM_shore", + "Jungle_shore", + "MesaPlateauFM_sandlevel", + "MesaPlateauF_sandlevel", + "MesaBryce_sandlevel", + "Mesa_sandlevel", + "RoofedForest_ocean", + "JungleEdgeM_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "ExtremeHillsM_deep_ocean", + "Savanna_deep_ocean", + "SunflowerPlains_ocean", + "Swampland_deep_ocean", + "Swampland_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "JungleEdgeM_deep_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "Mesa_ocean", + "StoneBeach_ocean", + "Plains_deep_ocean", + "JungleEdge_deep_ocean", + "SavannaM_deep_ocean", + "Desert_deep_ocean", + "Mesa_deep_ocean", + "ColdTaiga_deep_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "Forest_deep_ocean", + "JungleM_deep_ocean", + "FlowerForest_deep_ocean", + "MushroomIsland_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "SavannaM_ocean", + "MesaPlateauF_deep_ocean", + "MesaBryce_deep_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "MushroomIsland_deep_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "Jungle_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "MesaPlateauFM_deep_ocean", + "Desert_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", + "JungleM_ocean", + "FlowerForest_underground", + "JungleEdge_underground", + "StoneBeach_underground", + "MesaBryce_underground", + "Mesa_underground", + "RoofedForest_underground", + "Jungle_underground", + "Swampland_underground", + "MushroomIsland_underground", + "BirchForest_underground", + "Plains_underground", + "MesaPlateauF_underground", + "ExtremeHills_underground", + "MegaSpruceTaiga_underground", + "BirchForestM_underground", + "SavannaM_underground", + "MesaPlateauFM_underground", + "Desert_underground", + "Savanna_underground", + "Forest_underground", + "SunflowerPlains_underground", + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "ExtremeHills+_underground", + "JungleM_underground", + "ExtremeHillsM_underground", + "JungleEdgeM_underground", + }, + 0, + minetest.LIGHT_MAX + 1, + 30, + 10000, + 3, + water - 16, + water) + +-- spawn egg +mcl_mobs.register_egg("mobs_mc:glow_squid", S("Glow Squid"), "#095757", "#87f6c0", 0) diff --git a/mods/ENTITIES/mobs_mc/guardian.lua b/mods/ENTITIES/mobs_mc/guardian.lua index 53e93f472..e9a15264b 100644 --- a/mods/ENTITIES/mobs_mc/guardian.lua +++ b/mods/ENTITIES/mobs_mc/guardian.lua @@ -4,16 +4,18 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:guardian", { +mcl_mobs.register_mob("mobs_mc:guardian", { description = S("Guardian"), type = "monster", spawn_class = "hostile", + spawn_in_group_min = 2, + spawn_in_group = 4, hp_min = 30, hp_max = 30, xp_min = 10, xp_max = 10, breath_max = -1, - passive = false, + passive = false, attack_type = "dogfight", pathfinding = 1, view_range = 16, @@ -102,4 +104,4 @@ mcl_mobs:register_mob("mobs_mc:guardian", { --mcl_mobs:spawn_specific("mobs_mc:guardian", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level - 10) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:guardian", S("Guardian"), "mobs_mc_spawn_icon_guardian.png", 0) +mcl_mobs.register_egg("mobs_mc:guardian", S("Guardian"), "#5a8272", "#f17d31", 0) diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua index f33576fb9..d08cc1846 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -6,7 +6,7 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:guardian_elder", { +mcl_mobs.register_mob("mobs_mc:guardian_elder", { description = S("Elder Guardian"), type = "monster", spawn_class = "hostile", @@ -112,5 +112,6 @@ mcl_mobs:register_mob("mobs_mc:guardian_elder", { -- mcl_mobs:spawn_specific("mobs_mc:guardian_elder", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-18) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "mobs_mc_spawn_icon_guardian_elder.png", 0) +mcl_mobs.register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "#ceccba", "#747693", 0) + diff --git a/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua b/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua new file mode 100644 index 000000000..e5cdcc8a8 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua @@ -0,0 +1,135 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local S = minetest.get_translator("mobs_mc") + +--################### +--################### hoglin +--################### + +local hoglin = { + type = "monster", + passive = false, + spawn_class = "hostile", + hp_min = 40, + hp_max = 40, + xp_min = 9, + xp_max = 9, + armor = {fleshy = 90}, + attack_type = "dogfight", + damage = 4, + reach = 3, + collisionbox = {-.6, -0.01, -.6, .6, 1.4, .6}, + visual = "mesh", + mesh = "extra_mobs_hoglin.b3d", + textures = { { + "extra_mobs_hoglin.png", + } }, + visual_size = {x=3, y=3}, + sounds = { + random = "extra_mobs_hoglin", + damage = "extra_mobs_hoglin_hurt", + distance = 16, + }, + jump = true, + makes_footstep_sound = true, + walk_velocity = 1, + run_velocity = 4, + drops = { + {name = "mobs_mcitems:leather", + chance = 1, + min = 0, + max = 1,}, + }, + drops = { + {name = "mcl_mobitems:porkchop", + chance = 1, + min = 2, + max = 4,}, + }, + animation = { + stand_speed = 7, + walk_speed = 7, + run_speed = 15, + stand_start = 24, + stand_end = 24, + walk_start = 11, + walk_end = 21, + run_start = 1, + run_end = 10, + punch_start = 22, + punch_end = 32, + }, + fear_height = 4, + view_range = 32, + floats = 0, + custom_attack = function(self) + if self.state == "attack" and self.reach > vector.distance(self.object:get_pos(), self.attack:get_pos()) then + self.attack:add_velocity({x=0,y=13,z=0}) + self.attack:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = self.damage} + }, nil) + end + end, + do_custom = function(self) + if self.object:get_pos().y > -100 then + local zog = minetest.add_entity(self.object:get_pos(), "mobs_mc:zoglin") + zog:set_rotation(self.object:get_rotation()) + self.object:remove() + end + end, + attack_animals = true, +} + +mcl_mobs.register_mob("mobs_mc:hoglin", hoglin) + +local zoglin = table.copy(hoglin) +zoglin.fire_resistant = 1 +zoglin.textures = {"extra_mobs_zoglin.png"} +zoglin.do_custom = function() + return +end +zoglin.attacks_monsters = true +zoglin.lava_damage = 0 +zoglin.fire_damage = 0 +mcl_mobs.register_mob("mobs_mc:zoglin", zoglin) + +-- Baby hoglin. + +local baby_hoglin = table.copy(hoglin) +baby_hoglin.collisionbox = {-.3, -0.01, -.3, .3, 0.94, .3} +baby_hoglin.xp_min = 20 +baby_hoglin.xp_max = 20 +baby_hoglin.visual_size = {x=hoglin.visual_size.x/2, y=hoglin.visual_size.y/2} +textures = { { + "extra_mobs_hoglin.png", + "extra_mobs_trans.png", +} } +baby_hoglin.walk_velocity = 1.2 +baby_hoglin.run_velocity = 2.4 +baby_hoglin.child = 1 + +mcl_mobs.register_mob("mobs_mc:baby_hoglin", baby_hoglin) + +-- Regular spawning in the Nether +mcl_mobs:spawn_specific( +"mobs_mc:hoglin", +"nether", +"ground", +{ +"Nether", +"CrimsonForest" +}, +0, +minetest.LIGHT_MAX+1, +30, +6000, +3, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) + +-- spawn eggs +mcl_mobs.register_egg("mobs_mc:hoglin", S("Hoglin"), "#85682e", "#2b2140", 0) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 53951b460..7f61627bc 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -34,6 +34,30 @@ local horse_extra_texture = function(horse) return textures end + +local function get_drops(self) + self.drops = {} + table.insert(self.drops, + {name = "mcl_mobitems:leather", + chance = 1, + min = 0, + max = 2, + looting = "common", + }) + if self._saddle then + table.insert(self.drops,{name = "mcl_mobitems:saddle", + chance = 1, + min = 1, + max = 1,}) + end + if self._chest then + table.insert(self.drops,{name = "mcl_chests:chest", + chance = 1, + min = 1, + max = 1,}) + end +end + -- Helper functions to determine equipment rules local can_equip_horse_armor = function(entity_id) return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse" @@ -81,11 +105,27 @@ for b=1, #horse_base do end end +-- in e7898352d890c2414af653eba624939df9c0b8b4 (0.76-dev) all items from mobs_mc were moved to mcl_mobitems +-- this results in existing horses wearing armor would still have the old texture filename in their +-- properties this function updates them. It should be removed some time in the future when we can be +-- reasonably sure all horses that want it get the new nexture. +local function update_textures(self) + local old = "mobs_mc_horse_armor_" + local txt = self.object:get_properties().textures + if txt[2]:find(old) then + txt[2] = txt[2]:gsub(old,"mcl_mobitems_horse_armor_") + self.object:set_properties({textures=txt}) + return + end +end + -- Horse local horse = { description = S("Horse"), type = "animal", spawn_class = "passive", + spawn_in_group_min = 2, + spawn_in_group = 6, visual = "mesh", mesh = "mobs_mc_horse.b3d", visual_size = {x=3.0, y=3.0}, @@ -138,9 +178,15 @@ local horse = { max = 2, looting = "common",}, }, - + on_spawn = update_textures, do_custom = function(self, dtime) + if not self._horse_speed then + self._horse_speed = math.random(486, 1457)/100 + elseif self.run_velocity ~= self._horse_speed then + self.run_velocity = self._horse_speed + end + -- set needed values if not already present if not self._regentimer then self._regentimer = 0 @@ -221,6 +267,27 @@ local horse = { local iname = item:get_name() local heal = 0 + if self._inv_id then + if not self._chest and item:get_name() == "mcl_chests:chest" then + item:take_item() + clicker:set_wielded_item(item) + self._chest = true + -- Update texture + if not self._naked_texture then + -- Base horse texture without chest or saddle + self._naked_texture = self.base_texture[2] + end + local tex = horse_extra_texture(self) + self.base_texture = tex + self.object:set_properties({textures = self.base_texture}) + get_drops(self) + return + elseif self._chest and clicker:get_player_control().sneak then + mcl_entity_invs.show_inv_form(self,clicker) + return + end + end + -- Taming self.temper = self.temper or (math.random(1,100)) @@ -270,7 +337,7 @@ local horse = { elseif (iname == "mcl_farming:carrot_item_gold") then heal = 4 end - if heal > 0 and mcl_mobs:feed_tame(self, clicker, heal, true, false) then + if heal > 0 and self:feed_tame(clicker, heal, true, false) then return end end @@ -285,7 +352,7 @@ local horse = { elseif (iname == "mcl_farming:hay_block") then heal = 20 end - if heal > 0 and mcl_mobs:feed_tame(self, clicker, heal, false, false) then + if heal > 0 and self:feed_tame(clicker, heal, false, false) then return end @@ -324,6 +391,7 @@ local horse = { self.base_texture = tex self.object:set_properties({textures = self.base_texture}) minetest.sound_play({name = "mcl_armor_equip_leather"}, {gain=0.5, max_hear_distance=12, pos=self.object:get_pos()}, true) + get_drops(self) -- Put on horse armor if tamed elseif can_equip_horse_armor(self.name) and not self.driver and not self._horse_armor @@ -373,7 +441,7 @@ local horse = { on_breed = function(parent1, parent2) local pos = parent1.object:get_pos() - local child = mcl_mobs:spawn_child(pos, parent1.name) + local child = mcl_mobs.spawn_child(pos, parent1.name) if child then local ent_c = child:get_luaentity() local p = math.random(1, 2) @@ -422,7 +490,7 @@ local horse = { end, } -mcl_mobs:register_mob("mobs_mc:horse", horse) +mcl_mobs.register_mob("mobs_mc:horse", horse) -- Skeleton horse local skeleton_horse = table.copy(horse) @@ -445,7 +513,7 @@ skeleton_horse.sounds = { distance = 16, } skeleton_horse.harmed_by_heal = true -mcl_mobs:register_mob("mobs_mc:skeleton_horse", skeleton_horse) +mcl_mobs.register_mob("mobs_mc:skeleton_horse", skeleton_horse) -- Zombie horse local zombie_horse = table.copy(horse) @@ -469,13 +537,15 @@ zombie_horse.sounds = { distance = 16, } zombie_horse.harmed_by_heal = true -mcl_mobs:register_mob("mobs_mc:zombie_horse", zombie_horse) +mcl_mobs.register_mob("mobs_mc:zombie_horse", zombie_horse) -- Donkey local d = 0.86 -- donkey scale local donkey = table.copy(horse) donkey.description = S("Donkey") donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}} +donkey.spawn_in_group = 3 +donkey.spawn_in_group_min = 1 donkey.animation = { speed_normal = 25, stand_start = 0, stand_end = 0, @@ -500,8 +570,9 @@ donkey.collisionbox = { donkey.jump = true donkey.jump_height = 3.75 -- can clear 1 block height -mcl_mobs:register_mob("mobs_mc:donkey", donkey) +mcl_mobs.register_mob("mobs_mc:donkey", donkey) +mcl_entity_invs.register_inv("mobs_mc:donkey","Donkey",15,true) -- Mule local m = 0.94 local mule = table.copy(donkey) @@ -518,7 +589,8 @@ mule.collisionbox = { horse.collisionbox[5] * m, horse.collisionbox[6] * m, } -mcl_mobs:register_mob("mobs_mc:mule", mule) +mcl_mobs.register_mob("mobs_mc:mule", mule) +mcl_entity_invs.register_inv("mobs_mc:mule","Mule",15,true) --=========================== --Spawn Function @@ -528,41 +600,14 @@ mcl_mobs:spawn_specific( "ground", { "flat", - "IcePlainsSpikes", - "ColdTaiga", - "ColdTaiga_beach", - "ColdTaiga_beach_water", - "MegaTaiga", - "MegaSpruceTaiga", - "ExtremeHills", - "ExtremeHills_beach", - "ExtremeHillsM", - "ExtremeHills+", - "ExtremeHills+_snowtop", - "StoneBeach", "Plains", "Plains_beach", "SunflowerPlains", - "Taiga", - "Taiga_beach", - "Forest", - "Forest_beach", - "FlowerForest", - "FlowerForest_beach", - "BirchForest", - "BirchForestM", - "RoofedForest", "Savanna", "Savanna_beach", "SavannaM", - "Jungle", - "Jungle_shore", - "JungleM", - "JungleM_shore", - "JungleEdge", - "JungleEdgeM", - "Swampland", - "Swampland_shore" + "Savanna_beach", + "Plains_beach", }, 0, minetest.LIGHT_MAX+1, @@ -572,20 +617,22 @@ minetest.LIGHT_MAX+1, mobs_mc.water_level+3, mcl_vars.mg_overworld_max) - mcl_mobs:spawn_specific( "mobs_mc:donkey", "overworld", "ground", { -"Mesa", -"MesaPlateauFM_grasstop", -"MesaPlateauF", -"MesaPlateauFM", -"MesaPlateauF_grasstop", -"MesaBryce", + "flat", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Savanna", + "Savanna_beach", + "SavannaM", + "Savanna_beach", + "Plains_beach", }, -0, +9, minetest.LIGHT_MAX+1, 30, 15000, @@ -594,8 +641,8 @@ mobs_mc.water_level+3, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) -mcl_mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) ---mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) -mcl_mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0) -mcl_mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0) +mcl_mobs.register_egg("mobs_mc:horse", S("Horse"), "#c09e7d", "#eee500", 0) +mcl_mobs.register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "#68684f", "#e5e5d8", 0) +--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "#2a5a37", "#84d080", 0) +mcl_mobs.register_egg("mobs_mc:donkey", S("Donkey"), "#534539", "#867566", 0) +mcl_mobs.register_egg("mobs_mc:mule", S("Mule"), "#1b0200", "#51331d", 0) diff --git a/mods/ENTITIES/mobs_mc/init.lua b/mods/ENTITIES/mobs_mc/init.lua index 02f5023a5..c2b3d8ed0 100644 --- a/mods/ENTITIES/mobs_mc/init.lua +++ b/mods/ENTITIES/mobs_mc/init.lua @@ -96,6 +96,7 @@ mobs_mc.water_level = tonumber(minetest.settings:get("water_level")) or 0 -- Animals local path = minetest.get_modpath("mobs_mc") +dofile(path .. "/axolotl.lua") -- Mesh and animation by JoeEnderman, Textures by Nova Wustra, modified by JoeEnderman dofile(path .. "/bat.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/rabbit.lua") -- Mesh and animation byExeterDad dofile(path .. "/chicken.lua") -- Mesh and animation by Pavel_S @@ -114,6 +115,7 @@ dofile(path .. "/squid.lua") -- Animation, sound and egg texture by daufinsyd dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i -- Illagers and witch +dofile(path .. "/pillager.lua") -- Mesh by KrupnoPavel and MrRar, animation by MrRar dofile(path .. "/villager_evoker.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager_vindicator.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager_zombie.lua") -- Mesh and animation by toby109tt / https://github.com/22i @@ -142,3 +144,16 @@ dofile(path .. "/slime+magma_cube.lua") -- Wuzzy dofile(path .. "/spider.lua") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture) dofile(path .. "/vex.lua") -- KrupnoPavel dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i + +dofile(path .. "/cod.lua") +dofile(path .. "/salmon.lua") +dofile(path .. "/tropical_fish.lua") +dofile(path .. "/dolphin.lua") + + +dofile(path .. "/glow_squid.lua") + +dofile(path .. "/piglin.lua") +dofile(path .. "/hoglin+zoglin.lua") + +dofile(path .. "/strider.lua") diff --git a/mods/ENTITIES/mobs_mc/iron_golem.lua b/mods/ENTITIES/mobs_mc/iron_golem.lua index 7f1e66714..7ca4dd88a 100644 --- a/mods/ENTITIES/mobs_mc/iron_golem.lua +++ b/mods/ENTITIES/mobs_mc/iron_golem.lua @@ -11,7 +11,7 @@ local S = minetest.get_translator("mobs_mc") local etime = 0 -mcl_mobs:register_mob("mobs_mc:iron_golem", { +mcl_mobs.register_mob("mobs_mc:iron_golem", { description = S("Iron Golem"), type = "npc", spawn_class = "passive", @@ -22,6 +22,9 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", { collisionbox = {-0.7, -0.01, -0.7, 0.7, 2.69, 0.7}, visual = "mesh", mesh = "mobs_mc_iron_golem.b3d", + head_swivel = "head.control", + bone_eye_height = 3.38, + curiosity = 10, textures = { {"mobs_mc_iron_golem.png"}, }, @@ -37,6 +40,7 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", { run_velocity = 1.2, -- Approximation damage = 14, + knock_back = false, reach = 3, group_attack = true, attacks_monsters = true, @@ -44,13 +48,14 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", { _got_poppy = false, pick_up = {"mcl_flowers:poppy"}, on_pick_up = function(self,n) - if n.itemstring:find("mcl_flowers:poppy") then + local it = ItemStack(n.itemstring) + if it:get_name() == "mcl_flowers:poppy" then if not self._got_poppy then self._got_poppy=true - return + it:take_item(1) end - return true end + return it end, replace_what = {"mcl_flowers:poppy"}, replace_with = {"air"}, @@ -84,7 +89,7 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", { etime = etime + dtime if etime > 10 then if self._home and vector.distance(self._home,self.object:get_pos()) > 50 then - mcl_mobs:gopath(self,self._home) + self:gopath(self._home) end end end, @@ -92,8 +97,7 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", { -- spawn eggs -mcl_mobs:register_egg("mobs_mc:iron_golem", S("Iron Golem"), "mobs_mc_spawn_icon_iron_golem.png", 0) - +mcl_mobs.register_egg("mobs_mc:iron_golem", S("Iron Golem"), "#3b3b3b", "#f57223", 0) --[[ This is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function of the node. This summons an iron golen if placing the pumpkin created an iron golem summon pattern: diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index a211b117a..503f4207b 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -24,15 +24,52 @@ local carpets = { unicolor_light_blue = { "mcl_wool:light_blue_carpet", "light_blue" }, } -mcl_mobs:register_mob("mobs_mc:llama", { +local function get_drops(self) + self.drops = {} + table.insert(self.drops, + {name = "mcl_mobitems:leather", + chance = 1, + min = 0, + max = 2, + looting = "common", + }) + if self.carpet then + table.insert(self.drops,{name = self.carpet, + chance = 1, + min = 1, + max = 1,}) + end + if self._has_chest then + table.insert(self.drops,{name = "mcl_chests:chest", + chance = 1, + min = 1, + max = 1,}) + end +end + +mcl_mobs.register_mob("mobs_mc:llama", { description = S("Llama"), type = "animal", spawn_class = "passive", + passive = false, + attack_type = "shoot", + shoot_interval = 5.5, + arrow = "mobs_mc:llamaspit", + shoot_offset = 1, --3.5 *would* be a good value visually but it somehow messes with the projectiles trajectory + spawn_in_group_min = 4, + spawn_in_group = 6, + + head_swivel = "head.control", + bone_eye_height = 11, + head_eye_height = 3, + horrizonatal_head_height=0, + curiosity = 60, + head_yaw = "z", + hp_min = 15, hp_max = 30, xp_min = 1, xp_max = 3, - passive = false, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.86, 0.45}, visual = "mesh", mesh = "mobs_mc_llama.b3d", @@ -43,9 +80,8 @@ mcl_mobs:register_mob("mobs_mc:llama", { {"blank.png", "blank.png", "mobs_mc_llama_white.png"}, {"blank.png", "blank.png", "mobs_mc_llama.png"}, }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, - runaway = true, + runaway = false, walk_velocity = 1, run_velocity = 4.4, follow_velocity = 4.4, @@ -65,36 +101,28 @@ mcl_mobs:register_mob("mobs_mc:llama", { distance = 16, }, animation = { - speed_normal = 24, - run_speed = 60, - run_start = 0, - run_end = 40, - stand_start = 0, - stand_end = 0, - walk_start = 0, - walk_end = 40, - hurt_start = 118, - hurt_end = 154, - death_start = 154, - death_end = 179, - eat_start = 49, - eat_end = 78, - look_start = 78, - look_end = 108, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 35, + run_start = 0, run_end = 40, run_speed = 50, + }, + child_animations = { + stand_start = 41, stand_end = 41, + walk_start = 41, walk_end = 81, walk_speed = 50, + run_start = 41, run_end = 81, run_speed = 75, }, follow = { "mcl_farming:wheat_item", "mcl_farming:hay_block" }, view_range = 16, do_custom = function(self, dtime) -- set needed values if not already present - if not self.v2 then - self.v2 = 0 + if not self.v3 then + self.v3 = 0 self.max_speed_forward = 4 self.max_speed_reverse = 2 self.accel = 4 self.terrain_type = 3 - self.driver_attach_at = {x = 0, y = 4.17, z = -1.5} - self.driver_eye_offset = {x = 0, y = 3, z = 0} + self.driver_attach_at = {x = 0, y = 12.7, z = -5} + self.driver_eye_offset = {x = 0, y = 6, z = 0} self.driver_scale = {x = 1/self.visual_size.x, y = 1/self.visual_size.y} end @@ -128,62 +156,59 @@ mcl_mobs:register_mob("mobs_mc:llama", { local item = clicker:get_wielded_item() if item:get_name() == "mcl_farming:hay_block" then -- Breed with hay bale - if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end + if self:feed_tame(clicker, 1, true, false) then return end + elseif not self._has_chest and item:get_name() == "mcl_chests:chest" then + item:take_item() + clicker:set_wielded_item(item) + self._has_chest = true + self.base_texture = table.copy(self.base_texture) + self.base_texture[1] = self.base_texture[3] + self.object:set_properties({ + textures = self.base_texture, + }) + get_drops(self) + return + elseif self._has_chest and clicker:get_player_control().sneak then + mcl_entity_invs.show_inv_form(self,clicker," - Strength "..math.floor(self._inv_size / 3)) + return else -- Feed with anything else - if mcl_mobs:feed_tame(self, clicker, 1, false, true) then return end + if self:feed_tame(clicker, 1, false, true) then return end end if mcl_mobs:protect(self, clicker) then return end -- Make sure tamed llama is mature and being clicked by owner only if self.tamed and not self.child and self.owner == clicker:get_player_name() then - - -- Place carpet - 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) + -- Place carpet + 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) + 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({ + textures = self.base_texture, + }) + self.carpet = item:get_name() + get_drops(self) + return 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({ - textures = self.base_texture, - }) - self.carpet = item:get_name() - self.drops = { - {name = "mcl_mobitems:leather", - chance = 1, - min = 0, - max = 2,}, - {name = item:get_name(), - chance = 1, - min = 1, - max = 1,}, - } - return end end - end - -- detatch player already riding llama - if self.driver and clicker == self.driver then - - mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1}) - - -- attach player to llama - elseif not self.driver then - - self.object:set_properties({stepheight = 1.1}) - mcl_mobs.attach(self, clicker) - end - - -- Used to capture llama - elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" then - mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + -- detatch player already riding llama + if self.driver and clicker == self.driver then + mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1}) + -- attach player to llama + elseif not self.driver then + self.object:set_properties({stepheight = 1.1}) + mcl_mobs.attach(self, clicker) + end end end, @@ -196,7 +221,7 @@ mcl_mobs:register_mob("mobs_mc:llama", { else parent = parent2 end - child = mcl_mobs:spawn_child(pos, parent.name) + child = mcl_mobs.spawn_child(pos, parent.name) if child then local ent_c = child:get_luaentity() ent_c.base_texture = table.copy(ent_c.base_texture) @@ -208,7 +233,44 @@ mcl_mobs:register_mob("mobs_mc:llama", { return false end end, + on_spawn = function(self) + if not self._inv_size then + local r = math.random(1000) + if r < 80 then + self._inv_size = 15 + elseif r < 160 then + self._inv_size = 12 + elseif r < 488 then + self._inv_size = 9 + elseif r < 816 then + self._inv_size = 6 + else + self._inv_size = 3 + end + end + end, +}) +mcl_entity_invs.register_inv("mobs_mc:llama","Llama",nil,true) + +-- spit arrow (weapon) +mcl_mobs.register_arrow("mobs_mc:llamaspit", { + visual = "sprite", + visual_size = {x = 0.10, y = 0.10}, + textures = {"mobs_mc_llama_spit.png"}, + velocity = 5, + hit_player = function(self, player) + player:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 1}, + }, nil) + end, + + hit_mob = function(self, mob) + end, + + hit_node = function(self, pos, node) + end }) --spawn @@ -217,19 +279,15 @@ mcl_mobs:spawn_specific( "overworld", "ground", { - "Mesa", - "MesaPlateauFM_grasstop", - "MesaPlateauF", - "MesaPlateauFM", - "MesaPlateauF_grasstop", - "MesaBryce", - "Jungle", - "Jungle_shore", - "JungleM", - "JungleM_shore", - "JungleEdge", - "JungleEdgeM", -}, + "Savanna", + "SavannaM", + "SavannaM_beach", + "Savanna_beach", + "Savanna_ocean", + "ExtremeHills", + "ExtremeHills_beach", + "ExtremeHillsM", +}, --FIXME: Needs Windswept Forest when that is added. 0, minetest.LIGHT_MAX+1, 30, @@ -239,4 +297,4 @@ mobs_mc.water_level+15, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) +mcl_mobs.register_egg("mobs_mc:llama", S("Llama"), "#c09e7d", "#995f40", 0) diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr index 7f89bb664..09e0335b8 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr @@ -1,64 +1,58 @@ # textdomain: mobs_mc -Agent=Agente Bat=Murciélago Blaze=Blaze Chicken=Pollo +Cod=Bacalao Cow=Vaca -Mooshroom=Champiñaca +Mooshroom=Champivaca Creeper=Creeper -Ender Dragon=Enderdragón +Dolphin=Delfín +Ender Dragon=Ender Dragon Enderman=Enderman Endermite=Endermite Ghast=Ghast -Elder Guardian=Gran guardián Guardian=Guardián -Horse=Caballo -Skeleton Horse=Caballo esquelético -Zombie Horse=Caballo zombie +Elder Guardian=Guardián Anciano Donkey=Burro +Horse=Caballo Mule=Mula +Skeleton Horse=Caballo esqueleto +Zombie Horse=Caballo zombi Iron Golem=Golem de hierro Llama=Llama +Cat=Gato Ocelot=Ocelote Parrot=Loro Pig=Cerdo Polar Bear=Oso polar -Rabbit=Conejo Killer Bunny=Conejo asesino +Rabbit=Conejo +Salmon=Salmón Sheep=Oveja Shulker=Shulker Silverfish=Lepisma Skeleton=Esqueleto -Stray=Esqueleto -Wither Skeleton=Esqueleto wither +Stray=Esqueleto glacial +Wither Skeleton=Esqueleto del Wither Magma Cube=Cubo de Magma Slime=Slime Snow Golem=Golem de nieve -Spider=Araña Cave Spider=Araña de las cuevas +Spider=Araña Squid=Calamar Vex=Ánima +Master=Maestro +Villager=Aldeano Evoker=Invocador Illusioner=Illusionista -Villager=Aldeano Vindicator=Vindicador -Zombie Villager=Aldeano zombie +Zombie Villager=Aldeano zombi Witch=Bruja Wither=Wither Wolf=Lobo -Husk=Husk -Zombie=Zombie -Zombie Pigman=Cerdo Zombie -Farmer=Granjero -Fisherman=Pescador -Fletcher=Flechador -Shepherd=Sacerdote -Librarian=Bibliotecario -Cartographer=Cartógrafo -Armorer=Armero -Leatherworker=Peletero -Butcher=Carnicero -Weapon Smith=Herrero de Armas -Tool Smith=Herrero de Herramientas -Cleric=Sacerdote -Nitwit=Simple +Baby Husk=Bebé Zombi Momificado +Baby Zombie=Bebé Zombi +Husk=Zombi Momificado +Zombie=Zombi +Baby Zombie Pigman=Bebé Hombrecerdo Zombi +Zombie Pigman=Hombrecerdo Zombi diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr index 3354dd49a..06c97945e 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr @@ -62,3 +62,8 @@ Weapon Smith=Fabriquant d'arme Tool Smith=Fabriquant d'outil Cleric=Clerc Nitwit=Crétin +Cod=Morue +Salmon=Saumon +Dolphin=Dauphin +Pillager=Pilleur +Tropical fish=Poisson tropical \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ja.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ja.tr new file mode 100644 index 000000000..ff6966131 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ja.tr @@ -0,0 +1,70 @@ +# textdomain: mobs_mc +Agent=エージェント +Axolotl=ウーパールーパー +Bat=コウモリ +Blaze=ブレイズ +Chicken=ニワトリ +Cow=ウシ +Mooshroom=ムーシュルーム +Creeper=クリーパー +Ender Dragon=エンダードラゴン +Enderman=エンダーマン +Endermite=エンダーマイト +Ghast=ガスト +Elder Guardian=エルダーガーディアン +Guardian=ガーディアン +Horse=ウマ +Skeleton Horse=スケルトンホース +Zombie Horse=ゾンビホース +Donkey=ロバ +Mule=ラバ +Iron Golem=アイアンゴーレム +Llama=ラマ +Ocelot=ヤマネコ +Parrot=オウム +Pig=ブタ +Polar Bear=シロクマ +Rabbit=ウサギ +Killer Bunny=殺人ウサギ +Sheep=ヒツジ +Shulker=シュルカー +Silverfish=シルバーフィッシュ +Skeleton=スケルトン +Stray=ストレイ +Wither Skeleton=ウィザースケルトン +Magma Cube=マグマキューブ +Slime=スライム +Snow Golem=スノーゴーレム +Spider=クモ +Cave Spider=洞窟グモ +Squid=イカ +Vex=ヴェックス +Evoker=エヴォーカー +Illusioner=イリュージョナー +Villager=村人 +Vindicator=ヴィンディケーター +Zombie Villager=村人ゾンビ +Witch=魔女 +Wither=ウィザー +Wolf=オオカミ +Husk=ハスク +Zombie=ゾンビ +Zombie Pigman=ゾンビピッグマン +Farmer=農民 +Fisherman=漁師 +Fletcher=矢師 +Shepherd=羊飼い +Librarian=司書 +Cartographer=製図家 +Armorer=防具鍛冶 +Leatherworker=革職人 +Butcher=肉屋 +Weapon Smith=武器鍛冶 +Tool Smith=道具鍛冶 +Cleric=聖職者 +Nitwit=求職者 +Cod=タラ +Salmon=サケ +Dolphin=イルカ +Pillager=ピリジャー +Tropical fish=クマノミ \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/locale/template.txt b/mods/ENTITIES/mobs_mc/locale/template.txt index aedd8754c..38c6111b5 100644 --- a/mods/ENTITIES/mobs_mc/locale/template.txt +++ b/mods/ENTITIES/mobs_mc/locale/template.txt @@ -1,5 +1,6 @@ # textdomain: mobs_mc Agent= +Axolotl= Bat= Blaze= Chicken= @@ -62,3 +63,8 @@ Weapon Smith= Tool Smith= Cleric= Nitwit= +Cod= +Salmon= +Dolphin= +Pillager= +Tropical fish= \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/mod.conf b/mods/ENTITIES/mobs_mc/mod.conf index 3d6a6928d..5b94879b2 100644 --- a/mods/ENTITIES/mobs_mc/mod.conf +++ b/mods/ENTITIES/mobs_mc/mod.conf @@ -1,6 +1,5 @@ name = mobs_mc author = maikerumine description = Adds Minecraft-like monsters and animals. -depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core -optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items - +depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core, mcl_util +optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, doc_items diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_cod.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_cod.b3d new file mode 100644 index 000000000..c7e60e12c Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_cod.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_dolphin.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_dolphin.b3d new file mode 100644 index 000000000..37e2e96ae Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_dolphin.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_glow_squid.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_glow_squid.b3d new file mode 100644 index 000000000..887576b28 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_glow_squid.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_hoglin.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_hoglin.b3d new file mode 100644 index 000000000..d3886e089 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_hoglin.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_piglin.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_piglin.b3d new file mode 100644 index 000000000..e07bd15aa Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_piglin.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_salmon.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_salmon.b3d new file mode 100644 index 000000000..50180af95 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_salmon.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_strider.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_strider.b3d new file mode 100644 index 000000000..72f4e254e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_strider.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_sword_piglin.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_sword_piglin.b3d new file mode 100644 index 000000000..1988f4082 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_sword_piglin.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_a.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_a.b3d new file mode 100644 index 000000000..2131319fa Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_a.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_b.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_b.b3d new file mode 100644 index 000000000..b97bfb228 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_b.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_agent.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_agent.b3d deleted file mode 100644 index 3e79c009b..000000000 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_agent.b3d and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_axolotl.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_axolotl.b3d new file mode 100644 index 000000000..3e4c8119e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/mobs_mc_axolotl.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_blaze.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_blaze.b3d index 2328c8a64..7593baa2f 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_blaze.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_blaze.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_cat.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_cat.b3d index 1a6ecbbe8..84cc91652 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_cat.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_cat.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_chicken.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_chicken.b3d index 6d839a459..623a467b9 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_chicken.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_chicken.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_cow.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_cow.b3d index c00983919..f29c6a961 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_cow.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_cow.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_creeper.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_creeper.b3d index e04ffc7b0..72887d8d4 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_creeper.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_creeper.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_evoker.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_evoker.b3d index 6e1017e0c..4a429f7c3 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_evoker.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_evoker.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_illusioner.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_illusioner.b3d index 7bb719ffb..6bdcbf339 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_illusioner.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_illusioner.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_iron_golem.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_iron_golem.b3d index a7fbd352b..db87e6540 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_iron_golem.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_iron_golem.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_llama.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_llama.b3d index 5d6dd6b37..8e1da8b24 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_llama.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_llama.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_mooshroom.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_mooshroom.b3d deleted file mode 100644 index c00983919..000000000 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_mooshroom.b3d and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_parrot.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_parrot.b3d index 7cb326d3d..2f59c313b 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_parrot.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_parrot.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_pig.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_pig.b3d index 8ba5b6a84..4bbaf6e23 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_pig.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_pig.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.b3d new file mode 100644 index 000000000..18c1a06c4 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.blend b/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.blend new file mode 100644 index 000000000..e0524ab74 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.blend differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_polarbear.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_polarbear.b3d index bb64b2b79..cbda1f8c9 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_polarbear.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_polarbear.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_rabbit.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_rabbit.b3d index ad2067d7b..d28aa5368 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_rabbit.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_rabbit.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_sheepfur.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_sheepfur.b3d index 1db15ddba..7ee15fb55 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_sheepfur.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_sheepfur.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_skeleton.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_skeleton.b3d index aa1681dbe..f5e8d4917 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_skeleton.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_skeleton.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_spider.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_spider.b3d index aec461a6b..0d71f6377 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_spider.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_spider.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_villager.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_villager.b3d index 1b92adfa5..1d46a162b 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_villager.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_villager.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_villager_zombie.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_villager_zombie.b3d index b7dd9d7ee..a45eac602 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_villager_zombie.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_villager_zombie.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_vindicator.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_vindicator.b3d index ae14e8edb..d220e895c 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_vindicator.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_vindicator.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_witherskeleton.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_witherskeleton.b3d index c1b808307..ec2952cf5 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_witherskeleton.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_witherskeleton.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_wolf.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_wolf.b3d index 63db5e097..82684e303 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_wolf.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_wolf.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie.b3d index deacf31b6..1da2bc66b 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie_pigman.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie_pigman.b3d index 0b9f4f7c9..0f1d6ea24 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie_pigman.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie_pigman.b3d differ diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index 983199762..8a7ea7545 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -30,15 +30,22 @@ local ocelot = { type = "animal", spawn_class = "passive", can_despawn = true, + spawn_in_group = 3, + spawn_in_group_min = 1, hp_min = 10, hp_max = 10, xp_min = 1, xp_max = 3, + head_swivel = "head.control", + bone_eye_height = 6.2, + head_eye_height = 0.4, + horrizonatal_head_height=-0, + head_yaw="z", + curiosity = 4, collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.69, 0.3}, visual = "mesh", mesh = "mobs_mc_cat.b3d", textures = {"mobs_mc_cat_ocelot.png"}, - visual_size = {x=2.0, y=2.0}, makes_footstep_sound = true, walk_chance = default_walk_chance, walk_velocity = 1, @@ -55,14 +62,16 @@ local ocelot = { distance = 16, }, animation = { - speed_normal = 25, - run_speed = 50, - stand_start = 0, - stand_end = 0, - walk_start = 0, - walk_end = 40, - run_start = 0, - run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 40, + run_start = 0, run_end = 40, run_speed = 50, + sit_start = 50, sit_end = 50, + }, + child_animations = { + stand_start = 51, stand_end = 51, + walk_start = 51, walk_end = 91, walk_speed = 60, + run_start = 51, run_end = 91, run_speed = 75, + sit_start = 101, sit_end = 101, }, follow = follow, view_range = 12, @@ -98,7 +107,7 @@ local ocelot = { end, } -mcl_mobs:register_mob("mobs_mc:ocelot", ocelot) +mcl_mobs.register_mob("mobs_mc:ocelot", ocelot) -- Cat local cat = table.copy(ocelot) @@ -121,7 +130,7 @@ cat.sounds = { distance = 16, } cat.on_rightclick = function(self, clicker) - if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end + if self:feed_tame(clicker, 1, true, false) then return end if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end if mcl_mobs:protect(self, clicker) then return end @@ -148,7 +157,17 @@ cat.on_rightclick = function(self, clicker) end -mcl_mobs:register_mob("mobs_mc:cat", cat) +cat.on_spawn = function(self) + if self.owner == "!witch!" then + self._texture = {"mobs_mc_cat_black.png"} + end + if not self._texture then + self._texture = cat.textures[math.random(#cat.textures)] + end + self.object:set_properties({textures = {self._texture}}) +end + +mcl_mobs.register_mob("mobs_mc:cat", cat) local base_spawn_chance = 5000 @@ -230,5 +249,4 @@ mobs:spawn({ ]]-- -- spawn eggs --- FIXME: The spawn icon shows a cat texture, not an ocelot texture -mcl_mobs:register_egg("mobs_mc:ocelot", S("Ocelot"), "mobs_mc_spawn_icon_cat.png", 0) +mcl_mobs.register_egg("mobs_mc:ocelot", S("Ocelot"), "#efde7d", "#564434", 0) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 84b3aaead..ed2892aca 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -13,6 +13,53 @@ local shoulders = { right = vector.new(3.75,10.5,0) } +local function table_get_rand(tbl) + local keys = {} + for k in pairs(tbl) do + table.insert(keys, k) + end + return tbl[keys[math.random(#keys)]] +end + +local function get_random_mob_sound() + local t = table.copy(minetest.registered_entities) + table.shuffle(t) + for _,e in pairs(t) do + if e.is_mob and e.sounds and #e.sounds > 0 then + return table_get_rand(e.sounds) + end + end + return minetest.registered_entities["mobs_mc:parrot"].sounds.random +end + +local function imitate_mob_sound(self,mob) + local snd = mob.sounds.random + if not snd or mob.name == "mobs_mc:parrot" or math.random(20) == 1 then + snd = get_random_mob_sound() + end + return minetest.sound_play(snd, { + pos = self.object:get_pos(), + gain = 1.0, + pitch = 2.5, + max_hear_distance = self.sounds and self.sounds.distance or 32 + }, true) +end + +local function check_mobimitate(self,dtime) + if not self._mobimitate_timer or self._mobimitate_timer > 30 then + self._mobimitate_timer = 0 + for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),20)) do + local l = o:get_luaentity() + if l and l.is_mob and l.name ~= "mobs_mc:parrot" then + imitate_mob_sound(self,l) + return + end + end + end + self._mobimitate_timer = self._mobimitate_timer + dtime + +end + --find a free shoulder or return nil local function get_shoulder(player) local sh = "left" @@ -40,7 +87,7 @@ local function perch(self,player) local shoulder = get_shoulder(player) if not shoulder then return true end self.object:set_attach(player,"",shoulder,vector.new(0,0,0),true) - mcl_mobs:set_animation(self, "stand") + self:set_animation("stand") end end @@ -53,7 +100,8 @@ local function check_perch(self,dtime) local n1 = minetest.get_node(vector.offset(p:get_pos(),0,-0.6,0)).name local n2 = minetest.get_node(vector.offset(p:get_pos(),0,0,0)).name local n3 = minetest.get_node(vector.offset(p:get_pos(),0,1,0)).name - if n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0 then + if ( n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0) and + not minetest.is_creative_enabled(p:get_player_name()) then o:set_detach() self.detach_timer = 0 return @@ -77,15 +125,20 @@ local function check_perch(self,dtime) end end -mcl_mobs:register_mob("mobs_mc:parrot", { +mcl_mobs.register_mob("mobs_mc:parrot", { description = S("Parrot"), - type = "npc", + type = "animal", spawn_class = "passive", + passive = true, pathfinding = 1, hp_min = 6, hp_max = 6, xp_min = 1, xp_max = 3, + head_swivel = "head.control", + bone_eye_height = 1.1, + horrizonatal_head_height=0, + curiosity = 10, collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25}, visual = "mesh", mesh = "mobs_mc_parrot.b3d", @@ -154,11 +207,12 @@ mcl_mobs:register_mob("mobs_mc:parrot", { return end -- Feed to tame, but not breed - if mcl_mobs:feed_tame(self, clicker, 1, false, true) then return end + if self:feed_tame(clicker, 1, false, true) then return end perch(self,clicker) end, do_custom = function(self,dtime) check_perch(self,dtime) + check_mobimitate(self,dtime) end, do_punch = function(self,puncher) --do_punch is the mcl_mobs_redo variant - it gets called by on_punch later.... if self.object:get_attach() == puncher then @@ -187,4 +241,4 @@ mobs_mc.water_level+7, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) +mcl_mobs.register_egg("mobs_mc:parrot", S("Parrot"), "#0da70a", "#ff0000", 0) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 3cf88b915..99e05391f 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -2,7 +2,7 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:pig", { +mcl_mobs.register_mob("mobs_mc:pig", { description = S("Pig"), type = "animal", spawn_class = "passive", @@ -15,11 +15,15 @@ mcl_mobs:register_mob("mobs_mc:pig", { visual = "mesh", mesh = "mobs_mc_pig.b3d", textures = {{ - "blank.png", -- baby "mobs_mc_pig.png", -- base "blank.png", -- saddle }}, - visual_size = {x=2.5, y=2.5}, + head_swivel = "head.control", + bone_eye_height = 7.5, + head_eye_height = 0.8, + horrizonatal_head_height=-1, + curiosity = 3, + head_yaw="z", makes_footstep_sound = true, walk_velocity = 1, run_velocity = 3, @@ -40,15 +44,14 @@ mcl_mobs:register_mob("mobs_mc:pig", { distance = 16, }, animation = { - stand_speed = 40, - walk_speed = 40, - run_speed = 90, - stand_start = 0, - stand_end = 0, - walk_start = 0, - walk_end = 40, - run_start = 0, - run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 60, + run_start = 0, run_end = 40, run_speed = 90, + }, + child_animations = { + stand_start = 41, stand_end = 41, + walk_start = 41, walk_end = 81, walk_speed = 90, + run_start = 41, run_end = 81, run_speed = 135, }, follow = { "mcl_farming:potato_item", @@ -57,18 +60,24 @@ mcl_mobs:register_mob("mobs_mc:pig", { "mcl_mobitems:carrot_on_a_stick" }, view_range = 8, + on_lightning_strike = function(self, pos, pos2, objects) + mcl_util.replace_mob(self.object, "mobs_mc:zombified_piglin") + return true + end, do_custom = function(self, dtime) -- set needed values if not already present - if not self.v2 then - self.v2 = 0 + if not self.v3 then + self.v3 = 0 self.max_speed_forward = 4 self.max_speed_reverse = 2 self.accel = 4 self.terrain_type = 3 - self.driver_attach_at = {x = 0.0, y = 2.75, z = -1.5} + self.driver_attach_at = {x = 0.0, y = 6.5, z = -3.75} self.driver_eye_offset = {x = 0, y = 3, z = 0} self.driver_scale = {x = 1/self.visual_size.x, y = 1/self.visual_size.y} + self.base_texture = self.texture_list[1] + self.object:set_properties({textures = self.base_texture}) end -- if driver present allow control of horse @@ -99,7 +108,7 @@ mcl_mobs:register_mob("mobs_mc:pig", { local wielditem = clicker:get_wielded_item() -- Feed pig if wielditem:get_name() ~= "mcl_mobitems:carrot_on_a_stick" then - if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end + if self:feed_tame(clicker, 1, true, false) then return end end if mcl_mobs:protect(self, clicker) then return end @@ -111,7 +120,6 @@ mcl_mobs:register_mob("mobs_mc:pig", { local item = clicker:get_wielded_item() if item:get_name() == "mcl_mobitems:saddle" and self.saddle ~= "yes" then self.base_texture = { - "blank.png", -- baby "mobs_mc_pig.png", -- base "mobs_mc_pig_saddle.png", -- saddle } @@ -178,7 +186,7 @@ mcl_mobs:register_mob("mobs_mc:pig", { on_breed = function(parent1, parent2) local pos = parent1.object:get_pos() - local child = mcl_mobs:spawn_child(pos, parent1.name) + local child = mcl_mobs.spawn_child(pos, parent1.name) if child then local ent_c = child:get_luaentity() ent_c.tamed = true @@ -194,17 +202,12 @@ mcl_mobs:spawn_specific( "ground", { "flat", - "IcePlainsSpikes", - "ColdTaiga", - "ColdTaiga_beach", - "ColdTaiga_beach_water", "MegaTaiga", "MegaSpruceTaiga", "ExtremeHills", "ExtremeHills_beach", "ExtremeHillsM", "ExtremeHills+", - "ExtremeHills+_snowtop", "StoneBeach", "Plains", "Plains_beach", @@ -239,4 +242,4 @@ mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0) +mcl_mobs.register_egg("mobs_mc:pig", S("Pig"), "#f0a5a2", "#db635f", 0) diff --git a/mods/ENTITIES/mobs_mc/piglin.lua b/mods/ENTITIES/mobs_mc/piglin.lua new file mode 100644 index 000000000..90e19ef02 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/piglin.lua @@ -0,0 +1,320 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local trading_items = { + { itemstring = "mcl_core:obsidian", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:gravel", amount_min = 8, amount_max = 16 }, + { itemstring = "mcl_mobitems:leather", amount_min = 4, amount_max = 10 }, + { itemstring = "mcl_nether:soul_sand", amount_min = 4, amount_max = 16 }, + { itemstring = "mcl_nether:nether_brick", amount_min = 4, amount_max = 16 }, + { itemstring = "mcl_mobitems:string", amount_min = 3, amount_max = 9 }, + { itemstring = "mcl_nether:quartz", amount_min = 4, amount_max = 10 }, + { itemstring = "mcl_potions:water", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:iron_nugget", amount_min = 10, amount_max = 36 }, + { itemstring = "mcl_throwing:ender_pearl", amount_min = 2, amount_max = 6 }, + { itemstring = "mcl_potions:fire_resistance", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_potions:fire_resistance_splash", amount_min = 1, amount_max = 1 }, +} + +local S = minetest.get_translator("mobs_mc") +local mod_bows = minetest.get_modpath("mcl_bows") ~= nil + +function mobs_mc.player_wears_gold(player) + for i=1, 6 do + local stack = player:get_inventory():get_stack("armor", i) + local item = stack:get_name() + if item == "mcl_armor:chestplate_gold" or item == "mcl_armor:leggings_gold" or item == "mcl_armor:helmet_gold" or item == "mcl_armor:boots_gold" then + return true + end + end +end + +--################### +--################### piglin +--################### +local piglin = { + type = "monster", + passive = false, + spawn_class = "hostile", + hp_min = 16, + hp_max = 16, + xp_min = 9, + xp_max = 9, + armor = {fleshy = 90}, + damage = 4, + reach = 3, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, + visual = "mesh", + mesh = "extra_mobs_piglin.b3d", + spawn_in_group = 4, + spawn_in_group_min = 2, + textures = { { + "extra_mobs_piglin.png", + "mcl_bows_bow_2.png", + } }, + visual_size = {x=1, y=1}, + sounds = { + random = "extra_mobs_piglin", + damage = "extra_mobs_piglin_hurt", + distance = 16, + }, + jump = true, + makes_footstep_sound = true, + walk_velocity = 4.317, + run_velocity = 5.6121, + drops = { + {name = "mcl_bows:crossbow", + chance = 10, + min = 1, + max = 1,}, + }, + animation = { + stand_speed = 30, + walk_speed = 30, + run_speed = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 440, + run_end = 459, + }, + fear_height = 4, + view_range = 16, + pick_up = {"mcl_core:gold_ingot"}, + on_spawn = function(self) + self.weapon = self.base_texture[2] + self.gold_items = 0 + end, + do_custom = function(self) + if self.object:get_pos().y > mcl_vars.mg_overworld_min then + local zog = minetest.add_entity(self.object:get_pos(), "mobs_mc:zombified_piglin") + zog:set_rotation(self.object:get_rotation()) + self.object:remove() + return + elseif self.trading == true then + self.state = "trading" + self.object:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(20,-20,18)) + self.object:set_bone_position("Head", vector.new(0,6.3,0), vector.new(-40,0,0)) + self.base_texture[2] = "default_gold_ingot.png" + self.object:set_properties({textures = self.base_texture}) + else + self.object:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) + self.base_texture[2] = self.weapon + self.object:set_properties({textures = self.base_texture}) + self.object:set_bone_position("Head", vector.new(0,6.3,0), vector.new(0,0,0)) + self.object:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) + end + + if self.state ~= "attack" then + self._attacked_by_player = false + elseif self.attack:is_player() and mobs_mc.player_wears_gold(self.attack) then + if self._attacked_by_player == false then + self.state = "stand" + end + end + end, + on_pick_up = function(self, itementity) + local item = itementity.itemstring:split(" ")[1] + local it = ItemStack(itementity.itemstring) + if item == "mcl_core:gold_ingot" and self.state ~= "attack" and self.gold_items and self.gold_items < 3 then + it:take_item(1) + self.state = "stand" + self.object:set_animation({x=0,y=79}) + self.trading = true + self.gold_items = self.gold_items + 1 + self.object:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) + minetest.after(5, function() + self.gold_items = self.gold_items - 1 + if self.gold_items == 0 then + self.trading = false + self.state = "stand" + end + local c_pos = self.object:get_pos() + if c_pos then + self.what_traded = trading_items[math.random(#trading_items)] + for x = 1, math.random(self.what_traded.amount_min, self.what_traded.amount_max) do + local p = c_pos + local nn=minetest.find_nodes_in_area_under_air(vector.offset(c_pos,-1,-1,-1),vector.offset(c_pos,1,1,1),{"group:solid"}) + if nn and #nn > 0 then + p = vector.offset(nn[math.random(#nn)],0,1,0) + end + minetest.add_item(p, self.what_traded.itemstring) + end + end + end) + end + return it + end, + do_punch = function(self, hitter) + if hitter:is_player() then + self._attacked_by_player = true + end + end, + attack_type = "dogshoot", + arrow = "mcl_bows:arrow_entity", + shoot_arrow = function(self, pos, dir) + if mod_bows then + if self.attack then + self.object:set_yaw(minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos()))) + end + -- 2-4 damage per arrow + local dmg = math.max(4, math.random(2, 8)) + mcl_bows.shoot_arrow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + end + end, + shoot_interval = 2, + shoot_offset = 1.5, + dogshoot_switch = 1, + dogshoot_count_max =1.8, + attacks_monsters = true, + attack_animals = true, + specific_attack = { "player", "mobs_mc:hoglin" }, +} + +mcl_mobs.register_mob("mobs_mc:piglin", piglin) + + +local sword_piglin = table.copy(piglin) +sword_piglin.mesh = "extra_mobs_sword_piglin.b3d" +sword_piglin.textures = {"extra_mobs_piglin.png", "default_tool_goldsword.png"} +sword_piglin.on_spawn = function(self) + self.gold_items = 0 + self.weapon = self.base_texture[2] + self.object:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) +end +sword_piglin.drops = { + {name = "mcl_tools:sword_gold", + chance = 10, + min = 1, + max = 1,}, +} +sword_piglin.attack_type = "dogfight" +sword_piglin.animation = { + stand_speed = 30, + walk_speed = 30, + punch_speed = 45, + run_speed = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 440, + run_end = 459, + punch_start = 189, + punch_end = 198, +} +mcl_mobs.register_mob("mobs_mc:sword_piglin", sword_piglin) + +local zombified_piglin = table.copy(piglin) +zombified_piglin.fire_resistant = 1 +zombified_piglin.do_custom = function() + return +end +zombified_piglin.on_spawn = function() + return +end +zombified_piglin.on_rightclick = function() + return +end +zombified_piglin.lava_damage = 0 +zombified_piglin.fire_damage = 0 +zombified_piglin.attack_animals = true +zombified_piglin.mesh = "extra_mobs_sword_piglin.b3d" +zombified_piglin.textures = {"extra_mobs_zombified_piglin.png", "default_tool_goldsword.png", "extra_mobs_trans.png"} +zombified_piglin.attack_type = "dogfight" +zombified_piglin.animation = { + stand_speed = 30, + walk_speed = 30, + punch_speed = 45, + run_speed = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 440, + run_end = 459, + punch_start = 189, + punch_end = 198, +} +mcl_mobs.register_mob("mobs_mc:zombified_piglin", zombified_piglin) + + +local piglin_brute = table.copy(piglin) +piglin_brute.xp_min = 20 +piglin_brute.xp_max = 20 +piglin_brute.hp_min = 50 +piglin_brute.hp_max = 50 +piglin_brute.fire_resistant = 1 +piglin_brute.do_custom = function() + return +end +piglin_brute.on_spawn = function() + return +end +piglin_brute.on_rightclick = function() + return +end +piglin_brute.attacks_monsters = true +piglin_brute.lava_damage = 0 +piglin_brute.fire_damage = 0 +piglin_brute.attack_animals = true +piglin_brute.mesh = "extra_mobs_sword_piglin.b3d" +piglin_brute.textures = {"extra_mobs_piglin_brute.png", "default_tool_goldaxe.png", "extra_mobs_trans.png"} +piglin_brute.attack_type = "dogfight" +piglin_brute.animation = { + stand_speed = 30, + walk_speed = 30, + punch_speed = 45, + run_speed = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 440, + run_end = 459, + punch_start = 189, + punch_end = 198, +} +piglin_brute.can_despawn = false +piglin_brute.group_attack = { "mobs_mc:piglin", "mobs_mc:piglin_brute" } +mcl_mobs.register_mob("mobs_mc:piglin_brute", piglin_brute) + + +-- Regular spawning in the Nether +mcl_mobs:spawn_specific( +"mobs_mc:piglin", +"nether", +"ground", +{ +"Nether", +"CrimsonForest" +}, +0, +minetest.LIGHT_MAX+1, +30, +6000, +3, +mcl_vars.mg_lava_nether_max, +mcl_vars.mg_nether_max) + +mcl_mobs:spawn_specific( +"mobs_mc:sword_piglin", +"nether", +"ground", +{ +"Nether", +"CrimsonForest" +}, +0, +minetest.LIGHT_MAX+1, +30, +6000, +3, +mcl_vars.mg_lava_nether_max, +mcl_vars.mg_nether_max) +-- spawn eggs +mcl_mobs.register_egg("mobs_mc:piglin", S("Piglin"), "#7b4a17","#d5c381", 0) +mcl_mobs.register_egg("mobs_mc:piglin_brute", S("Piglin Brute"), "#562b0c","#ddc89d", 0) diff --git a/mods/ENTITIES/mobs_mc/pillager.lua b/mods/ENTITIES/mobs_mc/pillager.lua new file mode 100644 index 000000000..0b6b036f7 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/pillager.lua @@ -0,0 +1,124 @@ +local S = minetest.get_translator("mobs_mc") + +local function reload(self) + if not self.object:get_pos() then return end + minetest.sound_play("mcl_bows_crossbow_drawback_1", {object = self.object, max_hear_distance=16}, true) + local props = self.object:get_properties() + if not props then return end + props.textures[2] = "mcl_bows_crossbow_3.png^[resize:16x16" + self.object:set_properties(props) +end + +local function reset_animation(self, animation) + if not self.object:get_pos() or self._current_animation ~= animation then return end + self._current_animation = "stand_reload" -- Mobs Redo won't set the animation unless we do this + self:set_animation(animation) +end + +pillager = { + description = S("Pillager"), + type = "monster", + spawn_class = "hostile", + hp_min = 24, + hp_max = 24, + xp_min = 6, + xp_max = 6, + breath_max = -1, + eye_height = 1.5, + shoot_interval = 3, + shoot_offset = 1.5, + armor = {fleshy = 100}, + can_despawn = false, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3}, + pathfinding = 1, + group_attack = true, + visual = "mesh", + mesh = "mobs_mc_pillager.b3d", + visual_size = {x=2.75, y=2.75}, + makes_footstep_sound = true, + walk_velocity = 1.2, + run_velocity = 4, + view_range = 16, + fear_height = 4, + arrow = "mcl_bows:arrow_entity", + attack_type = "dogshoot", -- Alternate punching/shooting + attack_npcs = true, + reach = 0, -- Punching max distance + damage = 0, -- Punching damage + dogshoot_switch = 1, -- Start of shooting + dogshoot_count_max = 5, -- Max time spent shooting (standing) + dogshoot_count2_max = 1, -- Max time spent punching (running) + sounds = { + random = "mobs_mc_pillager_grunt2", + war_cry = "mobs_mc_pillager_grunt1", + death = "mobs_mc_pillager_ow2", + damage = "mobs_mc_pillager_ow1", + distance = 16, + }, + textures = { + { + "mobs_mc_pillager.png", -- Skin + "mcl_bows_crossbow_3.png^[resize:16x16", -- Wielded item + } + }, + drops = { + { + name = "mcl_bows:arrow", + chance = 1, + min = 0, + max = 2, + looting = "common", + }, + { + name = "mcl_bows:crossbow", + chance = 100 / 8.5, + min = 1, + max = 1, + looting = "rare", + }, + }, + animation = { + unloaded_walk_start = 1, unloaded_walk_end = 40, + unloaded_stand_start = 41, unloaded_stand_end = 60, + reload_stand_start = 61, reload_stand_end = 100, reload_stand_speed = 20, + stand_start = 101, stand_end = 109, stand_speed = 6, + walk_start = 111, walk_end = 150, walk_speed = 30, + run_start = 111, run_end = 150, run_speed = 50, + reload_run_start = 151, reload_run_end = 190, reload_run_speed = 20, + die_start = 191, die_end = 192, die_speed = 15, + stand_unloaded_start = 40, stand_unloaded_end = 59, + die_loop = false, + }, + shoot_arrow = function(self, pos, dir) + minetest.sound_play("mcl_bows_crossbow_shoot", {object = self.object, max_hear_distance=16}, true) + local props = self.object:get_properties() + props.textures[2] = "mcl_bows_crossbow_0.png^[resize:16x16" + self.object:set_properties(props) + local old_anim = self._current_animation + if old_anim == "run" or old_anim == "walk" then + self:set_animation("reload_run") + end + if old_anim == "stand" then + self:set_animation("reload_stand") + end + self._current_animation = old_anim -- Mobs Redo will imediately reset the animation otherwise + minetest.after(1, reload, self) + minetest.after(2, reset_animation, self, old_anim) + + -- 2-4 damage per arrow + local dmg = math.max(4, math.random(2, 8)) + mcl_bows_s.shoot_arrow_crossbow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + + -- While we are at it, change the sounds since there is no way to do this in Mobs Redo + if self.sounds and self.sounds.random then + self.sounds = table.copy(self.sounds) + self.sounds.random = "mobs_mc_pillager_grunt" .. math.random(2) + end + + -- Randomize reload time + self.shoot_interval = math.random(3, 4) + end, +} + +mcl_mobs.register_mob("mobs_mc:pillager", pillager) +mcl_mobs.register_egg("mobs_mc:pillager", S("Pillager"), "#532f36", "#959b9b", 0) diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 3fd2d0a0c..d6667a256 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -7,7 +7,7 @@ local S = minetest.get_translator("mobs_mc") --################### -mcl_mobs:register_mob("mobs_mc:polar_bear", { +mcl_mobs.register_mob("mobs_mc:polar_bear", { description = S("Polar Bear"), type = "animal", spawn_class = "passive", @@ -24,6 +24,12 @@ mcl_mobs:register_mob("mobs_mc:polar_bear", { textures = { {"mobs_mc_polarbear.png"}, }, + head_swivel = "head.control", + bone_eye_height = 2.6, + head_eye_height = 1, + horrizonatal_head_height = 0, + curiosity = 20, + head_yaw="z", visual_size = {x=3.0, y=3.0}, makes_footstep_sound = true, damage = 6, @@ -76,7 +82,6 @@ mcl_mobs:spawn_specific( "ColdTaiga", "IcePlainsSpikes", "IcePlains", -"ExtremeHills+_snowtop", }, 0, minetest.LIGHT_MAX+1, @@ -87,4 +92,4 @@ mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn egg -mcl_mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) +mcl_mobs.register_egg("mobs_mc:polar_bear", S("Polar Bear"), "#f2f2f2", "#959590", 0) diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index 524000a71..6d13fbe22 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -6,15 +6,21 @@ local rabbit = { description = S("Rabbit"), type = "animal", spawn_class = "passive", + spawn_in_group_min = 2, + spawn_in_group = 3, passive = true, reach = 1, - hp_min = 3, hp_max = 3, xp_min = 1, xp_max = 3, collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.49, 0.2}, - + head_swivel = "head.control", + bone_eye_height = 2, + head_eye_height = 0.5, + horrizonatal_head_height = -.3, + curiosity = 20, + head_yaw="z", visual = "mesh", mesh = "mobs_mc_rabbit.b3d", textures = { @@ -25,7 +31,6 @@ local rabbit = { {"mobs_mc_rabbit_salt.png"}, {"mobs_mc_rabbit_black.png"}, }, - visual_size = {x=1.5, y=1.5}, sounds = { random = "mobs_mc_rabbit_random", damage = "mobs_mc_rabbit_hurt", @@ -48,10 +53,14 @@ local rabbit = { }, fear_height = 4, animation = { - speed_normal = 25, speed_run = 50, - stand_start = 0, stand_end = 0, - walk_start = 0, walk_end = 20, - run_start = 0, run_end = 20, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 20, walk_speed = 20, + run_start = 0, run_end = 20, run_speed = 30, + }, + child_animations = { + stand_start = 21, stand_end = 21, + walk_start = 21, walk_end = 41, walk_speed = 30, + run_start = 21, run_end = 41, run_speed = 45, }, -- Follow (yellow) dangelions, carrots and golden carrots follow = { @@ -74,7 +83,7 @@ local rabbit = { }, on_rightclick = function(self, clicker) -- Feed, tame protect or capture - if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end + if self:feed_tame(clicker, 1, true, false) then return end if mcl_mobs:protect(self, clicker) then return end if mcl_mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end end, @@ -93,7 +102,7 @@ local rabbit = { end, } -mcl_mobs:register_mob("mobs_mc:rabbit", rabbit) +mcl_mobs.register_mob("mobs_mc:rabbit", rabbit) -- The killer bunny (Only with spawn egg) local killer_bunny = table.copy(rabbit) @@ -119,7 +128,7 @@ killer_bunny.do_custom = function(self) end end -mcl_mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) +mcl_mobs.register_mob("mobs_mc:killer_bunny", killer_bunny) -- Mob spawning rules. -- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out @@ -132,18 +141,9 @@ mcl_mobs:spawn_specific( "Desert", "FlowerForest", "Taiga", -"ExtremeHills", -"BirchForest", "MegaSpruceTaiga", "MegaTaiga", -"ExtremeHills+", -"Plains", "ColdTaiga", -"SunflowerPlains", -"RoofedForest", -"MesaPlateauFM_grasstop", -"ExtremeHillsM", -"BirchForestM", }, 9, minetest.LIGHT_MAX+1, @@ -213,7 +213,7 @@ mcl_mobs:spawn(spawn_grass) ]]-- -- Spawn egg -mcl_mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) +mcl_mobs.register_egg("mobs_mc:rabbit", S("Rabbit"), "#995f40", "#734831", 0) -- Note: This spawn egg does not exist in Minecraft -mcl_mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit.png^[colorize:#FF0000:192", 0) -- TODO: Update inventory image +mcl_mobs.register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "#f2f2f2", "#ff0000", 0) diff --git a/mods/ENTITIES/mobs_mc/salmon.lua b/mods/ENTITIES/mobs_mc/salmon.lua new file mode 100644 index 000000000..873d4bb74 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/salmon.lua @@ -0,0 +1,229 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local S = minetest.get_translator(minetest.get_current_modname()) + +--################### +--################### salmon +--################### + +local salmon = { + type = "animal", + spawn_class = "water", + can_despawn = true, + passive = true, + hp_min = 3, + hp_max = 3, + xp_min = 1, + xp_max = 3, + armor = 100, + spawn_in_group = 5, + tilt_swim = true, + collisionbox = {-0.4, 0.0, -0.4, 0.4, 0.79, 0.4}, + visual = "mesh", + mesh = "extra_mobs_salmon.b3d", + textures = { + {"extra_mobs_salmon.png"} + }, + sounds = { + }, + animation = { + stand_start = 1, + stand_end = 20, + walk_start = 1, + walk_end = 20, + run_start = 1, + run_end = 20, + }, + drops = { + {name = "mcl_fishing:salmon_raw", + chance = 1, + min = 1, + max = 1,}, + {name = "mcl_bone_meal:bone_meal", + chance = 20, + min = 1, + max = 1,}, + }, + visual_size = {x=3, y=3}, + makes_footstep_sound = false, + swim = true, + fly = true, + fly_in = "mcl_core:water_source", + breathes_in_water = true, + jump = false, + view_range = 16, + runaway = true, + fear_height = 4, + on_rightclick = function(self, clicker) + local bn = clicker:get_wielded_item():get_name() + if bn == "mcl_buckets:bucket_water" or bn == "mcl_buckets:bucket_river_water" then + self.object:remove() + clicker:set_wielded_item("mcl_buckets:bucket_salmon") + awards.unlock(clicker:get_player_name(), "mcl:tacticalFishing") + end + end +} + +mcl_mobs.register_mob("mobs_mc:salmon", salmon) + + +--spawning TODO: in schools +local water = 0 +mcl_mobs:spawn_specific( +"mobs_mc:salmon", +"overworld", +"water", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +--spawn egg +mcl_mobs.register_egg("mobs_mc:salmon", S("Salmon"), "#a00f10", "#0e8474", 0) diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index d2d09be50..caa22205b 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -52,7 +52,7 @@ end local gotten_texture = { "blank.png", "mobs_mc_sheep.png" } --mcsheep -mcl_mobs:register_mob("mobs_mc:sheep", { +mcl_mobs.register_mob("mobs_mc:sheep", { description = S("Sheep"), type = "animal", spawn_class = "passive", @@ -61,15 +61,21 @@ mcl_mobs:register_mob("mobs_mc:sheep", { xp_min = 1, xp_max = 3, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45}, - + head_swivel = "head.control", + bone_eye_height = 3.3, + head_eye_height = 1.1, + horrizonatal_head_height=-.7, + curiosity = 6, + head_yaw="z", visual = "mesh", - visual_size = {x=3, y=3}, mesh = "mobs_mc_sheepfur.b3d", textures = { sheep_texture("unicolor_white") }, gotten_texture = gotten_texture, color = "unicolor_white", makes_footstep_sound = true, walk_velocity = 1, + runaway = true, + runaway_from = {"mobs_mc:wolf"}, drops = { {name = "mcl_mobitems:mutton", chance = 1, @@ -91,10 +97,14 @@ mcl_mobs:register_mob("mobs_mc:sheep", { distance = 16, }, animation = { - speed_normal = 25, run_speed = 65, - stand_start = 40, stand_end = 80, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 30, + run_start = 0, run_end = 40, run_speed = 40, + }, + child_animations = { + stand_start = 81, stand_end = 81, + walk_start = 81, walk_end = 121, walk_speed = 45, + run_start = 81, run_end = 121, run_speed = 60, }, follow = { "mcl_farming:wheat_item" }, view_range = 12, @@ -195,7 +205,7 @@ mcl_mobs:register_mob("mobs_mc:sheep", { on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() - if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end + if self:feed_tame(clicker, 1, true, false) then return end if mcl_mobs:protect(self, clicker) then return end if item:get_name() == "mcl_tools:shears" and not self.gotten and not self.child then @@ -257,7 +267,7 @@ mcl_mobs:register_mob("mobs_mc:sheep", { on_breed = function(parent1, parent2) -- Breed sheep and choose a fur color for the child. local pos = parent1.object:get_pos() - local child = mcl_mobs:spawn_child(pos, parent1.name) + local child = mcl_mobs.spawn_child(pos, parent1.name) if child then local ent_c = child:get_luaentity() local color1 = parent1.color @@ -346,7 +356,7 @@ mcl_mobs:spawn_specific( "Swampland", "Swampland_shore" }, -0, +9, minetest.LIGHT_MAX+1, 30, 15000, @@ -355,4 +365,4 @@ mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) +mcl_mobs.register_egg("mobs_mc:sheep", S("Sheep"), "#e7e7e7", "#ffb5b5", 0) diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index 5b3c4d282..46737e90f 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -9,9 +9,28 @@ local S = minetest.get_translator("mobs_mc") --################### SHULKER --################### +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,1,0), + vector.new(0,-1,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} +local function check_spot(pos) + pos = vector.offset(pos,0,0.5,0) + local n = minetest.get_node(pos) + if n.name ~="air" then return false end + for _,a in pairs(adjacents) do + local p = vector.add(pos,a) + local pn = minetest.get_node(p) + if minetest.get_item_group(pn.name,"solid") > 0 then return true end + end + return false +end +local pr = PseudoRandom(os.time()*(-334)) -- animation 45-80 is transition between passive and attack stance - -mcl_mobs:register_mob("mobs_mc:shulker", { +mcl_mobs.register_mob("mobs_mc:shulker", { description = S("Shulker"), type = "monster", spawn_class = "hostile", @@ -33,7 +52,10 @@ mcl_mobs:register_mob("mobs_mc:shulker", { -- TODO: Make shulker dye-able visual_size = {x=3, y=3}, walk_chance = 0, + knock_back = false, jump = false, + can_despawn = false, + fall_speed = 0, drops = { {name = "mcl_mobitems:shulker_shell", chance = 2, @@ -43,19 +65,94 @@ mcl_mobs:register_mob("mobs_mc:shulker", { looting_factor = 0.0625}, }, animation = { - stand_speed = 25, walk_speed = 25, run_speed = 50, punch_speed = 25, + stand_speed = 25, walk_speed = 0, run_speed = 50, punch_speed = 25, speed_normal = 25, speed_run = 50, - stand_start = 0, stand_end = 45, - walk_start = 0, walk_end = 45, - run_start = 0, run_end = 45, + stand_start = 0, stand_end = 25, + walk_start = 25, walk_end = 45, + run_start = 45, run_end = 85, punch_start = 80, punch_end = 100, }, view_range = 16, - fear_height = 4, + fear_height = 0, + noyaw = true, + do_custom = function(self,dtime) + local pos = self.object:get_pos() + if math.floor(self.object:get_yaw()) ~=0 then + self.object:set_yaw(0) + mcl_mobs:yaw(self, 0, 0, dtime) + end + if self.state == "walk" or self.state == "stand" then + self.state = "stand" + self:set_animation("stand") + end + if self.state == "attack" then + self:set_animation("punch") + end + self.path.way = false + self.look_at_players = false + if not check_spot(pos) then + self:teleport(nil) + end + end, + do_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + self:teleport(puncher) + end, + do_teleport = function(self, target) + if target ~= nil then + local target_pos = target:get_pos() + -- Find all solid nodes below air in a 10×10×10 cuboid centered on the target + local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(target_pos, 5), vector.add(target_pos, 5), {"group:solid", "group:cracky", "group:crumbly"}) + local telepos + if nodes ~= nil then + if #nodes > 0 then + -- Up to 64 attempts to teleport + for n=1, math.min(64, #nodes) do + local r = pr:next(1, #nodes) + local nodepos = nodes[r] + local tg = vector.offset(nodepos,0,1,0) + if check_spot(tg) then + telepos = tg + node_ok = true + end + end + if telepos then + self.object:set_pos(telepos) + end + end + end + else + local pos = self.object:get_pos() + -- Up to 8 top-level attempts to teleport + for n=1, 8 do + local node_ok = false + -- We need to add (or subtract) different random numbers to each vector component, so it couldn't be done with a nice single vector.add() or .subtract(): + local randomCube = vector.new( pos.x + 8*(pr:next(0,16)-8), pos.y + 8*(pr:next(0,16)-8), pos.z + 8*(pr:next(0,16)-8) ) + local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(randomCube, 4), vector.add(randomCube, 4), {"group:solid", "group:cracky", "group:crumbly"}) + if nodes ~= nil then + if #nodes > 0 then + -- Up to 8 low-level (in total up to 8*8 = 64) attempts to teleport + for n=1, math.min(8, #nodes) do + local r = pr:next(1, #nodes) + local nodepos = nodes[r] + local tg = vector.offset(nodepos,0,0.5,0) + if check_spot(tg) then + self.object:set_pos(tg) + node_ok = true + break + end + end + end + end + if node_ok then + break + end + end + end + end, }) -- bullet arrow (weapon) -mcl_mobs:register_arrow("mobs_mc:shulkerbullet", { +mcl_mobs.register_arrow("mobs_mc:shulkerbullet", { visual = "sprite", visual_size = {x = 0.25, y = 0.25}, textures = {"mobs_mc_shulkerbullet.png"}, @@ -80,8 +177,9 @@ mcl_mobs:register_arrow("mobs_mc:shulkerbullet", { }) -mcl_mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) +mcl_mobs.register_egg("mobs_mc:shulker", S("Shulker"), "#946694", "#4d3852", 0) +--[[ mcl_mobs:spawn_specific( "mobs_mc:shulker", "end", @@ -96,3 +194,4 @@ minetest.LIGHT_MAX+1, 2, mcl_vars.mg_end_min, mcl_vars.mg_end_max) +--]] diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index 857c9326e..e0bcc23aa 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -4,7 +4,7 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:silverfish", { +mcl_mobs.register_mob("mobs_mc:silverfish", { description = S("Silverfish"), type = "monster", spawn_class = "hostile", @@ -23,7 +23,7 @@ mcl_mobs:register_mob("mobs_mc:silverfish", { {"mobs_mc_silverfish.png"}, }, pathfinding = 1, - visual_size = {x=3, y=3}, + visual_size = {x = 3, y = 3}, sounds = { random = "mobs_mc_silverfish_idle", death = "mobs_mc_silverfish_death", @@ -45,96 +45,14 @@ mcl_mobs:register_mob("mobs_mc:silverfish", { }, replace_rate = 2, animation = { - speed_normal = 25, speed_run = 50, - stand_start = 0, stand_end = 20, - walk_start = 0, walk_end = 20, - run_start = 0, run_end = 20, + speed_normal = 25, speed_run = 50, + stand_start = 0, stand_end = 20, + walk_start = 0, walk_end = 20, + run_start = 0, run_end = 20, }, view_range = 16, attack_type = "dogfight", damage = 1, - reach = 1, }) -mcl_mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0) - --- Monster egg blocks (Minetest Game) -if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then - local spawn_silverfish = function(pos, oldnode, oldmetadata, digger) - if not minetest.is_creative_enabled(digger:get_player_name()) then - minetest.add_entity(pos, "mobs_mc:silverfish") - end - end - minetest.register_node("mobs_mc:monster_egg_stone", { - description = "Stone Monster Egg", - tiles = {"default_stone.png"}, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - is_ground_content = true, - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - minetest.register_node("mobs_mc:monster_egg_cobble", { - description = "Cobblestone Monster Egg", - tiles = {"default_cobble.png"}, - is_ground_content = false, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - minetest.register_node("mobs_mc:monster_egg_mossycobble", { - description = "Mossy Cobblestone Monster Egg", - tiles = {"default_mossycobble.png"}, - is_ground_content = false, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - minetest.register_node("mobs_mc:monster_egg_stonebrick", { - description = "Stone Brick Monster Egg", - paramtype2 = "facedir", - place_param2 = 0, - tiles = {"default_stone_brick.png"}, - is_ground_content = false, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - minetest.register_node("mobs_mc:monster_egg_stone_block", { - description = "Stone Block Monster Egg", - tiles = {"default_stone_block.png"}, - is_ground_content = false, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - -- Randomly spawn stone monster eggs in the world - local mg_name = minetest.get_mapgen_setting("mg_name") - local scarcity - if mg_name == "v6" then - scarcity = 28 * 28 * 28 - else - scarcity = 22 * 22 * 22 - end - minetest.register_ore({ - ore_type = "scatter", - ore = "mobs_mc:monster_egg_stone", - wherein = "default:stone", - clust_scarcity = scarcity, - clust_num_ores = 3, - clust_size = 2, - y_min = -31000, - y_max = 31000, - biomes = { "grassland" }, - }) - -end +mcl_mobs.register_egg("mobs_mc:silverfish", S("Silverfish"), "#6d6d6d", "#313131", 0) diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index aab719b1c..ca2fe25fa 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -25,13 +25,17 @@ local skeleton = { collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3}, pathfinding = 1, group_attack = true, + head_swivel = "Head_Control", + bone_eye_height = 2.38, + curiosity = 6, visual = "mesh", mesh = "mobs_mc_skeleton.b3d", + shooter_avoid_enemy = true, + strafes = true, textures = { { "mcl_bows_bow_0.png", -- bow "mobs_mc_skeleton.png", -- skeleton } }, - visual_size = {x=1, y=1}, makes_footstep_sound = true, textures = { { @@ -78,11 +82,31 @@ local skeleton = { run_speed = 30, shoot_start = 70, shoot_end = 90, + jockey_start = 172, + jockey_end = 172, die_start = 160, die_end = 170, die_speed = 15, die_loop = false, }, + jock = "mobs_mc:spider", + on_spawn = function(self) + minetest.after(1,function() + if self and self.object then + if math.random(100) == 1 or self.jockey == true then -- 1% like from MCwiki + self.jockey = true + local jock = minetest.add_entity(self.object:get_pos(), "mobs_mc:spider") + jock:get_luaentity().docile_by_day = false + self.object:set_attach(jock, "", vector.new(0,0,0), vector.new(0,0,0)) + end + self.jockey = false + return true + end + end) + end, + on_detach=function(self, parent) + self.jockey = false + end, ignited_by_sunlight = true, view_range = 16, fear_height = 4, @@ -90,6 +114,9 @@ local skeleton = { arrow = "mcl_bows:arrow_entity", shoot_arrow = function(self, pos, dir) if mod_bows then + if self.attack then + self.object:set_yaw(minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos()))) + end -- 2-4 damage per arrow local dmg = math.max(4, math.random(2, 8)) mcl_bows.shoot_arrow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) @@ -102,7 +129,7 @@ local skeleton = { harmed_by_heal = true, } -mcl_mobs:register_mob("mobs_mc:skeleton", skeleton) +mcl_mobs.register_mob("mobs_mc:skeleton", skeleton) --################### @@ -139,7 +166,7 @@ table.insert(stray.drops, { end, }) -mcl_mobs:register_mob("mobs_mc:stray", stray) +mcl_mobs.register_mob("mobs_mc:stray", stray) -- Overworld spawn mcl_mobs:spawn_specific( @@ -162,7 +189,6 @@ mcl_mobs:spawn_specific( "Plains", "Desert", "ColdTaiga", -"MushroomIsland", "IcePlainsSpikes", "SunflowerPlains", "IcePlains", @@ -189,7 +215,6 @@ mcl_mobs:spawn_specific( "ExtremeHills_beach", "ColdTaiga_beach", "Swampland_shore", -"MushroomIslandShore", "JungleM_shore", "Jungle_shore", "MesaPlateauFM_sandlevel", @@ -228,7 +253,6 @@ mcl_mobs:spawn_specific( "Forest_deep_ocean", "JungleM_deep_ocean", "FlowerForest_deep_ocean", -"MushroomIsland_ocean", "MegaTaiga_ocean", "StoneBeach_deep_ocean", "IcePlainsSpikes_deep_ocean", @@ -238,7 +262,6 @@ mcl_mobs:spawn_specific( "MesaBryce_deep_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills_ocean", -"MushroomIsland_deep_ocean", "Forest_ocean", "MegaTaiga_deep_ocean", "JungleEdge_ocean", @@ -264,7 +287,6 @@ mcl_mobs:spawn_specific( "RoofedForest_underground", "Jungle_underground", "Swampland_underground", -"MushroomIsland_underground", "BirchForest_underground", "Plains_underground", "MesaPlateauF_underground", @@ -302,10 +324,10 @@ mcl_mobs:spawn_specific( "nether", "ground", { -"Nether" +"SoulsandValley", }, 0, -7, +minetest.LIGHT_MAX+1, 30, 10000, 3, @@ -334,5 +356,6 @@ mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:skeleton", S("Skeleton"), "mobs_mc_spawn_icon_skeleton.png", 0) -mcl_mobs:register_egg("mobs_mc:stray", S("Stray"), "mobs_mc_spawn_icon_stray.png", 0) +mcl_mobs.register_egg("mobs_mc:skeleton", S("Skeleton"), "#c1c1c1", "#494949", 0) + +mcl_mobs.register_egg("mobs_mc:stray", S("Stray"), "#5f7476", "#dae8e7", 0) diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index 5e31453fa..94fa78120 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -9,7 +9,7 @@ local S = minetest.get_translator("mobs_mc") --################### WITHER SKELETON --################### -mcl_mobs:register_mob("mobs_mc:witherskeleton", { +mcl_mobs.register_mob("mobs_mc:witherskeleton", { description = S("Wither Skeleton"), type = "monster", spawn_class = "hostile", @@ -24,11 +24,14 @@ mcl_mobs:register_mob("mobs_mc:witherskeleton", { collisionbox = {-0.35, -0.01, -0.35, 0.35, 2.39, 0.35}, visual = "mesh", mesh = "mobs_mc_witherskeleton.b3d", + head_swivel = "head.control", + bone_eye_height = 2.38, + curiosity = 60, textures = { { "mobs_mc_empty.png", -- armor - "mobs_mc_wither_skeleton.png", -- wither skeleton "default_tool_stonesword.png", -- sword + "mobs_mc_wither_skeleton.png", -- wither skeleton } }, visual_size = {x=1.2, y=1.2}, @@ -96,12 +99,14 @@ mcl_mobs:register_mob("mobs_mc:witherskeleton", { }) --spawn +--[[] mcl_mobs:spawn_specific( "mobs_mc:witherskeleton", "nether", "ground", { -"Nether" +"Nether", +"SoulsandValley", }, 0, 7, @@ -110,6 +115,6 @@ mcl_mobs:spawn_specific( 5, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) - +--]] -- spawn eggs -mcl_mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) +mcl_mobs.register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "#141414", "#474d4d", 0) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 0c6c1ee1e..31ecad187 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -1,5 +1,8 @@ --License for code WTFPL and otherwise stated in readmes +-- FIXME: Slimes should spawn only in "slime chunks" which make up only +-- 10% of the map. +-- local S = minetest.get_translator("mobs_mc") -- Returns a function that spawns children in a circle around pos. @@ -7,46 +10,47 @@ local S = minetest.get_translator("mobs_mc") -- self: mob reference -- pos: position of "mother" mob -- child_mod: Mob to spawn --- children_count: Number of children to spawn -- spawn_distance: Spawn distance from "mother" mob -- eject_speed: Initial speed of child mob away from "mother" mob -local spawn_children_on_die = function(child_mob, children_count, spawn_distance, eject_speed) +local spawn_children_on_die = function(child_mob, spawn_distance, eject_speed) return function(self, pos) - local angle, posadd, newpos, dir + local posadd, newpos, dir if not eject_speed then eject_speed = 1 end local mndef = minetest.registered_nodes[minetest.get_node(pos).name] local mother_stuck = mndef and mndef.walkable - angle = math.random(0, math.pi*2) + local angle = math.random(0, math.pi*2) local children = {} - for i=1,children_count do - dir = {x=math.cos(angle),y=0,z=math.sin(angle)} - posadd = vector.multiply(vector.normalize(dir), spawn_distance) - newpos = vector.add(pos, posadd) + local spawn_count = math.random(2, 4) + for i = 1, spawn_count do + dir = vector.new(math.cos(angle), 0, math.sin(angle)) + posadd = vector.normalize(dir) * spawn_distance + newpos = pos + posadd -- If child would end up in a wall, use position of the "mother", unless -- the "mother" was stuck as well - local speed_penalty = 1 - 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 + if not mother_stuck then + local cndef = minetest.registered_nodes[minetest.get_node(newpos).name] + if cndef and cndef.walkable then + newpos = pos + eject_speed = eject_speed * 0.5 + end end local mob = minetest.add_entity(newpos, child_mob) - if (not mother_stuck) then - mob:set_velocity(vector.multiply(dir, eject_speed * speed_penalty)) + if not mother_stuck then + mob:set_velocity(dir * eject_speed) end mob:set_yaw(angle - math.pi/2) table.insert(children, mob) - angle = angle + (math.pi*2)/children_count + angle = angle + (math.pi*2) / spawn_count end -- If mother was murdered, children attack the killer after 1 second if self.state == "attack" then minetest.after(1.0, function(children, enemy) - for c=1, #children do - local child = children[c] - local le = child:get_luaentity() - if le ~= nil then + local le + for c = 1, #children do + le = children[c]:get_luaentity() + if le then le.state = "attack" le.attack = enemy end @@ -106,10 +110,10 @@ local slime_big = { jump_height = 5.2, fear_height = 0, spawn_small_alternative = "mobs_mc:slime_small", - on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5), + on_die = spawn_children_on_die("mobs_mc:slime_small", 1.0, 1.5), use_texture_alpha = true, } -mcl_mobs:register_mob("mobs_mc:slime_big", slime_big) +mcl_mobs.register_mob("mobs_mc:slime_big", slime_big) local slime_small = table.copy(slime_big) slime_small.sounds.base_pitch = 1.15 @@ -125,8 +129,8 @@ slime_small.walk_velocity = 1.3 slime_small.run_velocity = 1.3 slime_small.jump_height = 4.3 slime_small.spawn_small_alternative = "mobs_mc:slime_tiny" -slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 4, 0.6, 1.0) -mcl_mobs:register_mob("mobs_mc:slime_small", slime_small) +slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 0.6, 1.0) +mcl_mobs.register_mob("mobs_mc:slime_small", slime_small) local slime_tiny = table.copy(slime_big) slime_tiny.sounds.base_pitch = 1.3 @@ -151,142 +155,129 @@ slime_tiny.jump_height = 3 slime_tiny.spawn_small_alternative = nil slime_tiny.on_die = nil -mcl_mobs:register_mob("mobs_mc:slime_tiny", slime_tiny) +mcl_mobs.register_mob("mobs_mc:slime_tiny", slime_tiny) -local smin = mcl_vars.mg_overworld_min -local smax = mobs_mc.water_level - 23 +local water_level = mobs_mc.water_level + +local cave_biomes = { + "FlowerForest_underground", + "JungleEdge_underground", + "StoneBeach_underground", + "MesaBryce_underground", + "Mesa_underground", + "RoofedForest_underground", + "Jungle_underground", + "Swampland_underground", + "MushroomIsland_underground", + "BirchForest_underground", + "Plains_underground", + "MesaPlateauF_underground", + "ExtremeHills_underground", + "MegaSpruceTaiga_underground", + "BirchForestM_underground", + "SavannaM_underground", + "MesaPlateauFM_underground", + "Desert_underground", + "Savanna_underground", + "Forest_underground", + "SunflowerPlains_underground", + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "ExtremeHills+_underground", + "JungleM_underground", + "ExtremeHillsM_underground", + "JungleEdgeM_underground", + "MangroveSwamp_underground" +} + +local cave_min = mcl_vars.mg_overworld_min +local cave_max = water_level - 23 + +local swampy_biomes = {"Swampland", "MangroveSwamp"} +local swamp_light_max = 7 +local swamp_min = water_level +local swamp_max = water_level + 27 mcl_mobs:spawn_specific( "mobs_mc:slime_tiny", "overworld", "ground", -{ -"FlowerForest_underground", -"JungleEdge_underground", -"StoneBeach_underground", -"MesaBryce_underground", -"Mesa_underground", -"RoofedForest_underground", -"Jungle_underground", -"Swampland_underground", -"MushroomIsland_underground", -"BirchForest_underground", -"Plains_underground", -"MesaPlateauF_underground", -"ExtremeHills_underground", -"MegaSpruceTaiga_underground", -"BirchForestM_underground", -"SavannaM_underground", -"MesaPlateauFM_underground", -"Desert_underground", -"Savanna_underground", -"Forest_underground", -"SunflowerPlains_underground", -"ColdTaiga_underground", -"IcePlains_underground", -"IcePlainsSpikes_underground", -"MegaTaiga_underground", -"Taiga_underground", -"ExtremeHills+_underground", -"JungleM_underground", -"ExtremeHillsM_underground", -"JungleEdgeM_underground", -}, +cave_biomes, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, -smin, -smax) +cave_min, +cave_max) + +mcl_mobs:spawn_specific( +"mobs_mc:slime_tiny", +"overworld", +"ground", +swampy_biomes, +0, +swamp_light_max, +30, +12000, +4, +swamp_min, +swamp_max) mcl_mobs:spawn_specific( "mobs_mc:slime_small", "overworld", "ground", -{ -"FlowerForest_underground", -"JungleEdge_underground", -"StoneBeach_underground", -"MesaBryce_underground", -"Mesa_underground", -"RoofedForest_underground", -"Jungle_underground", -"Swampland_underground", -"MushroomIsland_underground", -"BirchForest_underground", -"Plains_underground", -"MesaPlateauF_underground", -"ExtremeHills_underground", -"MegaSpruceTaiga_underground", -"BirchForestM_underground", -"SavannaM_underground", -"MesaPlateauFM_underground", -"Desert_underground", -"Savanna_underground", -"Forest_underground", -"SunflowerPlains_underground", -"ColdTaiga_underground", -"IcePlains_underground", -"IcePlainsSpikes_underground", -"MegaTaiga_underground", -"Taiga_underground", -"ExtremeHills+_underground", -"JungleM_underground", -"ExtremeHillsM_underground", -"JungleEdgeM_underground", -}, +cave_biomes, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, -smin, -smax) +cave_min, +cave_max) + +mcl_mobs:spawn_specific( +"mobs_mc:slime_small", +"overworld", +"ground", +swampy_biomes, +0, +swamp_light_max, +30, +8500, +4, +swamp_min, +swamp_max) mcl_mobs:spawn_specific( "mobs_mc:slime_big", "overworld", "ground", -{ -"FlowerForest_underground", -"JungleEdge_underground", -"StoneBeach_underground", -"MesaBryce_underground", -"Mesa_underground", -"RoofedForest_underground", -"Jungle_underground", -"Swampland_underground", -"MushroomIsland_underground", -"BirchForest_underground", -"Plains_underground", -"MesaPlateauF_underground", -"ExtremeHills_underground", -"MegaSpruceTaiga_underground", -"BirchForestM_underground", -"SavannaM_underground", -"MesaPlateauFM_underground", -"Desert_underground", -"Savanna_underground", -"Forest_underground", -"SunflowerPlains_underground", -"ColdTaiga_underground", -"IcePlains_underground", -"IcePlainsSpikes_underground", -"MegaTaiga_underground", -"Taiga_underground", -"ExtremeHills+_underground", -"JungleM_underground", -"ExtremeHillsM_underground", -"JungleEdgeM_underground", -}, +cave_biomes, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, -smin, -smax) +cave_min, +cave_max) + +mcl_mobs:spawn_specific( +"mobs_mc:slime_big", +"overworld", +"ground", +swampy_biomes, +0, +swamp_light_max, +30, +10000, +4, +swamp_min, +swamp_max) -- Magma cube local magma_cube_big = { @@ -345,10 +336,10 @@ local magma_cube_big = { walk_chance = 0, fear_height = 0, spawn_small_alternative = "mobs_mc:magma_cube_small", - on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 3, 0.8, 1.5), + on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 0.8, 1.5), fire_resistant = true, } -mcl_mobs:register_mob("mobs_mc:magma_cube_big", magma_cube_big) +mcl_mobs.register_mob("mobs_mc:magma_cube_big", magma_cube_big) local magma_cube_small = table.copy(magma_cube_big) magma_cube_small.sounds.jump = "mobs_mc_magma_cube_small" @@ -368,8 +359,8 @@ magma_cube_small.damage = 4 magma_cube_small.reach = 2.75 magma_cube_small.armor = 66 magma_cube_small.spawn_small_alternative = "mobs_mc:magma_cube_tiny" -magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 4, 0.6, 1.0) -mcl_mobs:register_mob("mobs_mc:magma_cube_small", magma_cube_small) +magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 0.6, 1.0) +mcl_mobs.register_mob("mobs_mc:magma_cube_small", magma_cube_small) local magma_cube_tiny = table.copy(magma_cube_big) magma_cube_tiny.sounds.jump = "mobs_mc_magma_cube_small" @@ -391,63 +382,55 @@ magma_cube_tiny.drops = {} magma_cube_tiny.spawn_small_alternative = nil magma_cube_tiny.on_die = nil -mcl_mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) +mcl_mobs.register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) -local mmin = mcl_vars.mg_nether_min -local mmax = mcl_vars.mg_nether_max +local magma_cube_biomes = {"Nether", "BasaltDelta"} +local nether_min = mcl_vars.mg_nether_min +local nether_max = mcl_vars.mg_nether_max mcl_mobs:spawn_specific( "mobs_mc:magma_cube_tiny", "nether", "ground", -{ -"Nether" -}, +magma_cube_biomes, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, -mmin, -mmax) - +nether_min, +nether_max) mcl_mobs:spawn_specific( "mobs_mc:magma_cube_small", "nether", "ground", -{ -"Nether" -}, +magma_cube_biomes, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, -mmin, -mmax) +nether_min, +nether_max) mcl_mobs:spawn_specific( "mobs_mc:magma_cube_big", "nether", "ground", -{ -"Nether" -}, +magma_cube_biomes, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, -mmin, -mmax) - ---mcl_mobs:spawn_specific("mobs_mc:magma_cube_tiny", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) ---mcl_mobs:spawn_specific("mobs_mc:magma_cube_small", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) ---mcl_mobs:spawn_specific("mobs_mc:magma_cube_big", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) - +nether_min, +nether_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "mobs_mc_spawn_icon_magmacube.png") -mcl_mobs:register_egg("mobs_mc:slime_big", S("Slime"), "mobs_mc_spawn_icon_slime.png") +mcl_mobs.register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "#350000", "#fcfc00") + +mcl_mobs.register_egg("mobs_mc:slime_big", S("Slime"), "#52a03e", "#7ebf6d") + +-- FIXME: add spawn eggs for small and tiny slimes and magma cubes diff --git a/mods/ENTITIES/mobs_mc/snowman.lua b/mods/ENTITIES/mobs_mc/snowman.lua index 816c96947..f9f0043c2 100644 --- a/mods/ENTITIES/mobs_mc/snowman.lua +++ b/mods/ENTITIES/mobs_mc/snowman.lua @@ -20,7 +20,7 @@ local gotten_texture = { "blank.png", } -mcl_mobs:register_mob("mobs_mc:snowman", { +mcl_mobs.register_mob("mobs_mc:snowman", { description = S("Snow Golem"), type = "npc", spawn_class = "passive", @@ -196,4 +196,4 @@ function mobs_mc.check_snow_golem_summon(pos) end -- Spawn egg -mcl_mobs:register_egg("mobs_mc:snowman", S("Snow Golem"), "mobs_mc_spawn_icon_snowman.png", 0) +mcl_mobs.register_egg("mobs_mc:snowman", S("Snow Golem"), "#f2f2f2", "#fd8f47", 0) diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl1.ogg new file mode 100644 index 000000000..b3d9c5967 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl2.ogg new file mode 100644 index 000000000..11141f6cc Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl_hurt.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl_hurt.ogg new file mode 100644 index 000000000..dddf298b6 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl_hurt.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt1.ogg new file mode 100644 index 000000000..38ef59445 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt2.ogg new file mode 100644 index 000000000..b5766734e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow1.ogg new file mode 100644 index 000000000..37e7620ef Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow2.ogg new file mode 100644 index 000000000..0983ae4bb Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg index 9c56b0f65..beae2bf1f 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg index bafc77b7e..39939308c 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg index 9e5c79b6d..148fbd48b 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg index 5c9ee492b..a1c5c24dd 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 acb236445..5b436af59 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 1ef7a5227..50c4fa99a 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 index c2743fbcc..8054e1349 100644 Binary files a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.1.ogg new file mode 100644 index 000000000..b72b8b83f Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.2.ogg new file mode 100644 index 000000000..6de7085b0 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.1.ogg new file mode 100644 index 000000000..6c96f57b8 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.2.ogg similarity index 52% rename from mods/CORE/mcl_sounds/sounds/default_dig_choppy.ogg rename to mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.2.ogg index e2ecd8416..a7568a3d6 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.1.ogg similarity index 54% rename from mods/CORE/mcl_sounds/sounds/default_dig_cracky.ogg rename to mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.1.ogg index da1167916..f17771367 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.ogg and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.2.ogg new file mode 100644 index 000000000..763bf9132 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.3.ogg new file mode 100644 index 000000000..e012ed349 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.3.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.4.ogg new file mode 100644 index 000000000..51d808f52 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.4.ogg differ diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 0fc16928e..403edba6d 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -11,6 +11,23 @@ local S = minetest.get_translator("mobs_mc") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture) +minetest.register_entity("mobs_mc:spider_eyes", { + pointable = false, + visual = "mesh", + mesh = "mobs_mc_spider.b3d", + visual_size = {x=1.01/3, y=1.01/3}, + textures = { + "mobs_mc_spider_eyes.png", + }, + on_step = function(self) + if self and self.object then + if not self.object:get_attach() then + self.object:remove() + end + end + end, + glow = 50, +}) local spider = { description = S("Spider"), @@ -27,13 +44,38 @@ local spider = { xp_min = 5, xp_max = 5, armor = {fleshy = 100, arthropod = 100}, + on_spawn = function(self) + self.object:set_properties({visual_size={x=1,y=1}}) + local spider_eyes=false + for n = 1, #self.object:get_children() do + local obj = self.object:get_children()[n] + if obj:get_luaentity() and self.object:get_luaentity().name == "mobs_mc:spider_eyes" then + spider_eyes = true + end + end + if not spider_eyes then + minetest.add_entity(self.object:get_pos(), "mobs_mc:spider_eyes"):set_attach(self.object, "body.head", vector.new(0,-0.98,2), vector.new(90,180,180)) + end + end, + on_die=function(self) + if self.object:get_children() and self.object:get_children()[1] then + self.object:get_children()[1]:set_detach() + end + end, + detach_child=function(self, child) + child:get_luaentity().jockey = false + end, + head_swivel = "Head_Control", + bone_eye_height = 1, + curiosity = 10, + head_yaw="z", collisionbox = {-0.7, -0.01, -0.7, 0.7, 0.89, 0.7}, visual = "mesh", mesh = "mobs_mc_spider.b3d", textures = { - {"mobs_mc_spider.png^(mobs_mc_spider_eyes.png^[makealpha:0,0,0)"}, + {"mobs_mc_spider.png"}, }, - visual_size = {x=3, y=3}, + visual_size = {x=1, y=1}, makes_footstep_sound = false, sounds = { random = "mobs_mc_spider_random", @@ -69,7 +111,7 @@ local spider = { run_end = 20, }, } -mcl_mobs:register_mob("mobs_mc:spider", spider) +mcl_mobs.register_mob("mobs_mc:spider", spider) -- Cave spider local cave_spider = table.copy(spider) @@ -80,13 +122,26 @@ cave_spider.textures = { {"mobs_mc_cave_spider.png^(mobs_mc_spider_eyes.png^[mak cave_spider.damage = 3 -- damage increased to undo non-existing poison cave_spider.hp_min = 1 cave_spider.hp_max = 12 -cave_spider.collisionbox = {-0.35, -0.01, -0.35, 0.35, 0.49, 0.35} -cave_spider.visual_size = {x=1.66666, y=1.5} +cave_spider.collisionbox = {-0.35, -0.01, -0.35, 0.35, 0.46, 0.35} +cave_spider.visual_size = {x=0.55,y=0.5} +cave_spider.on_spawn = function(self) + self.object:set_properties({visual_size={x=0.55,y=0.5}}) + local spider_eyes=false + for n = 1, #self.object:get_children() do + local obj = self.object:get_children()[n] + if obj:get_luaentity() and self.object:get_luaentity().name == "mobs_mc:spider_eyes" then + spider_eyes = true + end + end + if not spider_eyes then + minetest.add_entity(self.object:get_pos(), "mobs_mc:spider_eyes"):set_attach(self.object, "body.head", vector.new(0,-0.98,2), vector.new(90,180,180)) + end +end cave_spider.walk_velocity = 1.3 cave_spider.run_velocity = 3.2 cave_spider.sounds = table.copy(spider.sounds) cave_spider.sounds.base_pitch = 1.25 -mcl_mobs:register_mob("mobs_mc:cave_spider", cave_spider) +mcl_mobs.register_mob("mobs_mc:cave_spider", cave_spider) mcl_mobs:spawn_specific( @@ -109,7 +164,6 @@ mcl_mobs:spawn_specific( "Plains", "Desert", "ColdTaiga", -"MushroomIsland", "IcePlainsSpikes", "SunflowerPlains", "IcePlains", @@ -136,7 +190,6 @@ mcl_mobs:spawn_specific( "ExtremeHills_beach", "ColdTaiga_beach", "Swampland_shore", -"MushroomIslandShore", "JungleM_shore", "Jungle_shore", "MesaPlateauFM_sandlevel", @@ -175,7 +228,6 @@ mcl_mobs:spawn_specific( "Forest_deep_ocean", "JungleM_deep_ocean", "FlowerForest_deep_ocean", -"MushroomIsland_ocean", "MegaTaiga_ocean", "StoneBeach_deep_ocean", "IcePlainsSpikes_deep_ocean", @@ -185,7 +237,6 @@ mcl_mobs:spawn_specific( "MesaBryce_deep_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills_ocean", -"MushroomIsland_deep_ocean", "Forest_ocean", "MegaTaiga_deep_ocean", "JungleEdge_ocean", @@ -211,7 +262,6 @@ mcl_mobs:spawn_specific( "RoofedForest_underground", "Jungle_underground", "Swampland_underground", -"MushroomIsland_underground", "BirchForest_underground", "Plains_underground", "MesaPlateauF_underground", @@ -243,5 +293,5 @@ mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0) -mcl_mobs:register_egg("mobs_mc:cave_spider", S("Cave Spider"), "mobs_mc_spawn_icon_cave_spider.png", 0) +mcl_mobs.register_egg("mobs_mc:spider", S("Spider"), "#342d26", "#a80e0e", 0) +mcl_mobs.register_egg("mobs_mc:cave_spider", S("Cave Spider"), "#0c424e", "#a80e0e", 0) diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index 86b80976e..a692fd8d4 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -6,7 +6,7 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:squid", { +mcl_mobs.register_mob("mobs_mc:squid", { description = S("Squid"), type = "animal", spawn_class = "water", @@ -40,7 +40,7 @@ mcl_mobs:register_mob("mobs_mc:squid", { run_end = 60, }, drops = { - {name = "mcl_dye:black", + {name = "mcl_mobitems:ink_sac", chance = 1, min = 1, max = 3, @@ -217,4 +217,4 @@ water-16, water+1) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0) +mcl_mobs.register_egg("mobs_mc:squid", S("Squid"), "#223b4d", "#708999", 0) diff --git a/mods/ENTITIES/mobs_mc/strider.lua b/mods/ENTITIES/mobs_mc/strider.lua new file mode 100644 index 000000000..a49845f7e --- /dev/null +++ b/mods/ENTITIES/mobs_mc/strider.lua @@ -0,0 +1,248 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local S = minetest.get_translator("mobs_mc") + +--################### +--################### STRIDER +--################### + + +local strider = { + type = "animal", + passive = true, + spawn_class = "passive", + hp_min = 20, + hp_max = 20, + xp_min = 9, + xp_max = 9, + armor = {fleshy = 90}, + attack_type = "dogfight", + damage = 2, + reach = 2, + collisionbox = {-.6, -0.01, -.6, .6, 1.94, .6}, + visual = "mesh", + mesh = "extra_mobs_strider.b3d", + textures = { { + "extra_mobs_strider.png", + } }, + visual_size = {x=3, y=3}, + sounds = { + }, + jump = true, + makes_footstep_sound = true, + walk_velocity = 2, + run_velocity = 4, + runaway = true, + drops = { + {name = "mcl_mobsitems:string", + chance = 1, + min = 2, + max = 5,}, + }, + animation = { + stand_speed = 15, + walk_speed = 15, + run_speed = 30, + stand_start = 5, + stand_end = 5, + walk_start = 1, + walk_end = 20, + }, + lava_damage = 0, + fire_damage = 0, + light_damage = 0, + water_damage = 5, + fear_height = 4, + view_range = 16, + fire_resistant = true, + floats_on_lava = 1, + floats = 0, + can_spawn = function(pos) + local l = minetest.find_node_near(pos,2,{"mcl_nether:nether_lava_source","mcl_nether:nether_lava_flowing"}) + return l ~= nil + end, + do_custom = function(self, dtime) + + if minetest.find_node_near(self.object:get_pos(), 2, {"mcl_core:lava_source","mcl_core:lava_flowing","mcl_nether:nether_lava_source","mcl_nether:nether_lava_flowing"}) then + self.walk_velocity = 2 + self.run_velocity = 4 + self.base_texture[1] = "extra_mobs_strider.png" + self.shaking = false + else + self.base_texture[1] = "extra_mobs_strider_cold.png" + self.walk_velocity = .5 + self.run_velocity = 1 + self.shaking = true + end + + self.object:set_properties({textures=self.base_texture, shaking=self.shaking, run_velocity=self.run_velocity, walk_velocity=self.walk_velocity}) + + -- set needed values if not already present + if not self.v2 then + self.v2 = 0 + self.max_speed_forward = 8 + self.max_speed_reverse = 4 + self.accel = 2 + self.terrain_type = 3 + self.driver_attach_at = {x = 0, y = 5.5, z = -1.75} + self.driver_eye_offset = {x = 0, y = 10, z = 0} + self.driver_scale = {x = 1/self.visual_size.x, y = 1/self.visual_size.y} + end + + -- if driver present allow control of horse + if self.driver then + local pos = self.object:get_pos() + local v = self.object:get_velocity() + self.object:set_velocity(vector.new(v.x,0,v.z)) + mcl_mobs.drive(self, "walk", "stand", false, dtime) + local l = minetest.find_node_near(pos,2,{"group:lava"}) + if l then self.object:set_pos(vector.new(pos.x,l.y+0.5,pos.z)) end + return false -- skip rest of mob functions + end + + return true + end, + + on_die = function(self, pos) + + -- drop saddle when horse is killed while riding + -- also detach from horse properly + if self.driver then + mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1}) + end + end, + + on_rightclick = function(self, clicker) + if not clicker or not clicker:is_player() then + return + end + + local wielditem = clicker:get_wielded_item() + + if wielditem:get_name() ~= "mcl_crimson:warped_fungus" then + if self:feed_tame(clicker, 1, true, true) then return end + end + + if self.child then + return + end + + local item = clicker:get_wielded_item() + if item:get_name() == "mcl_mobitems:saddle" and self.saddle ~= "yes" then + self.base_texture = { + "extra_mobs_strider.png", + "mobs_mc_pig_saddle.png", -- saddle + } + self.object:set_properties({ + textures = self.base_texture + }) + self.saddle = "yes" + self.tamed = true + self.drops = { + {name = "mcl_mobitems:string", + chance = 1, + min = 1, + max = 3,}, + {name = "mcl_mobitems:saddle", + chance = 1, + min = 1, + max = 1,}, + } + if not minetest.is_creative_enabled(clicker:get_player_name()) then + wielditem:take_item(1) + clicker:get_inventory():set_stack("main", clicker:get_wield_index(), wielditem) + end + minetest.sound_play({name = "mcl_armor_equip_leather"}, {gain=0.5, max_hear_distance=8, pos=self.object:get_pos()}, true) + return + end + + -- Mount or detach player + local name = clicker:get_player_name() + if self.driver and clicker == self.driver then + -- Detach if already attached + mcl_mobs.detach(clicker, {x=1, y=0, z=0}) + return + + elseif not self.driver and self.saddle == "yes" and wielditem:get_name() == "mcl_mobitems:warped_fungus_on_a_stick" then + -- Ride pig if it has a saddle and player uses a carrot on a stick + + mcl_mobs.attach(self, clicker) + + if not minetest.is_creative_enabled(clicker:get_player_name()) then + + local inv = self.driver:get_inventory() + -- 26 uses + if wielditem:get_wear() > 63000 then + -- Break carrot on a stick + local def = wielditem:get_definition() + if def.sounds and def.sounds.breaks then + minetest.sound_play(def.sounds.breaks, {pos = clicker:get_pos(), max_hear_distance = 8, gain = 0.5}, true) + end + wielditem = {name = mobs_mc.items.fishing_rod, count = 1} + else + wielditem:add_wear(2521) + end + inv:set_stack("main",self.driver:get_wield_index(), wielditem) + end + return + end + end, +} + +mcl_mobs.register_mob("mobs_mc:strider", strider) + +-- Baby strider. + +local baby_strider = table.copy(strider) +baby_strider.collisionbox = {-.3, -0.01, -.3, .3, 0.94, .3} +baby_strider.xp_min = 13 +baby_strider.xp_max = 13 +textures = { { + "extra_mobs_strider.png", + "extra_mobs_trans.png", +} } +baby_strider.walk_velocity = 1.2 +baby_strider.run_velocity = 2.4 +baby_strider.child = 1 + +mcl_mobs.register_mob("mobs_mc:baby_strider", baby_strider) + +-- Regular spawning in the Nether + +mcl_mobs:spawn_setup({ + name = "mobs_mc:strider", + type_of_spawning = "lava", + dimension = "nether", + biomes = { + "Nether", + "BasaltDelta", + "WarpedForest", + "CrimsonForest", + "SoulsandValley" + }, + min_height = mcl_vars.mg_nether_min, + max_height = mcl_vars.mg_nether_max, + chance = 2000, +}) + +mcl_mobs:spawn_setup({ + name = "mobs_mc:baby_strider", + type_of_spawning = "lava", + dimension = "nether", + biomes = { + "Nether", + "BasaltDelta", + "WarpedForest", + "CrimsonForest", + "SoulsandValley" + }, + min_height = mcl_vars.mg_nether_min, + max_height = mcl_vars.mg_nether_max, + chance = 100, +}) + +-- spawn eggs +mcl_mobs.register_egg("mobs_mc:strider", S("Strider"), "#000000", "#FF0000", 0) diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_cod.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_cod.png new file mode 100644 index 000000000..0da300c6e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_cod.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_dolphin.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_dolphin.png new file mode 100644 index 000000000..6b8a40bf2 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_dolphin.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid.png new file mode 100644 index 000000000..ccbdb9707 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint1.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint1.png new file mode 100644 index 000000000..2ed9a013c Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint1.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint2.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint2.png new file mode 100644 index 000000000..deed54099 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint2.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint3.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint3.png new file mode 100644 index 000000000..e0fe8919a Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint3.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint4.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint4.png new file mode 100644 index 000000000..966589fa8 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_glow_squid_glint4.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_hoglin.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_hoglin.png new file mode 100644 index 000000000..c85d6a25b Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_hoglin.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_piglin.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_piglin.png new file mode 100644 index 000000000..c38606550 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_piglin.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_piglin_brute.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_piglin_brute.png new file mode 100644 index 000000000..4a757e61e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_piglin_brute.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_salmon.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_salmon.png new file mode 100644 index 000000000..5ce4d6cc3 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_salmon.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_strider.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_strider.png new file mode 100644 index 000000000..5039afe36 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_strider.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_strider_cold.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_strider_cold.png new file mode 100644 index 000000000..ecf6bbb90 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_strider_cold.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_a.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_a.png new file mode 100644 index 000000000..3f9abe3dc Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_a.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_b.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_b.png new file mode 100644 index 000000000..587ada083 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_b.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_1.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_1.png new file mode 100644 index 000000000..89787fcce Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_1.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_2.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_2.png new file mode 100644 index 000000000..1403e277c Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_2.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_3.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_3.png new file mode 100644 index 000000000..a1a7cfd88 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_3.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_4.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_4.png new file mode 100644 index 000000000..417ba86cf Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_4.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_5.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_5.png new file mode 100644 index 000000000..63ec19567 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_5.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_6.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_6.png new file mode 100644 index 000000000..0b2ce4f71 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_a_6.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_1.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_1.png new file mode 100644 index 000000000..f33aaa803 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_1.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_2.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_2.png new file mode 100644 index 000000000..1834146bb Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_2.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_3.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_3.png new file mode 100644 index 000000000..4878e813a Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_3.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_4.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_4.png new file mode 100644 index 000000000..9a4315be6 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_4.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_5.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_5.png new file mode 100644 index 000000000..6288da9a5 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_5.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_6.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_6.png new file mode 100644 index 000000000..ea82ed883 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_tropical_fish_pattern_b_6.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_zoglin.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_zoglin.png new file mode 100644 index 000000000..6f5367550 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_zoglin.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/extra_mobs_zombified_piglin.png b/mods/ENTITIES/mobs_mc/textures/extra_mobs_zombified_piglin.png new file mode 100644 index 000000000..358c22bc3 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/extra_mobs_zombified_piglin.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_chicken_egg.png b/mods/ENTITIES/mobs_mc/textures/mobs_chicken_egg.png index 9c6545452..346dac7ab 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_chicken_egg.png and b/mods/ENTITIES/mobs_mc/textures/mobs_chicken_egg.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_TEMP_wither_projectile.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_TEMP_wither_projectile.png index df8b24c12..d9ddd9bba 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_TEMP_wither_projectile.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_TEMP_wither_projectile.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_arrow_particle.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_arrow_particle.png index 1d0cd9b1c..b7105877c 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_arrow_particle.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_arrow_particle.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_black.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_black.png new file mode 100644 index 000000000..8f13938f8 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_black.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_brown.png new file mode 100644 index 000000000..b90ba3c88 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_brown.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_green.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_green.png new file mode 100644 index 000000000..4dca4fdf5 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_green.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_pink.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_pink.png new file mode 100644 index 000000000..193a8e087 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_pink.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_purple.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_purple.png new file mode 100644 index 000000000..bd7f67c6f Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_purple.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_white.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_white.png new file mode 100644 index 000000000..15b3ba43d Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_white.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_yellow.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_yellow.png new file mode 100644 index 000000000..6b3fd6157 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_axolotl_yellow.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_black.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_black.png index 8d1322565..02e84f3db 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_black.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_black.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_chicken.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_chicken.png index b9d69278e..a9e516c6b 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_chicken.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_chicken.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_creeper_charge.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_creeper_charge.png index a5e8ab443..f80392bc0 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_creeper_charge.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_creeper_charge.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_diamond.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_diamond.png new file mode 100644 index 000000000..32f0c05f3 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_diamond.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_donkey.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_donkey.png index e3f04ffd3..549d4d5ce 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_donkey.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_donkey.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon_fireball.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon_fireball.png index 69e643b13..77a282727 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon_fireball.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon_fireball.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_emerald.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_emerald.png new file mode 100644 index 000000000..bdb1ef667 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_emerald.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_empty.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_empty.png index 809f22b69..4c3d3ea87 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_empty.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_empty.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_block.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_block.png deleted file mode 100644 index 97d949d8a..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_block.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_cactus_background.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_cactus_background.png index e2f7ad9a2..576684878 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_cactus_background.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_cactus_background.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_evoker.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_evoker.png index eec707c5c..af793b59b 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_evoker.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_evoker.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast.png index dc2addc1d..d3c14bbcc 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast_firing.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast_firing.png index 3e5b41c32..9516fa0ed 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast_firing.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast_firing.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_gold.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_gold.png new file mode 100644 index 000000000..e136dad54 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_gold.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_black.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_black.png index 91159c9d8..a1b3f7aae 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_black.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_black.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_brown.png index 2d1733af9..9024f9564 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_brown.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_brown.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_chestnut.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_chestnut.png index ef051a009..1a39e0bbf 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_chestnut.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_chestnut.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_darkbrown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_darkbrown.png index 5fa6dd45a..8298d8047 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_darkbrown.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_darkbrown.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_gray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_gray.png index fb6c1c6b6..733ca4e2a 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_gray.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_gray.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png index 615eb67a8..922090afc 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_white.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_white.png index 264fffd26..dc8df13c6 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_white.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_white.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png new file mode 100644 index 000000000..b6f3522f3 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_illusionist.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_illusionist.png index e6a0f86a6..f6be747d4 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_illusionist.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_illusionist.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_iron.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_iron.png new file mode 100644 index 000000000..8573938f3 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_iron.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama.png index 4a08544cf..2fba8db66 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_brown.png index 6cf366deb..b0e830f94 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_brown.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_brown.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_creamy.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_creamy.png index e1df4612f..fae25c341 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_creamy.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_creamy.png 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 index 9a06b5871..e380a6bd6 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_black.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_black.png 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 index 74db6eb32..b15cdf11f 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_blue.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_blue.png 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 index 3ed90ca0d..b879f18e2 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_brown.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_brown.png 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 index b66df4571..c41324867 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_cyan.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_cyan.png 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 index b74dd86af..d850c7ec8 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_gray.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_gray.png 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 index e956a3023..c0ffc074d 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_green.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_green.png 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 index 6c3b2a795..025c923be 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_blue.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_blue.png 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 index 33b9376dd..715b954d4 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_gray.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_light_gray.png 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 index f201bc4fa..4ac62011b 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_lime.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_lime.png 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 index d05057fbb..cba899ca1 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_magenta.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_magenta.png 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 index a261eada2..42fe00c8a 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_orange.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_orange.png 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 index 108aab155..fe5296db4 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_pink.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_pink.png 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 index 3b3e472ce..ede94f98e 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_purple.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_purple.png 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 index 18b9fbcff..09b419194 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_red.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_red.png 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 index b70b55419..94852fac4 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_white.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_white.png 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 index 50962e99d..e082fe7b5 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_yellow.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_decor_yellow.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_spit.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_spit.png new file mode 100644 index 000000000..9433d2f86 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_spit.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom_brown.png index 115416a53..c274c2fa6 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom_brown.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom_brown.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mule.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mule.png index 328018f5d..98ab5d45f 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mule.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mule.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_brown.png index fac0f56ef..84e8c89b5 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_brown.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_brown.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_red.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_red.png index 8c22bd62a..391392f20 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_red.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_red.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_blue.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_blue.png index 9181de260..e8b44a9ef 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_blue.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_blue.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_green.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_green.png index 152acb8f4..63cdc02af 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_green.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_green.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_grey.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_grey.png index ce723561c..d621282cc 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_grey.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_grey.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_red_blue.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_red_blue.png index 2f14ef1a5..2d61a8371 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_red_blue.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_red_blue.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_yellow_blue.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_yellow_blue.png index f35adfd02..bc6ab8525 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_yellow_blue.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_yellow_blue.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_pillager.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_pillager.png new file mode 100644 index 000000000..1fe768ac1 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_pillager.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep.png index 13496a3c5..6fdd83197 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep_fur.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep_fur.png index fa447031d..1763f4f6f 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep_fur.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep_fur.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_silverfish.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_silverfish.png index 956af9ce7..d1af41064 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_silverfish.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_silverfish.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png index 5a30e16fd..eb45eec10 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_bat.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_bat.png index 9720b7679..820b58dac 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_bat.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_bat.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_blaze.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_blaze.png index aaa8de0ae..94a5014fb 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_blaze.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_blaze.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cat.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cat.png index 3f975c19d..123ffc337 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cat.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cat.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cave_spider.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cave_spider.png index dea6dc92b..d5f453de8 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cave_spider.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cave_spider.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_chicken.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_chicken.png index 58fc64136..70717aed3 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_chicken.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_chicken.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cod.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cod.png new file mode 100644 index 000000000..e82b889d2 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cod.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cow.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cow.png index ac3e7a2d1..619547a4b 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cow.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cow.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_creeper.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_creeper.png index 99b766881..51477b201 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_creeper.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_creeper.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_donkey.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_donkey.png index 10bd751fb..a3ed2c9b1 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_donkey.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_donkey.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_dragon.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_dragon.png index 5519d4de7..7f7558241 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_dragon.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_dragon.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_enderman.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_enderman.png index 36983ce33..da9ad3555 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_enderman.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_enderman.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_endermite.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_endermite.png index f2d3b4065..8e0fdba94 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_endermite.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_endermite.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_evoker.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_evoker.png index c6aec4f43..01908a557 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_evoker.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_evoker.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_ghast.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_ghast.png index 3c0422cae..ed3370dec 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_ghast.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_ghast.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian.png index 10bcbcffb..019a9dee8 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian_elder.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian_elder.png index fac4ac819..a524502b0 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian_elder.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian_elder.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse.png index 38d88e8b6..17b2460f7 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_skeleton.png index bea0c518d..0f11de7c9 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_skeleton.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_skeleton.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_zombie.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_zombie.png index ab981289b..9c7db2249 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_zombie.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_zombie.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_husk.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_husk.png index 48945d89e..7d1b75769 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_husk.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_husk.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_illusioner.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_illusioner.png index 7b9dc99e3..953e90f44 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_illusioner.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_illusioner.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_iron_golem.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_iron_golem.png index 6de2cccb9..f0b1cf745 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_iron_golem.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_iron_golem.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_killer_bunny.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_killer_bunny.png new file mode 100644 index 000000000..51dbdaa7c Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_killer_bunny.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_llama.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_llama.png index f3daba200..752c9a570 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_llama.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_llama.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_magmacube.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_magmacube.png index 9c38e1b38..5d6d58d3f 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_magmacube.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_magmacube.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mooshroom.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mooshroom.png index 552b70389..2fc8300f6 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mooshroom.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mooshroom.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mule.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mule.png index 741df99f3..4086a361d 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mule.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mule.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_parrot.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_parrot.png index b52c390f7..a9a2895f8 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_parrot.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_parrot.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_pig.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_pig.png index 692d1714d..c431de73b 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_pig.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_pig.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_polarbear.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_polarbear.png index 7570cacc8..b287317d3 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_polarbear.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_polarbear.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit.png index 1c77e4199..9382accbf 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_salmon.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_salmon.png new file mode 100644 index 000000000..a4b80e757 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_salmon.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_sheep.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_sheep.png index 72ddb1702..26c8c81f6 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_sheep.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_sheep.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_shulker.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_shulker.png index 491f840d6..be6a00de9 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_shulker.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_shulker.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_silverfish.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_silverfish.png index d0bca5664..5561016fc 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_silverfish.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_silverfish.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_skeleton.png index d0225da21..ad6d9f228 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_skeleton.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_skeleton.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_slime.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_slime.png index 0366bd267..6f2e39702 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_slime.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_slime.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_snowman.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_snowman.png index f518f0cfe..d14af8fa1 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_snowman.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_snowman.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_spider.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_spider.png index 7877d0bb0..f89a6ade2 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_spider.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_spider.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_squid.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_squid.png index 40fa44080..73e475f46 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_squid.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_squid.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_stray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_stray.png index 67e5bbe3c..9b8dafa93 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_stray.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_stray.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vex.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vex.png index 93bfa7b92..8d01c05c2 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vex.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vex.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_villager.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_villager.png index cf8ce28cc..6b0d0c083 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_villager.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_villager.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vindicator.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vindicator.png index 24316e0f9..a8b208c83 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vindicator.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vindicator.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witch.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witch.png index cd1db520f..2b3cf8d87 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witch.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witch.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wither.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wither.png index 5ce5c44bf..c1f01c3de 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wither.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wither.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witherskeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witherskeleton.png index 9055548bb..75694303d 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witherskeleton.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witherskeleton.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wolf.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wolf.png index 7098285b6..a42bd0925 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wolf.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wolf.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie.png index 0b4da4163..3d16dbb93 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_pigman.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_pigman.png index ba27c85d3..461ffcfa7 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_pigman.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_pigman.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_villager.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_villager.png index 9430af7ef..f092e6f5f 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_villager.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_villager.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stone.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_stone.png new file mode 100644 index 000000000..3e4e4485c Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_stone.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray.png index 21f15614d..94c9f3c47 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray_overlay.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray_overlay.png index b4b47a9fb..881bfbda5 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray_overlay.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray_overlay.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_bg.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_bg.png index e271ddb24..05b8f5741 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_bg.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_bg.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_mason.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_mason.png new file mode 100644 index 000000000..a09e79b2a Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_mason.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_vindicator.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_vindicator.png index 512eae60a..c47a157a5 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_vindicator.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_vindicator.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_witch.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_witch.png index acdf2ff93..abae57aa4 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_witch.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_witch.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither.png index d0b299ee9..3895ded6e 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_half_health.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_half_health.png index f6353400c..edce2e987 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_half_health.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_half_health.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_skeleton.png index d0d6afe77..3cd240e2a 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_skeleton.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_skeleton.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png index fc09566a5..cf9671f70 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png index 7dde7e5a8..50d764502 100644 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png and b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/spawn_egg.png b/mods/ENTITIES/mobs_mc/textures/spawn_egg.png new file mode 100644 index 000000000..aa9045e67 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/spawn_egg.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/spawn_egg_overlay.png b/mods/ENTITIES/mobs_mc/textures/spawn_egg_overlay.png new file mode 100644 index 000000000..fd0aa48a1 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/textures/spawn_egg_overlay.png differ diff --git a/mods/ENTITIES/mobs_mc/tropical_fish.lua b/mods/ENTITIES/mobs_mc/tropical_fish.lua new file mode 100644 index 000000000..bb9b63f64 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/tropical_fish.lua @@ -0,0 +1,192 @@ +--Tropical Fish by cora +local S = minetest.get_translator(minetest.get_current_modname()) + +local base_colors = { + "#FF3855", + "#FFF700", + "#A7F432", + "#FF5470", + "#5DADEC", + "#A83731", + "#87FF2A", + "#E936A7", + "#FF007C", + "#9C51B6", + "#66FF66", + "#AAF0D1", + "#50BFE6", + "#FFFF66", + "#FF9966", + "#FF00CC", +} +local pattern_colors = { + "#FF3855", + "#FFF700", + "#A7F432", + "#FF5470", + "#5DADEC", + "#A83731", + "#87FF2A", + "#E936A7", + "#FF007C", + "#9C51B6", + "#66FF66", + "#AAF0D1", + "#50BFE6", + "#FFFF66", + "#FF9966", + "#FF00CC", +} + +local function set_textures(self) + if not self._type then + self._type = "a" + if math.random(2) == 1 then + self.object:set_properties({}) + self._type="b" + end + self._base_color = base_colors[math.random(#base_colors)] + self._pattern_color = pattern_colors[math.random(#pattern_colors)] + self._pattern = "extra_mobs_tropical_fish_pattern_"..self._type.."_"..math.random(6)..".png" + end + self.object:set_properties({ + textures = { + "(extra_mobs_tropical_fish_"..self._type..".png^[colorize:"..self._base_color..":127)^("..self._pattern.."^[colorize:"..self._pattern_color..")", + }, + mesh="extra_mobs_tropical_fish_"..self._type..".b3d" + }) +end + +local tropical_fish = { + type = "animal", + spawn_class = "water", + can_despawn = true, + passive = true, + hp_min = 3, + hp_max = 3, + xp_min = 1, + xp_max = 3, + armor = 100, + spawn_in_group = 9, + tilt_swim = true, + collisionbox = {-0.2, 0.0, -0.2, 0.2, 0.1, 0.2}, + visual = "mesh", + mesh = "extra_mobs_tropical_fish_a.b3d", + textures = { "extra_mobs_tropical_fish_a.png" }, -- to be populated on_spawn + sounds = {}, + animation = { + stand_start = 0, + stand_end = 20, + walk_start = 20, + walk_end = 40, + run_start = 20, + run_end = 40, + }, + drops = { + {name = "mcl_fishing:clownfish_raw", + chance = 1, + min = 1, + max = 1,}, + {name = "mcl_bone_meal:bone_meal", + chance = 20, + min = 1, + max = 1,}, + }, + visual_size = {x=3, y=3}, + makes_footstep_sound = false, + swim = true, + fly = true, + fly_in = "mcl_core:water_source", + breathes_in_water = true, + jump = false, + view_range = 16, + runaway = true, + fear_height = 4, + on_rightclick = function(self, clicker) + local bn = clicker:get_wielded_item():get_name() + if bn == "mcl_buckets:bucket_water" or bn == "mcl_buckets:bucket_river_water" then + if clicker:set_wielded_item("mcl_buckets:bucket_tropical_fish") then + local it = clicker:get_wielded_item() + local m = it:get_meta() + m:set_string("properties",minetest.serialize(self.object:get_properties())) + clicker:set_wielded_item(it) + self.object:remove() + end + awards.unlock(clicker:get_player_name(), "mcl:tacticalFishing") + end + end, + on_spawn = set_textures, +} + +mcl_mobs.register_mob("mobs_mc:tropical_fish", tropical_fish) + +local water = 0 +mcl_mobs:spawn_specific( +"mobs_mc:tropical_fish", +"overworld", +"water", +{ +"Mesa", +"Jungle", +"Savanna", +"Desert", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"JungleM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"Savanna_beach", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"JungleEdgeM_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"Savanna_deep_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"Mesa_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"MesaPlateauFM_ocean", +"JungleM_deep_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"Jungle_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"JungleM_ocean", +"MesaBryce_underground", +"Mesa_underground", +"Jungle_underground", +"MesaPlateauF_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"JungleM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +--spawn egg +mcl_mobs.register_egg("mobs_mc:tropical_fish", S("Tropical fish"), "#ef6915", "#fff9ef", 0) diff --git a/mods/ENTITIES/mobs_mc/vex.lua b/mods/ENTITIES/mobs_mc/vex.lua index 9a5455425..f2cd6f14b 100644 --- a/mods/ENTITIES/mobs_mc/vex.lua +++ b/mods/ENTITIES/mobs_mc/vex.lua @@ -9,7 +9,7 @@ local S = minetest.get_translator("mobs_mc") --################### VEX --################### -mcl_mobs:register_mob("mobs_mc:vex", { +mcl_mobs.register_mob("mobs_mc:vex", { description = S("Vex"), type = "monster", spawn_class = "hostile", @@ -94,4 +94,4 @@ mcl_mobs:register_mob("mobs_mc:vex", { -- spawn eggs -mcl_mobs:register_egg("mobs_mc:vex", S("Vex"), "mobs_mc_spawn_icon_vex.png", 0) +mcl_mobs.register_egg("mobs_mc:vex", S("Vex"), "#7a90a4", "#e8edf1", 0) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index f04602ebf..bb23758c5 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -15,6 +15,8 @@ -- TODO: Internal inventory, trade with other villagers -- TODO: Schedule stuff (work,sleep,father) +local weather_mod = minetest.get_modpath("mcl_weather") + local S = minetest.get_translator("mobs_mc") local N = function(s) return s end local F = minetest.formspec_escape @@ -28,6 +30,10 @@ local DEFAULT_WALK_CHANCE = 33 -- chance to walk in percent, if no player nearby local PLAYER_SCAN_INTERVAL = 5 -- every X seconds, villager looks for players nearby local PLAYER_SCAN_RADIUS = 4 -- scan radius for looking for nearby players +local RESETTLE_DISTANCE = 100 -- If a mob is transported this far from home, it gives up bed and job and resettles + +local PATHFINDING = "gowp" + --[=======[ TRADING ]=======] -- LIST OF VILLAGER PROFESSIONS AND TRADES @@ -40,6 +46,13 @@ local PLAYER_SCAN_RADIUS = 4 -- scan radius for looking for nearby players -- these items should be implemented as single items, then everything -- will be much easier. +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false) +local function mcl_log (message) + if LOGGING_ON then + mcl_util.mcl_log (message, "[Mobs - Villager]", true) + end +end + local COMPASS = "mcl_compass:compass" if minetest.registered_aliases[COMPASS] then COMPASS = minetest.registered_aliases[COMPASS] @@ -66,11 +79,11 @@ local tiernames = { } local badges = { - "default_wood.png", - "default_steel_block.png", - "default_gold_block.png", - "mcl_core_emerald_block.png", - "default_diamond_block.png", + "mobs_mc_stone.png", + "mobs_mc_iron.png", + "mobs_mc_gold.png", + "mobs_mc_emerald.png", + "mobs_mc_diamond.png", } local professions = { @@ -84,10 +97,7 @@ local professions = { }, farmer = { name = N("Farmer"), - textures = { - "mobs_mc_villager_farmer.png", - "mobs_mc_villager_farmer.png", - }, + texture = "mobs_mc_villager_farmer.png", jobsite = "mcl_composters:composter", trades = { { @@ -98,7 +108,7 @@ local professions = { }, { - { { "mcl_farming:pumpkin", 8, 13 }, E1 }, + { { "mcl_farming:pumpkin", 6, 7 }, E1 }, { E1, { "mcl_farming:pumpkin_pie", 2, 3} }, { E1, { "mcl_core:apple", 2, 3} }, }, @@ -121,10 +131,7 @@ local professions = { }, fisherman = { name = N("Fisherman"), - textures = { - "mobs_mc_villager_fisherman.png", - "mobs_mc_villager_fisherman.png", - }, + texture = "mobs_mc_villager_fisherman.png", jobsite = "mcl_barrels:barrel_closed", trades = { { @@ -136,8 +143,7 @@ local professions = { { { { "mcl_fishing:fish_raw", 6, 15,}, E1 }, { { "mcl_fishing:salmon_raw", 6, 6, "mcl_core:emerald", 1, 1 },{ "mcl_fishing:salmon_cooked", 6, 6 } }, - -- FIXME missing campfire - -- {{ "mcl_core:emerald", 1, 2 },{"mcl_campfires:campfire",1,1} }, + { { "mcl_core:emerald", 1, 2 },{"mcl_campfires:campfire_lit",1,1} }, }, { { { "mcl_fishing:salmon_raw", 6, 13,}, E1 }, @@ -159,10 +165,7 @@ local professions = { }, fletcher = { name = N("Fletcher"), - textures = { - "mobs_mc_villager_fletcher.png", - "mobs_mc_villager_fletcher.png", - }, + texture = "mobs_mc_villager_fletcher.png", jobsite = "mcl_fletching_table:fletching_table", trades = { { @@ -201,10 +204,7 @@ local professions = { }, shepherd ={ name = N("Shepherd"), - textures = { - "mobs_mc_villager_sheperd.png", - "mobs_mc_villager_sheperd.png", - }, + texture = "mobs_mc_villager_sheperd.png", jobsite = "mcl_loom:loom", trades = { { @@ -234,10 +234,7 @@ local professions = { }, librarian = { name = N("Librarian"), - textures = { - "mobs_mc_villager_librarian.png", - "mobs_mc_villager_librarian.png", - }, + texture = "mobs_mc_villager_librarian.png", jobsite = "mcl_books:bookshelf", --FIXME: lectern trades = { { @@ -272,10 +269,7 @@ local professions = { }, cartographer = { name = N("Cartographer"), - textures = { - "mobs_mc_villager_cartographer.png", - "mobs_mc_villager_cartographer.png", - }, + texture = "mobs_mc_villager_cartographer.png", jobsite = "mcl_cartography_table:cartography_table", trades = { { @@ -284,7 +278,7 @@ local professions = { }, { -- compass subject to special checks - { { "xpanes:pane_natural_flat", 1, 1 }, E1 }, + { { "xpanes:pane_natural_flat", 11, 11 }, E1 }, --{ { "mcl_core:emerald", 13, 13, "mcl_compass:compass", 1, 1 }, { "FIXME:ocean explorer map" 1, 1} }, }, { @@ -318,10 +312,7 @@ local professions = { }, armorer = { name = N("Armorer"), - textures = { - "mobs_mc_villager_armorer.png", - "mobs_mc_villager_armorer.png", - }, + texture = "mobs_mc_villager_armorer.png", jobsite = "mcl_blast_furnace:blast_furnace", trades = { { @@ -358,10 +349,7 @@ local professions = { }, leatherworker = { name = N("Leatherworker"), - textures = { - "mobs_mc_villager_leatherworker.png", - "mobs_mc_villager_leatherworker.png", - }, + texture = "mobs_mc_villager_leatherworker.png", jobsite = "mcl_cauldrons:cauldron", trades = { { @@ -390,10 +378,7 @@ local professions = { }, butcher = { name = N("Butcher"), - textures = { - "mobs_mc_villager_butcher.png", - "mobs_mc_villager_butcher.png", - }, + texture = "mobs_mc_villager_butcher.png", jobsite = "mcl_smoker:smoker", trades = { { @@ -423,11 +408,8 @@ local professions = { }, weapon_smith = { name = N("Weapon Smith"), - textures = { - "mobs_mc_villager_weaponsmith.png", - "mobs_mc_villager_weaponsmith.png", - }, - jobsite = "mcl_furnaces:furnace", --FIXME: grindstone + texture = "mobs_mc_villager_weaponsmith.png", + jobsite = "mcl_grindstone:grindstone", trades = { { { { "mcl_core:coal_lump", 15, 15 }, E1 }, @@ -454,11 +436,8 @@ local professions = { }, tool_smith = { name = N("Tool Smith"), - textures = { - "mobs_mc_villager_toolsmith.png", - "mobs_mc_villager_toolsmith.png", - }, - jobsite = "mcl_anvils:anvil", --FIXME: smithing table + texture = "mobs_mc_villager_toolsmith.png", + jobsite = "mcl_smithing_table:table", trades = { { { { "mcl_core:coal_lump", 15, 15 }, E1 }, @@ -491,10 +470,7 @@ local professions = { }, cleric = { name = N("Cleric"), - textures = { - "mobs_mc_villager_priest.png", - "mobs_mc_villager_priest.png", - }, + texture = "mobs_mc_villager_priest.png", jobsite = "mcl_brewing:stand_000", trades = { { @@ -503,7 +479,7 @@ local professions = { }, { { { "mcl_core:gold_ingot", 3, 3 }, E1 }, - { E1, { "mcl_dye:blue", 1, 1 } }, + { E1, { "mcl_core:lapis", 1, 1 } }, }, { { { "mcl_mobitems:rabbit_foot", 2, 2 }, E1 }, @@ -521,27 +497,88 @@ local professions = { }, }, }, + mason = { + name = N("Mason"), + texture = "mobs_mc_villager_mason.png", + jobsite = "mcl_stonecutter:stonecutter", + trades = { + { + { { "mcl_core:clay_lump", 10, 10 }, E1 }, + { E1, { "mcl_core:brick", 10, 10 } }, + }, + { + { { "mcl_core:stone", 20, 20 }, E1 }, + { E1, { "mcl_core:stonebrickcarved", 4, 4 } }, + }, + { + { { "mcl_core:granite", 16, 16 }, E1 }, + { { "mcl_core:andesite", 16, 16 }, E1 }, + { { "mcl_core:diorite", 16, 16 }, E1 }, + { E1, { "mcl_core:granite_smooth", 4, 4 } }, + { E1, { "mcl_core:andesite_smooth", 4, 4 } }, + { E1, { "mcl_core:diorite_smooth", 4, 4 } }, + }, + { + { { "mcl_nether:quartz", 12, 12 }, E1 }, + { E1, { "mcl_colorblocks:hardened_clay", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_white", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_grey", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_silver", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_black", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_red", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_yellow", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_green", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_cyan", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_blue", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_magenta", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_orange", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_brown", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_pink", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_light_blue", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_lime", 1, 1} }, + { E1, { "mcl_colorblocks:hardened_clay_purple", 1, 1 } }, + }, + { + { E1, { "mcl_nether:quartz_pillar", 1, 1 } }, + { E1, { "mcl_nether:quartz_block", 1, 1 } }, + }, + }, + }, nitwit = { name = N("Nitwit"), - textures = { - "mobs_mc_villager_nitwit.png", - "mobs_mc_villager_nitwit.png", - }, + texture = "mobs_mc_villager_nitwit.png", -- No trades for nitwit trades = nil, } } +local WORK = "work" +local SLEEP = "sleep" +local GATHERING = "gathering" + local profession_names = {} for id, _ in pairs(professions) do table.insert(profession_names, id) end -local jobsites={} -for _,n in pairs(profession_names) do - table.insert(jobsites,professions[n].jobsite) +local function populate_jobsites (profession) + if profession then + mcl_log("populate_jobsites: ".. tostring(profession)) + end + local jobsites_requested={} + for _,n in pairs(profession_names) do + if n and professions[n].jobsite then + if not profession or (profession and profession == n) then + --minetest.log("populate_jobsites. Adding: ".. tostring(n)) + table.insert(jobsites_requested,professions[n].jobsite) + end + end + end + return jobsites_requested end +jobsites = populate_jobsites() + local function stand_still(self) self.walk_chance = 0 self.jump = false @@ -560,36 +597,404 @@ local function init_trader_vars(self) end local function get_badge_textures(self) - local t = professions[self._profession].textures + local t = professions[self._profession].texture + if self._profession == "unemployed" then + t = professions[self._profession].textures -- ideally both scenarios should be textures with a list containing 1 or multiple + --mcl_log("t: " .. tostring(t)) + end + if self._profession == "unemployed" or self._profession == "nitwit" then return t end local tier = self._max_trade_tier or 1 return { - "[combine:64x64:0,0="..t[1]..":11,55=".. badges[tier].."\\^[resize\\:2x2", - t[2] + t .. "^" .. badges[tier] } end local function set_textures(self) - self.object:set_properties({textures=get_badge_textures(self)}) + local badge_textures = get_badge_textures(self) + --mcl_log("Setting textures: " .. tostring(badge_textures)) + self.object:set_properties({textures=badge_textures}) end -local function go_home(entity) - entity.state = "go_home" - local b=entity._bed - if not b then return end - mcl_mobs:gopath(entity,b,function(entity,b) - if vector.distance(entity.object:get_pos(),b) < 2 then - entity.state = "stand" - set_velocity(entity,0) - entity.object:set_pos(b) - local n=minetest.get_node(b) - if n and n.name ~= "mcl_beds:bed_red_bottom" then - entity._bed=nil --the stormtroopers have killed uncle owen +function get_activity(tod) + -- night hours = tod > 18541 or tod < 5458 + if not tod then + tod = minetest.get_timeofday() + end + tod = ( tod * 24000 ) % 24000 + + local lunch_start = 11000 + local lunch_end = 13500 + local work_start = 7000 + local work_end = 16500 + + local activity = nil + if weather_mod and mcl_weather.get_weather() == "thunder" then + mcl_log("Better get to bed. Weather is: " .. mcl_weather.get_weather()) + activity = SLEEP + elseif (tod > work_start and tod < lunch_start) or (tod > lunch_end and tod < work_end) then + activity = WORK + elseif mcl_beds.is_night() then + activity = SLEEP + elseif tod > lunch_start and tod < lunch_end then + activity = GATHERING + else + activity = "chill" + end + --mcl_log("Time is " .. tod ..". Activity is: ".. activity) + return activity + +end + +local function find_closest_bed (self) + local p = self.object:get_pos() + + --local spawnable_bed={} + --table.insert(spawnable_bed, "mcl_beds:bed_red_bottom") + --local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), spawnable_bed) + --if nn then + -- mcl_log("Red beds: " .. #nn) + --end + + local unclaimed_beds = {} + local nn2 = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), {"group:bed"}) + if nn2 then + --mcl_log("All bed parts: " .. #nn2) + + for a,b in pairs(nn2) do + mcl_log("b: " .. minetest.pos_to_string(b)) + + local bed_node = minetest.get_node(b) + local bed_name = bed_node.name + local is_bed_bottom = string.find(bed_name,"_bottom") + + local bed_meta = minetest.get_meta(b) + local owned_by = bed_meta:get_string("villager") + --mcl_log("Owned by villager: ".. tostring(owned_by)) + + if (owned_by and owned_by == self._id) then + mcl_log("Clear as already owned by me.") + bed_meta:set_string("villager", nil) + owned_by = nil + end + + if is_bed_bottom then + local bed_top = mcl_beds.get_bed_top (b) + mcl_log("bed_top: " .. tostring(bed_top)) + + local bed_top_node = minetest.get_node(bed_top) + if bed_top_node then + mcl_log("There is a block here for bed top: ".. bed_top_node.name) + else + mcl_log("There is no block here for bed top") + end + + local bed_top_meta = minetest.get_meta(bed_top) + local owned_by_player = bed_top_meta:get_string("player") + if bed_top_meta then + mcl_log("Player: " .. tostring(owned_by_player)) + else + mcl_log("No bed top meta") + end + + if owned_by == "" and (not owned_by_player or owned_by_player == "") then + table.insert(unclaimed_beds, b) + mcl_log("is an unowned bed bottom") + else + + end + else + --mcl_log("bed_node name: " .. bed_name) + end + end + end + + local distance_to_closest_block = nil + local closest_block = nil + + if unclaimed_beds then + mcl_log("All unclaimed bed bottoms: " .. #unclaimed_beds) + + for i,b in pairs(unclaimed_beds) do + mcl_log("b: " .. minetest.pos_to_string(b)) + local distance_to_block = vector.distance(p, b) + mcl_log("Distance to block ".. i .. ": ".. distance_to_block) + + if not distance_to_closest_block or distance_to_closest_block > distance_to_block then + mcl_log("This block is closer than the last.") + closest_block = b + distance_to_closest_block = distance_to_block + end + + local bed_node = minetest.get_node(b) + local bed_name = bed_node.name + mcl_log("bed_node name: " .. bed_name) + end + end + + return closest_block +end + +local function find_closest_unclaimed_block (p, requested_block_types) + local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), requested_block_types) + + local distance_to_closest_block = nil + local closest_block = nil + + for i,n in pairs(nn) do + local m = minetest.get_meta(n) + + if m:get_string("villager") == "" then + mcl_log("Block: " .. minetest.pos_to_string(n).. ", owner: ".. m:get_string("villager")) + + local distance_to_block = vector.distance(p, n) + mcl_log("Distance to block ".. i .. ": ".. distance_to_block) + + if not distance_to_closest_block or distance_to_closest_block > distance_to_block then + mcl_log("This block is closer than the last.") + closest_block = n + distance_to_closest_block = distance_to_block + end + end + end + return closest_block +end + +local function check_bed (entity) + local b = entity._bed + if not b then + --minetest.log("No bed set on villager") + return false + end + + local n = minetest.get_node(b) + + local is_bed_bottom = string.find(n.name,"_bottom") + --mcl_log("is bed bottom: " .. tostring(is_bed_bottom)) + if n and not is_bed_bottom then + mcl_log("Where did my bed go?!") + entity._bed = nil --the stormtroopers have killed uncle owen + return false + else + return true + end +end + +local function go_home(entity, sleep) + + if not check_bed (entity) then + mcl_log("Cannot find bed, so cannot go home") + end + + local b = entity._bed + if not b then + return + end + + local bed_node = minetest.get_node(b) + if not bed_node then + entity._bed = nil + mcl_log("Cannot find bed. Unset it") + return + end + + if vector.distance(entity.object:get_pos(),b) < 2 then + if sleep then + entity.order = SLEEP + mcl_log("Sleep time!") + end + else + if sleep and entity.order == SLEEP then + entity.order = nil + return + end + + entity:gopath(b,function(entity,b) + local b = entity._bed + + if not b then + --minetest.log("NO BED, problem") return false end - return true + + if not minetest.get_node(b) then + --minetest.log("NO BED NODE, problem") + return false + end + + if vector.distance(entity.object:get_pos(),b) < 2 then + --minetest.log("Managed to walk home callback!") + return true + else + --minetest.log("Need to walk to home") + end + end) + end +end + + + +local function take_bed (entity) + if not entity then return end + if not entity:ready_to_path() then return end + + local p = entity.object:get_pos() + + local closest_block = find_closest_bed (entity) + + if closest_block then + mcl_log("Can we path to bed: "..minetest.pos_to_string(closest_block) ) + local distance_to_block = vector.distance(p, closest_block) + mcl_log("Distance: " .. distance_to_block) + if distance_to_block < 2 then + local m = minetest.get_meta(closest_block) + local owner = m:get_string("villager") + mcl_log("owner: ".. owner) + if owner and owner ~= "" and owner ~= entity._id then + mcl_log("Already taken") + if entity.order == "stand" then entity.order = nil end + return + end + + if entity.order ~= SLEEP then + mcl_log("Sleepy time" ) + entity.order = SLEEP + m:set_string("villager", entity._id) + entity._bed = closest_block + else + --entity.order = nil + mcl_log("Set as sleep already..." ) + end + else + local gp = entity:gopath(closest_block,function(self) end) + if gp then + mcl_log("Nice bed. I'll defintely take it as I can path") + else + mcl_log("Awww. I can't find my bed.") + end end - end) + else + mcl_log("Cannot find a bed to claim.") + if entity.order == "stand" then entity.order = nil end + end +end + +local function has_golem(pos) + local r = false + for _,o in pairs(minetest.get_objects_inside_radius(pos,16)) do + local l = o:get_luaentity() + if l and l.name == "mobs_mc:iron_golem" then return true end + end +end + +local function monsters_near(self) + for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),10)) do + local l = o:get_luaentity() + if l and l.type =="monster" then return true end + end +end + +local function has_summon_participants(self) + local r = 0 + for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),10)) do + local l = o:get_luaentity() + --TODO check for gossiping + if l and l.name == "mobs_mc:villager" then r = r + 1 end + end + return r > 2 +end + +local function summon_golem(self) + vector.offset(self.object:get_pos(),-10,-10,-10) + local nn = minetest.find_nodes_in_area_under_air(vector.offset(self.object:get_pos(),-10,-10,-10),vector.offset(self.object:get_pos(),10,10,10),{"group:solid","group:water"}) + table.shuffle(nn) + for _,n in pairs(nn) do + local up = minetest.find_nodes_in_area(vector.offset(n,0,1,0),vector.offset(n,0,3,0),{"air"}) + if up and #up >= 3 then + minetest.sound_play("mcl_portals_open_end_portal", {pos=n, gain=0.5, max_hear_distance = 16}, true) + return minetest.add_entity(vector.offset(n,0,1,0),"mobs_mc:iron_golem") + end + end +end + +local function check_summon(self,dtime) + -- TODO has selpt in last 20? + if self._summon_timer and self._summon_timer > 30 then + local pos = self.object:get_pos() + self._summon_timer = 0 + if has_golem(pos) then return end + if not monsters_near(self) then return end + if not has_summon_participants(self) then return end + summon_golem(self) + elseif self._summon_timer == nil then + self._summon_timer = 0 + end + self._summon_timer = self._summon_timer + dtime +end + +local function debug_trades(self) + mcl_log("Start debug trades") + if not self or not self._trades then return end + local trades = minetest.deserialize(self._trades) + if trades and type(trades) == "table" then + for trader, trade in pairs(trades) do + --mcl_log("Current record: ".. tostring(trader)) + for tr3, tr4 in pairs (trade) do + mcl_log("Key: ".. tostring(tr3)) + mcl_log("Value: ".. tostring(tr4)) + end + end + end + mcl_log("End debug trades") +end + +local function has_traded (self) + if not self._trades then + mcl_log("No trades set. has_traded is false") + return false + end + local cur_trades_tab = minetest.deserialize(self._trades) + if cur_trades_tab and type(cur_trades_tab) == "table" then + for trader, trades in pairs(cur_trades_tab) do + if trades.traded_once then + mcl_log("Villager has traded before. Returning true") + return true + end + end + end + mcl_log("Villager has not traded before") + return false +end + +local function unlock_trades (self) + if not self._trades then + mcl_log("No trades set. has_traded is false") + return false + end + mcl_log("Unlocking trades") + local has_unlocked = false + + local trades = minetest.deserialize(self._trades) + if trades and type(trades) == "table" then + for trader, trade in pairs(trades) do + local trade_tier_too_high = trade.tier > self._max_trade_tier + --mcl_log("Max trade tier of villager: ".. tostring(self._max_trade_tier)) + --mcl_log("current trade.tier: ".. tostring(trade.tier)) + --mcl_log("trade tier too high: ".. tostring(trade_tier_too_high)) + --mcl_log("locked: ".. tostring(trade["locked"])) + if not trade_tier_too_high then + if trade["locked"] == true then + trade.locked = false + trade.trade_counter = 0 + has_unlocked = true + mcl_log("Villager has a locked trade. Unlocking") + end + end + end + if has_unlocked then + self._trades = minetest.serialize(trades) + end + end end ----- JOBSITE LOGIC @@ -604,36 +1009,348 @@ local function employ(self,jobsite_pos) local m = minetest.get_meta(jobsite_pos) local p = get_profession_by_jobsite(n.name) if p and m:get_string("villager") == "" then - self._profession=p + mcl_log("Taking this jobsite") + m:set_string("villager",self._id) self._jobsite = jobsite_pos + + if not has_traded(self) then + self._profession=p + set_textures(self) + end + return true + else + mcl_log("I can not steal someone's job!") + end +end + + +local function look_for_job(self, requested_jobsites) + mcl_log("Looking for jobs") + + local p = self.object:get_pos() + + local closest_block = find_closest_unclaimed_block(p, requested_jobsites) + + if closest_block then + mcl_log("It's a free job for me (" .. minetest.pos_to_string(p) .. ")! I might be interested: ".. minetest.pos_to_string(closest_block) ) + + local gp = self:gopath(closest_block,function(self) + mcl_log("Arrived at block callback") + if self and self.state == "stand" then + self.order = WORK + else + mcl_log("no self. passing param to callback failed") + end + end) + + if gp then + if closest_block then + mcl_log("We can path to this block.. " .. tostring(closest_block)) + end + return closest_block + else + mcl_log("We could not path to block or it's not ready to path yet.") + end + else + mcl_log("We don't have a job block to path to") + end + + return nil +end + + +local function get_a_job(self) + if self.order == WORK then self.order = nil end + if not self:ready_to_path() then return end + + mcl_log("I'm unemployed or lost my job block and have traded. Can I get a job?") + + local requested_jobsites = jobsites + if has_traded (self) then + mcl_log("Has traded so look for job of my type") + requested_jobsites = populate_jobsites(self._profession) + -- Only pass in my jobsite to two functions here + end + + local p = self.object:get_pos() + local n = minetest.find_node_near(p,1,requested_jobsites) + if n and employ(self,n) then return true end + + if self.state ~= PATHFINDING then + mcl_log("Nothing near. Need to look for a job") + look_for_job(self, requested_jobsites) + end +end + +local function retrieve_my_jobsite (self) + if not self or not self._jobsite then + mcl_log("find_jobsite. Invalid params. Should not happen") + return + end + local n = mcl_vars.get_node(self._jobsite) + local m = minetest.get_meta(self._jobsite) + if m:get_string("villager") == self._id then + --mcl_log("find_jobsite. is my job.") + return n + else + mcl_log("This isn't my jobsite") + end + return +end + +local function remove_job (self) + self._jobsite = nil + if not has_traded(self) then + mcl_log("Cannot retrieve my jobsite. I am now unemployed.") + self._profession = "unemployed" + self._trades = nil set_textures(self) + else + mcl_log("Cannot retrieve my jobsite but I've traded so only remove jobsite.") + end +end + +local function validate_jobsite(self) + if self._profession == "unemployed" then return false end + + local job_block = retrieve_my_jobsite (self) + if not job_block then + if self.order == WORK then + self.order = nil + end + + remove_job (self) + return false + else + local resettle = vector.distance(self.object:get_pos(),self._jobsite) > RESETTLE_DISTANCE + mcl_log("Jobsite far, so resettle: " .. tostring(resettle)) + if resettle then + local m = minetest.get_meta(self._jobsite) + m:set_string("villager", nil) + remove_job (self) + return false + end return true end end -local function look_for_job(self) - local p = self.object:get_pos() - local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48),jobsites) - for _,n in pairs(nn) do - local m=minetest.get_meta(n) - if m:get_string("villager") == "" then - --minetest.log("goingt to jobsite "..minetest.pos_to_string(n) ) - local gp = mcl_mobs:gopath(self,n,function() - --minetest.log("arrived jobsite "..minetest.pos_to_string(n) ) +local function do_work (self) + + if not self or self.child then + mcl_log("No self, or a child so don't work") + return + end + + --mcl_log("Time for work") + local jobsite_node = retrieve_my_jobsite (self) + + if jobsite_node then + local jobsite = self._jobsite + + local distance_to_jobsite = vector.distance(self.object:get_pos(), jobsite) + --mcl_log("Villager: ".. minetest.pos_to_string(self.object:get_pos()) .. ", jobsite: " .. minetest.pos_to_string(self._jobsite) .. ", distance to jobsite: ".. distance_to_jobsite) + + if distance_to_jobsite < 2 then + if self.state ~= PATHFINDING and self.order ~= WORK then + mcl_log("Setting order to work.") + self.order = WORK + unlock_trades(self) + else + --mcl_log("Still pathfinding.") + end + else + mcl_log("Not at job block. Need to commute.") + if self.order == WORK then + self.order = nil + return + end + self:gopath(jobsite, function(self, jobsite) + if not self then + --mcl_log("missing self. not good") + return false + end + if not self._jobsite then + --mcl_log("Jobsite not valid") + return false + end + if vector.distance(self.object:get_pos(),self._jobsite) < 2 then + --mcl_log("Made it to work ok callback!") + return true + else + --mcl_log("Need to walk to work. Not sure we can get here.") + end end) - if gp then return end end end + end -local function get_a_job(self) - local p = self.object:get_pos() - local nn = minetest.find_nodes_in_area(vector.offset(p,-8,-8,-8),vector.offset(p,8,8,8),jobsites) - for _,n in pairs(nn) do - if n and employ(self,n) then return true end +local below_vec = vector.new(0, -1, 0) + +local function get_ground_below_floating_object (float_pos) + local pos = float_pos + repeat + mcl_log("Current pos: " .. minetest.pos_to_string(pos)) + pos = vector.add(pos, below_vec) + local node = minetest.get_node(pos) + mcl_log("First non air materials: ".. tostring(node.name)) + until node.name ~= "air" + + -- If pos is 1 below float_pos, then just return float_pos as there is no air below it + if pos.y == float_pos.y - 1 then + --mcl_log("pos is only 1 lower than float pos so no air below") + return float_pos + else + --mcl_log("pos is more than 1 lower than float pos so air is below") + return pos end - if self.state ~= "gowp" then look_for_job(self) end + + return pos +end + +local function go_to_town_bell(self) + if self.order == GATHERING then return + else mcl_log("Current order" .. self.order) end + + if not self:ready_to_path() then return end + + mcl_log("Go to town bell") + + local looking_for_type={} + table.insert(looking_for_type, "mcl_bells:bell") + + local p = self.object:get_pos() + local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), looking_for_type) + + --Ideally should check for closest available. It'll make pathing easier. + for _,n in pairs(nn) do + mcl_log("Found bell") + local target_point = get_ground_below_floating_object(n) + + local gp = self:gopath(target_point,function(self) + if self then + self.order = GATHERING + mcl_log("Callback has a self") + end + mcl_log("Arrived at block callback") + end) + + if gp then + if n then + mcl_log("We can path to this block.. " .. tostring(n)) + end + return n + else + mcl_log("We could not path to block or it's not ready to path yet.") + end + + end + + return nil +end + +local function validate_bed(self) + if not self or not self._bed then + return false + end + local n = mcl_vars.get_node(self._bed) + if not n then + self._bed = nil + return false + end + + local bed_valid = true + + local m = minetest.get_meta(self._bed) + + local resettle = vector.distance(self.object:get_pos(),self._bed) > RESETTLE_DISTANCE + mcl_log("Bed far, so resettle: " .. tostring(resettle)) + if resettle then + mcl_log("Resettled. Ditch bed.") + m:set_string("villager", nil) + self._bed = nil + bed_valid = false + return false + end + + local owned_by_player = m:get_string("player") + mcl_log("Player owner: " .. owned_by_player) + if owned_by_player ~= "" then + mcl_log("Player owns this. Villager won't take this.") + m:set_string("villager", nil) + self._bed = nil + bed_valid = false + return false + end + + if m:get_string("villager") ~= self._id then + mcl_log("This bed is owned by another player. I'll unclaim.") + self._bed = nil + return false + else + mcl_log("Bed is valid") + return true + end + +end + +local function do_activity (self) + + if self.following then + mcl_log("Following, so do not do activity.") + return + end + if self.state == PATHFINDING then + mcl_log("Pathfinding, so do not do activity.") + return + end + + local jobsite_valid = false + + if not mcl_beds.is_night() then + if self.order == SLEEP then self.order = nil end + + if not validate_jobsite(self) then + --debug_trades(self) + if self._profession == "unemployed" or has_traded(self) then + get_a_job(self) + return + end + else + jobsite_valid = true + --mcl_log("My jobsite is valid. Do i need to travel?") + end + else + if self.order == WORK then self.order = nil end + + if not validate_bed(self) then + if self.order == SLEEP then self.order = nil end + mcl_log("Villager at this location has no bed: " .. minetest.pos_to_string(self.object:get_pos())) + take_bed (self) + end + end + + -- Only check in day or during thunderstorm but wandered_too_far code won't work + local wandered_too_far = false + if check_bed (self) then + wandered_too_far = vector.distance(self.object:get_pos(),self._bed) > 50 + end + + if wandered_too_far then + --mcl_log("Wandered too far! Return home ") + go_home(self, false) + elseif get_activity() == SLEEP then + go_home(self, true) + elseif get_activity() == WORK and jobsite_valid then + do_work(self) + elseif get_activity() == GATHERING then + go_to_town_bell(self) + else + mcl_log("No order, so remove it.") + self.order = nil + end + end local function update_max_tradenum(self) @@ -708,7 +1425,7 @@ local function set_trade(trader, player, inv, concrete_tradenum) init_trades(trader) trades = minetest.deserialize(trader._trades) if not trades then - minetest.log("error", "[mobs_mc] Failed to select villager trade!") + --minetest.log("error", "Failed to select villager trade!") return end end @@ -724,7 +1441,10 @@ local function set_trade(trader, player, inv, concrete_tradenum) local trade = trades[concrete_tradenum] inv:set_stack("wanted", 1, ItemStack(trade.wanted[1])) local offered = ItemStack(trade.offered) - mcl_enchanting.load_enchantments(offered) + -- Only load enchantments for enchanted items; fixes unnecessary metadata being applied to regular items from villagers. + if mcl_enchanting.is_enchanted(offered:get_name()) then + mcl_enchanting.load_enchantments(offered) + end inv:set_stack("offered", 1, offered) if trade.wanted[2] then local wanted2 = ItemStack(trade.wanted[2]) @@ -802,7 +1522,7 @@ local function show_trade_formspec(playername, trader, tradenum) .."listring[current_player;main]" .."listring["..tradeinv..";input]" .."listring[current_player;main]" - minetest.sound_play("mobs_mc_villager_trade", {to_player = playername}, true) + minetest.sound_play("mobs_mc_villager_trade", {to_player = playername,object=trader.object}, true) minetest.show_formspec(playername, tradeinv_name, formspec) end @@ -864,13 +1584,13 @@ local function update_offer(inv, player, sound) (trade.locked == false)) then inv:set_stack("output", 1, inv:get_stack("offered", 1)) if sound then - minetest.sound_play("mobs_mc_villager_accept", {to_player = name}, true) + minetest.sound_play("mobs_mc_villager_accept", {to_player = name,object=trader.object}, true) end return true else inv:set_stack("output", 1, ItemStack("")) if sound then - minetest.sound_play("mobs_mc_villager_deny", {to_player = name}, true) + minetest.sound_play("mobs_mc_villager_deny", {to_player = name,object=trader.object}, true) end return false end @@ -982,6 +1702,11 @@ local trade_inventory = { elseif listname == "output" then if not trader_exists(player:get_player_name()) then return 0 + -- Begin Award Code + -- May need to be moved if award gets unlocked in the wrong cases. + elseif trader_exists(player:get_player_name()) then + awards.unlock(player:get_player_name(), "mcl:whatAdeal") + -- End Award Code end -- Only allow taking full stack local count = stack:get_count() @@ -1065,7 +1790,8 @@ local trade_inventory = { if not wanted2:is_empty() then inv:remove_item("input", inv:get_stack("wanted", 2)) end - minetest.sound_play("mobs_mc_villager_accept", {to_player = player:get_player_name()}, true) + local trader = player_trading_with[name] + minetest.sound_play("mobs_mc_villager_accept", {to_player = player:get_player_name(),object=trader.object}, true) end update_offer(inv, player, true) end, @@ -1093,7 +1819,9 @@ local trade_inventory = { -- END OF SPECIAL HANDLING FOR COMPASS local trader = player_trading_with[name] local tradenum = player_tradenum[name] + local trades + trader._traded = true if trader and trader._trades then trades = minetest.deserialize(trader._trades) end @@ -1131,6 +1859,7 @@ local trade_inventory = { trader.health = math.min(trader.hp_max, trader.health + 4) end trade.trade_counter = trade.trade_counter + 1 + mcl_log("Trade counter is: ".. trade.trade_counter) -- Semi-randomly lock trade for repeated trade (not if there's only 1 trade) if trader._max_tradenum > 1 then if trade.trade_counter >= 12 then @@ -1174,10 +1903,11 @@ local trade_inventory = { elseif listname == "input" then update_offer(inv, player, false) end + local trader = player_trading_with[name] if accept then - minetest.sound_play("mobs_mc_villager_accept", {to_player = name}, true) + minetest.sound_play("mobs_mc_villager_accept", {to_player = name,object=trader.object}, true) else - minetest.sound_play("mobs_mc_villager_deny", {to_player = name}, true) + minetest.sound_play("mobs_mc_villager_deny", {to_player = name,object=trader.object}, true) end end, } @@ -1202,12 +1932,18 @@ end) local pick_up = { "mcl_farming:bread", "mcl_farming:carrot_item", "mcl_farming:beetroot_item" , "mcl_farming:potato_item" } -mcl_mobs:register_mob("mobs_mc:villager", { +mcl_mobs.register_mob("mobs_mc:villager", { description = S("Villager"), type = "npc", spawn_class = "passive", + passive = true, hp_min = 20, hp_max = 20, + head_swivel = "head.control", + bone_eye_height = 6.3, + head_eye_height = 2.2, + curiosity = 10, + runaway = true, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, visual = "mesh", mesh = "mobs_mc_villager.b3d", @@ -1215,7 +1951,6 @@ mcl_mobs:register_mob("mobs_mc:villager", { "mobs_mc_villager.png", "mobs_mc_villager.png", --hat }, - visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, walk_velocity = 1.2, run_velocity = 2.4, @@ -1224,22 +1959,22 @@ mcl_mobs:register_mob("mobs_mc:villager", { -- TODO: sounds sounds = { random = "mobs_mc_villager", + damage = "mobs_mc_villager_hurt", distance = 10, }, animation = { - stand_speed = 25, - stand_start = 40, - stand_end = 59, - walk_speed = 25, - walk_start = 0, - walk_end = 40, - run_speed = 25, - run_start = 0, - run_end = 40, - die_speed = 15, - die_start = 210, - die_end = 220, - die_loop = false, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 25, + run_start = 0, run_end = 40, run_speed = 25, + head_shake_start = 60, head_shake_end = 70, head_shake_loop = false, + head_nod_start = 50, head_nod_end = 60, head_nod_loop = false, + }, + child_animations = { + stand_start = 71, stand_end = 71, + walk_start = 71, walk_end = 111, walk_speed = 37, + run_start = 71, run_end = 111, run_speed = 37, + head_shake_start = 131, head_shake_end = 141, head_shake_loop = false, + head_nod_start = 121, head_nod_end = 131, head_nod_loop = false, }, follow = pick_up, nofollow = true, @@ -1255,37 +1990,56 @@ mcl_mobs:register_mob("mobs_mc:villager", { can_open_doors = true, on_pick_up = function(self,itementity) local clicker + local it = ItemStack(itementity.itemstring) for _,p in pairs(minetest.get_connected_players()) do if vector.distance(p:get_pos(),self.object:get_pos()) < 10 then clicker = p end end - if clicker then - mcl_mobs:feed_tame(self, clicker, 1, true, false) - return + if clicker and not self.horny then + self:feed_tame(clicker, 1, true, false, true) + it:take_item(1) end - return true --do not pick up + return it end, on_rightclick = function(self, clicker) - local trg=vector.new(0,9,0) - if self._jobsite then - mcl_mobs:gopath(self,self._jobsite,function() - --minetest.log("arrived at jobsite") - end) - end - if self.child or self._profession == "unemployed" then + if self.child or self._profession == "unemployed" or self._profession == "nitwit" then + self.order = nil return end + + if self.state == PATHFINDING then + self.state = "stand" + end + -- Can we remove now we possibly have fixed root cause + if self.state == "attack" then + mcl_log("Somehow villager got into an invalid attack state. Removed attack state.") + -- Need to stop villager getting in attack state. This is a workaround to allow players to fix broken villager. + self.state = "stand" + self.attack = nil + end + -- Don't do at night. Go to bed? Maybe do_activity needs it's own method + if validate_jobsite(self) and not self.order == WORK then + --self:gopath(self._jobsite,function() + -- minetest.log("sent to jobsite") + --end) + else + self.state = "stand" -- cancel gowp in case it has messed up + --self.order = nil -- cancel work if working + end + -- Initiate trading init_trader_vars(self) local name = clicker:get_player_name() self._trading_players[name] = true - if self._trades == nil then + if self._trades == nil or self._trades == false then + --minetest.log("Trades is nil so init") init_trades(self) end update_max_tradenum(self) if self._trades == false then + --minetest.log("Trades is false. no right click op") -- Villager has no trades, rightclick is a no-op return end @@ -1313,18 +2067,22 @@ mcl_mobs:register_mob("mobs_mc:villager", { _player_scan_timer = 0, _trading_players = {}, -- list of playernames currently trading with villager (open formspec) do_custom = function(self, dtime) + check_summon(self,dtime) + -- Stand still if player is nearby. if not self._player_scan_timer then self._player_scan_timer = 0 end - self._player_scan_timer = self._player_scan_timer + dtime + -- Check infrequently to keep CPU load low if self._player_scan_timer > PLAYER_SCAN_INTERVAL then + self._player_scan_timer = 0 local selfpos = self.object:get_pos() local objects = minetest.get_objects_inside_radius(selfpos, PLAYER_SCAN_RADIUS) local has_player = false + for o, obj in pairs(objects) do if obj:is_player() then has_player = true @@ -1332,35 +2090,34 @@ mcl_mobs:register_mob("mobs_mc:villager", { end end if has_player then - minetest.log("verbose", "[mobs_mc] Player near villager found!") + --minetest.log("verbose", "[mobs_mc] Player near villager found!") stand_still(self) else - minetest.log("verbose", "[mobs_mc] No player near villager found!") + --minetest.log("verbose", "[mobs_mc] No player near villager found!") self.walk_chance = DEFAULT_WALK_CHANCE self.jump = true end - if self._bed and ( self.state ~= "go_home" and vector.distance(self.object:get_pos(),self._bed) > 50 ) then - go_home(self) - end - if self._profession == "unemployed" then - get_a_job(self) - end + + do_activity (self) + end end, on_spawn = function(self) + if not self._profession then + self._profession = "unemployed" + if math.random(100) == 1 then + self._profession = "nitwit" + end + end if self._id then set_textures(self) return end self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random())) - self._profession = "unemployed" - if math.random(100) == 1 then - self._profession = "nitwit" - end set_textures(self) end, - on_die = function(self, pos) + on_die = function(self, pos, cmi_cause) -- Close open trade formspecs and give input back to players local trading_players = self._trading_players if trading_players then @@ -1372,11 +2129,37 @@ mcl_mobs:register_mob("mobs_mc:villager", { end end end + + local bed = self._bed + if bed then + local bed_meta = minetest.get_meta(bed) + bed_meta:set_string("villager", nil) + mcl_log("Died, so bye bye bed") + end + local jobsite = self._jobsite + if jobsite then + local jobsite_meta = minetest.get_meta(jobsite) + jobsite_meta:set_string("villager", nil) + mcl_log("Died, so bye bye jobsite") + end + + if cmi_cause and cmi_cause.puncher then + local l = cmi_cause.puncher:get_luaentity() + if l and math.random(2) == 1 and( l.name == "mobs_mc:zombie" or l.name == "mobs_mc:baby_zombie" or l.name == "mobs_mc:villager_zombie" or l.name == "mobs_mc:husk") then + mcl_util.replace_mob(self.object,"mobs_mc:villager_zombie") + return true + end + end + end, + on_lightning_strike = function(self, pos, pos2, objects) + mcl_util.replace_mob(self.object, "mobs_mc:witch") + return true end, }) - +--[[ +Villager spawning in mcl_villages mcl_mobs:spawn_specific( "mobs_mc:villager", "overworld", @@ -1406,6 +2189,6 @@ minetest.LIGHT_MAX+1, 4, mobs_mc.water_level+1, mcl_vars.mg_overworld_max) - +--]] -- spawn eggs -mcl_mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0) +mcl_mobs.register_egg("mobs_mc:villager", S("Villager"), "#563d33", "#bc8b72", 0) diff --git a/mods/ENTITIES/mobs_mc/villager_evoker.lua b/mods/ENTITIES/mobs_mc/villager_evoker.lua index 6e62e00b6..4d46a7260 100644 --- a/mods/ENTITIES/mobs_mc/villager_evoker.lua +++ b/mods/ENTITIES/mobs_mc/villager_evoker.lua @@ -11,16 +11,23 @@ local S = minetest.get_translator("mobs_mc") local pr = PseudoRandom(os.time()*666) -mcl_mobs:register_mob("mobs_mc:evoker", { +local spawned_vexes = {} --this is stored locally so the mobs engine doesn't try to store it in staticdata + +mcl_mobs.register_mob("mobs_mc:evoker", { description = S("Evoker"), type = "monster", spawn_class = "hostile", + can_despawn = false, physical = true, pathfinding = 1, hp_min = 24, hp_max = 24, xp_min = 10, xp_max = 10, + head_swivel = "head.control", + bone_eye_height = 6.3, + head_eye_height = 2.2, + curiosity = 10, collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.95, 0.4}, visual = "mesh", mesh = "mobs_mc_villager.b3d", @@ -29,7 +36,6 @@ mcl_mobs:register_mob("mobs_mc:evoker", { "blank.png", --no hat -- TODO: Attack glow } }, - visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 6, walk_velocity = 0.2, @@ -38,16 +44,24 @@ mcl_mobs:register_mob("mobs_mc:evoker", { attack_type = "dogfight", -- Summon vexes custom_attack = function(self, to_attack) - local r = pr:next(2,4) + if not spawned_vexes[self] then spawned_vexes[self] = {} end + if #spawned_vexes[self] >= 7 then return end + for k,v in pairs(spawned_vexes[self]) do + if not v or v.health <= 0 then table.remove(spawned_vexes[self],k) end + end + local r = pr:next(1,4) local basepos = self.object:get_pos() basepos.y = basepos.y + 1 for i=1, r do local spawnpos = vector.add(basepos, minetest.yaw_to_dir(pr:next(0,360))) local vex = minetest.add_entity(spawnpos, "mobs_mc:vex") local ent = vex:get_luaentity() + -- Mark vexes as summoned and start their life clock (they take damage it reaches 0) ent._summoned = true ent._lifetimer = pr:next(33, 108) + + table.insert(spawned_vexes[self],ent) end end, shoot_interval = 15, @@ -65,23 +79,14 @@ mcl_mobs:register_mob("mobs_mc:evoker", { }, -- TODO: sounds animation = { - stand_speed = 25, - stand_start = 40, - stand_end = 59, - walk_speed = 25, - walk_start = 0, - walk_end = 40, - run_speed = 25, - shoot_start = 120, --magic arm swinging - shoot_end = 140, - die_speed = 15, - die_start = 190, - die_end = 200, - die_loop = false, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 6, + run_start = 0, run_end = 40, run_speed = 24, + shoot_start = 142, shoot_end = 152, -- Magic arm swinging }, view_range = 16, fear_height = 4, }) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:evoker", S("Evoker"), "mobs_mc_spawn_icon_evoker.png", 0) +mcl_mobs.register_egg("mobs_mc:evoker", S("Evoker"), "#959b9b", "#1e1c1a", 0) diff --git a/mods/ENTITIES/mobs_mc/villager_illusioner.lua b/mods/ENTITIES/mobs_mc/villager_illusioner.lua index 4af0c4024..f7c034eb0 100644 --- a/mods/ENTITIES/mobs_mc/villager_illusioner.lua +++ b/mods/ENTITIES/mobs_mc/villager_illusioner.lua @@ -6,7 +6,7 @@ local S = minetest.get_translator("mobs_mc") local mod_bows = minetest.get_modpath("mcl_bows") ~= nil -mcl_mobs:register_mob("mobs_mc:illusioner", { +mcl_mobs.register_mob("mobs_mc:illusioner", { description = S("Illusioner"), type = "monster", spawn_class = "hostile", @@ -33,6 +33,10 @@ mcl_mobs:register_mob("mobs_mc:illusioner", { "mobs_mc_illusionist.png", --hat "mcl_bows_bow.png", }, }, + head_swivel = "head.control", + bone_eye_height = 2.2, + head_eye_height = 2.2, + curiosity = 10, sounds = { -- TODO: more sounds distance = 16, @@ -61,4 +65,4 @@ mcl_mobs:register_mob("mobs_mc:illusioner", { fear_height = 4, }) -mcl_mobs:register_egg("mobs_mc:illusioner", S("Illusioner"), "mobs_mc_spawn_icon_illusioner.png", 0) +mcl_mobs.register_egg("mobs_mc:illusioner", S("Illusioner"), "#3f5cbb", "#8a8686", 0) diff --git a/mods/ENTITIES/mobs_mc/villager_vindicator.lua b/mods/ENTITIES/mobs_mc/villager_vindicator.lua index 0ed611899..b2dcb827a 100644 --- a/mods/ENTITIES/mobs_mc/villager_vindicator.lua +++ b/mods/ENTITIES/mobs_mc/villager_vindicator.lua @@ -10,7 +10,7 @@ local S = minetest.get_translator("mobs_mc") --################### -mcl_mobs:register_mob("mobs_mc:vindicator", { +mcl_mobs.register_mob("mobs_mc:vindicator", { description = S("Vindicator"), type = "monster", spawn_class = "hostile", @@ -23,14 +23,18 @@ mcl_mobs:register_mob("mobs_mc:vindicator", { collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, visual = "mesh", mesh = "mobs_mc_vindicator.b3d", - textures = { - { - "mobs_mc_vindicator.png", - "blank.png", --no hat - "default_tool_steelaxe.png", - -- TODO: Glow when attacking (mobs_mc_vindicator.png) - }, - }, + head_swivel = "head.control", + bone_eye_height = 2.2, + head_eye_height = 2.2, + curiosity = 10, + textures = { + { + "mobs_mc_vindicator.png", + "blank.png", --no hat + "default_tool_steelaxe.png", + -- TODO: Glow when attacking (mobs_mc_vindicator.png) + }, + }, visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 13, @@ -38,6 +42,7 @@ mcl_mobs:register_mob("mobs_mc:vindicator", { walk_velocity = 1.2, run_velocity = 2.4, attack_type = "dogfight", + attack_npcs = true, drops = { {name = "mcl_core:emerald", chance = 1, @@ -72,4 +77,4 @@ mcl_mobs:register_mob("mobs_mc:vindicator", { }) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:vindicator", S("Vindicator"), "mobs_mc_spawn_icon_vindicator.png", 0) +mcl_mobs.register_egg("mobs_mc:vindicator", S("Vindicator"), "#959b9b", "#275e61", 0) diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index 3dece8c29..9a1e30e70 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -25,10 +25,11 @@ local professions = { nitwit = "mobs_mc_villager.png", } -mcl_mobs:register_mob("mobs_mc:villager_zombie", { +mcl_mobs.register_mob("mobs_mc:villager_zombie", { description = S("Zombie Villager"), type = "monster", spawn_class = "hostile", + spawn_in_group = 1, hp_min = 20, hp_max = 20, xp_min = 5, @@ -38,13 +39,16 @@ mcl_mobs:register_mob("mobs_mc:villager_zombie", { collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, visual = "mesh", mesh = "mobs_mc_villager_zombie.b3d", + head_swivel = "Head_Control", + bone_eye_height = 2.35, + curiosity = 2, textures = { - {"mobs_mc_empty.png", "mobs_mc_zombie_butcher.png", "mobs_mc_empty.png"}, - {"mobs_mc_empty.png", "mobs_mc_zombie_farmer.png", "mobs_mc_empty.png"}, - {"mobs_mc_empty.png", "mobs_mc_zombie_librarian.png", "mobs_mc_empty.png"}, - {"mobs_mc_empty.png", "mobs_mc_zombie_priest.png", "mobs_mc_empty.png"}, - {"mobs_mc_empty.png", "mobs_mc_zombie_smith.png", "mobs_mc_empty.png"}, - {"mobs_mc_empty.png", "mobs_mc_zombie_villager.png", "mobs_mc_empty.png"}, + {"mobs_mc_zombie_butcher.png"}, + {"mobs_mc_zombie_farmer.png"}, + {"mobs_mc_zombie_librarian.png"}, + {"mobs_mc_zombie_priest.png"}, + {"mobs_mc_zombie_smith.png"}, + {"mobs_mc_zombie_villager.png"}, }, visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, @@ -119,20 +123,7 @@ mcl_mobs:register_mob("mobs_mc:villager_zombie", { villager_obj:set_yaw(yaw) villager.target_yaw = yaw villager.nametag = self.nametag - local texture = self.base_texture[1]:gsub("zombie", "villager") - if texture == "mobs_mc_villager_villager.png" then - texture = "mobs_mc_villager.png" - end - local textures = {texture} - villager.base_texture = textures - villager_obj:set_properties({textures = textures}) - local matches = {} - for prof, tex in pairs(professions) do - if texture == tex then - table.insert(matches, prof) - end - end - villager._profession = matches[math.random(#matches)] + villager._profession = "unemployed" self._curing = nil mcl_burning.extinguish(obj) obj:remove() @@ -145,6 +136,7 @@ mcl_mobs:register_mob("mobs_mc:villager_zombie", { view_range = 16, fear_height = 4, harmed_by_heal = true, + attack_npcs = true, }) mcl_mobs:spawn_specific( @@ -160,7 +152,6 @@ mcl_mobs:spawn_specific( "RoofedForest_underground", "Jungle_underground", "Swampland_underground", -"MushroomIsland_underground", "BirchForest_underground", "Plains_underground", "MesaPlateauF_underground", @@ -197,7 +188,6 @@ mcl_mobs:spawn_specific( "Plains", "Desert", "ColdTaiga", -"MushroomIsland", "IcePlainsSpikes", "SunflowerPlains", "IcePlains", @@ -224,7 +214,6 @@ mcl_mobs:spawn_specific( "ExtremeHills_beach", "ColdTaiga_beach", "Swampland_shore", -"MushroomIslandShore", "JungleM_shore", "Jungle_shore", "MesaPlateauFM_sandlevel", @@ -242,4 +231,4 @@ mcl_vars.mg_overworld_max) --mcl_mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0) +mcl_mobs.register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "#563d33", "#799c66", 0) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index f61fdb2d1..266d5b0c3 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -12,10 +12,11 @@ local S = minetest.get_translator("mobs_mc") -mcl_mobs:register_mob("mobs_mc:witch", { +mcl_mobs.register_mob("mobs_mc:witch", { description = S("Witch"), type = "monster", spawn_class = "hostile", + can_despawn = false, hp_min = 26, hp_max = 26, xp_min = 5, @@ -72,7 +73,7 @@ mcl_mobs:register_mob("mobs_mc:witch", { }) -- potion projectile (EXPERIMENTAL) -mcl_mobs:register_arrow("mobs_mc:potion_arrow", { +mcl_mobs.register_arrow("mobs_mc:potion_arrow", { visual = "sprite", visual_size = {x = 0.5, y = 0.5}, --textures = {"vessels_glass_bottle.png"}, --TODO fix to else if default @@ -104,6 +105,6 @@ mcl_mobs:register_arrow("mobs_mc:potion_arrow", { --mcl_mobs:spawn_specific("mobs_mc:witch", { "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern", "mcl_core:vine" }, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.water_level-6, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0, true) +mcl_mobs.register_egg("mobs_mc:witch", S("Witch"), "#340000", "#51a03e", 0, true) mcl_wip.register_wip_item("mobs_mc:witch") diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 3b47d0752..dda2beafa 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -9,7 +9,7 @@ local S = minetest.get_translator("mobs_mc") --################### WITHER --################### -mcl_mobs:register_mob("mobs_mc:wither", { +mcl_mobs.register_mob("mobs_mc:wither", { description = S("Wither"), type = "monster", spawn_class = "hostile", @@ -42,7 +42,7 @@ mcl_mobs:register_mob("mobs_mc:wither", { fly = true, makes_footstep_sound = false, dogshoot_switch = 1, - dogshoot_count_max =1, + dogshoot_count_max = 1, attack_animals = true, can_despawn = false, drops = { @@ -79,11 +79,13 @@ mcl_mobs:register_mob("mobs_mc:wither", { on_spawn = function(self) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) end, + }) local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false +local wither_rose_soil = { "group:grass_block", "mcl_core:dirt", "mcl_core:coarse_dirt", "mcl_nether:netherrack", "group:soul_block", "mcl_mud:mud", "mcl_moss:moss" } -mcl_mobs:register_arrow("mobs_mc:wither_skull", { +mcl_mobs.register_arrow("mobs_mc:wither_skull", { visual = "sprite", visual_size = {x = 0.75, y = 0.75}, -- TODO: 3D projectile, replace tetxture @@ -96,7 +98,7 @@ mcl_mobs:register_arrow("mobs_mc:wither_skull", { full_punch_interval = 0.5, damage_groups = {fleshy = 8}, }, nil) - mcl_mobs:boom(self, self.object:get_pos(), 1) + mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1) end, hit_mob = function(self, mob) @@ -104,17 +106,29 @@ mcl_mobs:register_arrow("mobs_mc:wither_skull", { full_punch_interval = 0.5, damage_groups = {fleshy = 8}, }, nil) - mcl_mobs:boom(self, self.object:get_pos(), 1) + mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1) + local l = mob:get_luaentity() + if l and l.health - 8 <= 0 then + local n = minetest.find_node_near(mob:get_pos(),2,wither_rose_soil) + if n then + local p = vector.offset(n,0,1,0) + if minetest.get_node(p).name == "air" then + if not ( mobs_griefing and minetest.place_node(p,{name="mcl_flowers:wither_rose"}) ) then + minetest.add_item(p,"mcl_flowers:wither_rose") + end + end + end + end end, -- node hit, explode hit_node = function(self, pos, node) - mcl_mobs:boom(self, pos, 1) + mcl_mobs.mob_class.boom(self,pos, 1) end }) -- TODO: Add blue wither skull --Spawn egg -mcl_mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true) +mcl_mobs.register_egg("mobs_mc:wither", S("Wither"), "#4f4f4f", "#4f4f4f", 0, true) mcl_wip.register_wip_item("mobs_mc:wither") diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index f2232c397..922069508 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -18,14 +18,20 @@ local wolf = { xp_max = 3, passive = false, group_attack = true, + spawn_in_group = 8, collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3}, visual = "mesh", mesh = "mobs_mc_wolf.b3d", textures = { {"mobs_mc_wolf.png"}, }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, + head_swivel = "head.control", + bone_eye_height = 3.5, + head_eye_height = 1.1, + horrizonatal_head_height=0, + curiosity = 3, + head_yaw="z", sounds = { attack = "mobs_mc_wolf_bark", war_cry = "mobs_mc_wolf_growl", @@ -64,6 +70,11 @@ local wolf = { dog:set_yaw(yaw) ent = dog:get_luaentity() ent.owner = clicker:get_player_name() + ent.tamed = true + ent:set_animation("sit") + ent.walk_chance = 0 + ent.jump = false + ent.health = self.health -- cornfirm taming minetest.sound_play("mobs_mc_wolf_bark", {object=dog, max_hear_distance=16}, true) -- Replace wolf @@ -72,10 +83,16 @@ local wolf = { end end, animation = { - speed_normal = 50, speed_run = 100, - stand_start = 40, stand_end = 45, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 50, + run_start = 0, run_end = 40, run_speed = 100, + sit_start = 45, sit_end = 45, + }, + child_animations = { + stand_start = 46, stand_end = 46, + walk_start = 46, walk_end = 86, walk_speed = 75, + run_start = 46, run_end = 86, run_speed = 150, + sit_start = 91, sit_end = 91, }, jump = true, attacks_monsters = true, @@ -83,7 +100,7 @@ local wolf = { specific_attack = { "player", "mobs_mc:sheep" }, } -mcl_mobs:register_mob("mobs_mc:wolf", wolf) +mcl_mobs.register_mob("mobs_mc:wolf", wolf) -- Tamed wolf @@ -126,7 +143,8 @@ dog.hp_max = 20 dog.textures = get_dog_textures("unicolor_red") dog.owner = "" -- TODO: Start sitting by default -dog.order = "roam" +dog.order = "sit" +dog.state = "stand" dog.owner_loyal = true dog.follow_velocity = 3.2 -- Automatically teleport dog to owner @@ -149,33 +167,12 @@ end dog.on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() - if mcl_mobs:protect(self, clicker) then + if self:feed_tame(clicker, 1, true, false) then + return + elseif mcl_mobs:protect(self, clicker) then return elseif item:get_name() ~= "" and mcl_mobs:capture_mob(self, clicker, 0, 2, 80, false, nil) then return - elseif is_food(item:get_name()) then - -- Feed to increase health - local hp = self.health - local hp_add = 0 - -- Use eatable group to determine health boost - local eatable = minetest.get_item_group(item, "eatable") - if eatable > 0 then - hp_add = eatable - elseif item:get_name() == "mcl_mobitems:rotten_flesh" then - hp_add = 4 - else - hp_add = 4 - end - local new_hp = hp + hp_add - if new_hp > self.hp_max then - new_hp = self.hp_max - end - if not minetest.is_creative_enabled(clicker:get_player_name()) then - item:take_item() - clicker:set_wielded_item(item) - end - self.health = new_hp - return elseif minetest.get_item_group(item:get_name(), "dye") == 1 then -- Dye (if possible) for group, _ in pairs(colors) do @@ -197,64 +194,33 @@ dog.on_rightclick = function(self, clicker) end end else - -- Toggle sitting order - if not self.owner or self.owner == "" then - -- Huh? This wolf has no owner? Let's fix this! This should never happen. + -- Huh? This dog has no owner? Let's fix this! This should never happen. self.owner = clicker:get_player_name() end - - local pos = self.object:get_pos() - local particle - if not self.order or self.order == "" or self.order == "sit" then - particle = "mobs_mc_wolf_icon_roam.png" - self.order = "roam" - self.walk_chance = default_walk_chance - self.jump = true - -- TODO: Add sitting model - else - particle = "mobs_mc_wolf_icon_sit.png" - self.order = "sit" - self.walk_chance = 0 - self.jump = false + if not minetest.settings:get_bool("mcl_extended_pet_control",true) then + self:toggle_sit(clicker,-0.4) end - -- Display icon to show current order (sit or roam) - minetest.add_particle({ - pos = vector.add(pos, {x=0,y=1,z=0}), - velocity = {x=0,y=0.2,z=0}, - expirationtime = 1, - size = 4, - texture = particle, - playername = self.owner, - glow = minetest.LIGHT_MAX, - }) end end -mcl_mobs:register_mob("mobs_mc:dog", dog) - +mcl_mobs.register_mob("mobs_mc:dog", dog) -- Spawn mcl_mobs:spawn_specific( "mobs_mc:wolf", "overworld", "ground", { -"FlowerForest", -"Swampland", -"Taiga", -"ExtremeHills", -"BirchForest", -"MegaSpruceTaiga", -"MegaTaiga", -"ExtremeHills+", -"Forest", -"Plains", -"ColdTaiga", -"SunflowerPlains", -"RoofedForest", -"MesaPlateauFM_grasstop", -"ExtremeHillsM", -"BirchForestM", + "Taiga", + "MegaSpruceTaiga", + "MegaTaiga", + "Forest", + "ColdTaiga", + "FlowerForest_beach", + "Forest_beach", + "ColdTaiga_beach_water", + "Taiga_beach", + "ColdTaiga_beach", }, 0, minetest.LIGHT_MAX+1, @@ -264,4 +230,4 @@ minetest.LIGHT_MAX+1, mobs_mc.water_level+3, mcl_vars.mg_overworld_max) -mcl_mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0) +mcl_mobs.register_egg("mobs_mc:wolf", S("Wolf"), "#d7d3d3", "#ceaf96", 0) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index 640b2ed11..a54f51dec 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -53,19 +53,23 @@ local zombie = { hp_max = 20, xp_min = 5, xp_max = 5, + head_swivel = "head.control", + bone_eye_height = 6.3, + head_eye_height = 2.2, + curiosity = 7, + head_pitch_multiplier=-1, breath_max = -1, + wears_armor = 1, armor = {undead = 90, fleshy = 90}, - collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.8, 0.3}, visual = "mesh", mesh = "mobs_mc_zombie.b3d", textures = { { "mobs_mc_empty.png", -- armor "mobs_mc_zombie.png", -- texture - "mobs_mc_empty.png", -- wielded_item } }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, sounds = { random = "mobs_mc_zombie_growl", @@ -85,34 +89,41 @@ local zombie = { group_attack = { "mobs_mc:zombie", "mobs_mc:baby_zombie", "mobs_mc:husk", "mobs_mc:baby_husk" }, drops = drops_zombie, animation = { - speed_normal = 25, speed_run = 50, - stand_start = 40, stand_end = 80, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, + stand_start = 40, stand_end = 49, stand_speed = 2, + walk_start = 0, walk_end = 39, speed_normal = 25, + run_start = 0, run_end = 39, speed_run = 50, + punch_start = 50, punch_end = 59, punch_speed = 20, }, ignited_by_sunlight = true, sunlight_damage = 2, view_range = 16, attack_type = "dogfight", harmed_by_heal = true, + attack_npcs = true, } -mcl_mobs:register_mob("mobs_mc:zombie", zombie) +mcl_mobs.register_mob("mobs_mc:zombie", zombie) -- Baby zombie. -- A smaller and more dangerous variant of the zombie local baby_zombie = table.copy(zombie) baby_zombie.description = S("Baby Zombie") -baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} +baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.98, 0.25} baby_zombie.xp_min = 12 baby_zombie.xp_max = 12 -baby_zombie.visual_size = {x=zombie.visual_size.x/2, y=zombie.visual_size.y/2} baby_zombie.walk_velocity = 1.2 baby_zombie.run_velocity = 2.4 baby_zombie.child = 1 +baby_zombie.reach = 1 +baby_zombie.animation = { + stand_start = 100, stand_end = 109, stand_speed = 2, + walk_start = 60, walk_end = 99, speed_normal = 40, + run_start = 60, run_end = 99, speed_run = 80, + punch_start = 109, punch_end = 119 +} -mcl_mobs:register_mob("mobs_mc:baby_zombie", baby_zombie) +mcl_mobs.register_mob("mobs_mc:baby_zombie", baby_zombie) -- Husk. -- Desert variant of the zombie @@ -122,7 +133,6 @@ husk.textures = { { "mobs_mc_empty.png", -- armor "mobs_mc_husk.png", -- texture - "mobs_mc_empty.png", -- wielded_item } } husk.ignited_by_sunlight = false @@ -130,21 +140,21 @@ husk.sunlight_damage = 0 husk.drops = drops_common -- TODO: Husks avoid water -mcl_mobs:register_mob("mobs_mc:husk", husk) +mcl_mobs.register_mob("mobs_mc:husk", husk) -- Baby husk. -- A smaller and more dangerous variant of the husk -local baby_husk = table.copy(husk) +local baby_husk = table.copy(baby_zombie) baby_husk.description = S("Baby Husk") -baby_husk.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} -baby_husk.xp_min = 12 -baby_husk.xp_max = 12 -baby_husk.visual_size = {x=zombie.visual_size.x/2, y=zombie.visual_size.y/2} -baby_husk.walk_velocity = 1.2 -baby_husk.run_velocity = 2.4 -baby_husk.child = 1 +baby_husk.textures = {{ + "mobs_mc_empty.png", -- wielded_item + "mobs_mc_husk.png", -- texture +}} +baby_husk.ignited_by_sunlight = false +baby_husk.sunlight_damage = 0 +baby_husk.drops = drops_common -mcl_mobs:register_mob("mobs_mc:baby_husk", baby_husk) +mcl_mobs.register_mob("mobs_mc:baby_husk", baby_husk) -- Spawning @@ -162,7 +172,6 @@ mcl_mobs:spawn_specific( "RoofedForest_underground", "Jungle_underground", "Swampland_underground", -"MushroomIsland_underground", "BirchForest_underground", "Plains_underground", "MesaPlateauF_underground", @@ -198,7 +207,6 @@ mcl_mobs:spawn_specific( "Forest", "Plains", "ColdTaiga", -"MushroomIsland", "IcePlainsSpikes", "SunflowerPlains", "IcePlains", @@ -225,7 +233,6 @@ mcl_mobs:spawn_specific( "ExtremeHills_beach", "ColdTaiga_beach", "Swampland_shore", -"MushroomIslandShore", "JungleM_shore", "Jungle_shore", "MesaPlateauFM_sandlevel", @@ -254,7 +261,6 @@ mcl_mobs:spawn_specific( "RoofedForest_underground", "Jungle_underground", "Swampland_underground", -"MushroomIsland_underground", "BirchForest_underground", "Plains_underground", "MesaPlateauF_underground", @@ -290,7 +296,6 @@ mcl_mobs:spawn_specific( "Forest", "Plains", "ColdTaiga", -"MushroomIsland", "IcePlainsSpikes", "SunflowerPlains", "IcePlains", @@ -317,7 +322,6 @@ mcl_mobs:spawn_specific( "ExtremeHills_beach", "ColdTaiga_beach", "Swampland_shore", -"MushroomIslandShore", "JungleM_shore", "Jungle_shore", "MesaPlateauFM_sandlevel", @@ -364,5 +368,5 @@ mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- Spawn eggs -mcl_mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0) -mcl_mobs:register_egg("mobs_mc:zombie", S("Zombie"), "mobs_mc_spawn_icon_zombie.png", 0) +mcl_mobs.register_egg("mobs_mc:husk", S("Husk"), "#777361", "#ded88f", 0) +mcl_mobs.register_egg("mobs_mc:zombie", S("Zombie"), "#00afaf", "#799c66", 0) diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua index 3d0b4f183..4e89db4f6 100644 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ b/mods/ENTITIES/mobs_mc/zombiepig.lua @@ -25,6 +25,10 @@ local pigman = { group_attack = { "mobs_mc:pigman", "mobs_mc:baby_pigman" }, damage = 9, reach = 2, + head_swivel = "head.control", + bone_eye_height = 2.4, + head_eye_height = 1.4, + curiosity = 15, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, visual = "mesh", mesh = "mobs_mc_zombie_pigman.b3d", @@ -89,7 +93,7 @@ local pigman = { fire_damage_resistant = true, } -mcl_mobs:register_mob("mobs_mc:pigman", pigman) +mcl_mobs.register_mob("mobs_mc:pigman", pigman) -- Baby pigman. -- A smaller and more dangerous variant of the pigman @@ -99,7 +103,6 @@ baby_pigman.description = S("Baby Zombie Pigman") baby_pigman.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} baby_pigman.xp_min = 13 baby_pigman.xp_max = 13 -baby_pigman.visual_size = {x=pigman.visual_size.x/2, y=pigman.visual_size.y/2} baby_pigman.textures = { { "mobs_mc_zombie_pigman.png", --baby "default_tool_goldsword.png", --sword @@ -110,7 +113,7 @@ baby_pigman.run_velocity = 2.4 baby_pigman.light_damage = 0 baby_pigman.child = 1 -mcl_mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) +mcl_mobs.register_mob("mobs_mc:baby_pigman", baby_pigman) -- Regular spawning in the Nether mcl_mobs:spawn_specific( @@ -118,7 +121,8 @@ mcl_mobs:spawn_specific( "nether", "ground", { -"Nether" +"Nether", +"CrimsonForest", }, 0, minetest.LIGHT_MAX+1, @@ -133,7 +137,8 @@ mcl_mobs:spawn_specific( "nether", "ground", { -"Nether" +"Nether", +"CrimsonForest", }, 0, minetest.LIGHT_MAX+1, @@ -147,4 +152,4 @@ mcl_vars.mg_nether_max) --mobs:spawn_specific("mobs_mc:pigman", {"mcl_portals:portal"}, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0) +mcl_mobs.register_egg("mobs_mc:pigman", S("Zombie Pigman"), "#ea9393", "#4c7129", 0) diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 3579316e8..59591b061 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -107,28 +107,7 @@ local function choose_pos(pos) return pos, pos2 end --- * pos: optional, if not given a random pos will be chosen --- * returns: bool - success if a strike happened -function lightning.strike(pos) - if lightning.auto then - after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) - end - - local pos2 - pos, pos2 = choose_pos(pos) - - if not pos then - return false - end - local 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) +function lightning.strike_func(pos, pos2, objects) local particle_pos = vector.offset(pos2, 0, (lightning.size / 2) + 0.5, 0) local particle_size = lightning.size * 10 local time = 0.2 @@ -156,23 +135,10 @@ lightning.register_on_strike(function(pos, pos2, objects) -- damage nearby objects, transform mobs for _, obj in pairs(objects) do local lua = obj:get_luaentity() - 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 - 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" } + if lua then + if not lua.on_lightning_strike or ( lua.on_lightning_strike and lua.on_lightning_strike(lua, pos, pos2, objects) ~= true ) then + mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" }) end - 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 - mcl_util.replace_mob(obj, "mobs_mc:creeper_charged") else mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" }) end @@ -182,8 +148,9 @@ lightning.register_on_strike(function(pos, pos2, objects) for i = 1, #playerlist do local player = playerlist[i] local sky = {} + local sky_table = player:get_sky(true) - sky.bgcolor, sky.type, sky.textures = player:get_sky() + sky.bgcolor, sky.type, sky.textures = sky_table.base_color, sky_table.type, sky_table.textures local name = player:get_player_name() if ps[name] == nil then @@ -227,7 +194,38 @@ lightning.register_on_strike(function(pos, pos2, objects) end end end -end) +end + +-- * pos: optional, if not given a random pos will be chosen +-- * returns: bool - success if a strike happened +function lightning.strike(pos) + if lightning.auto then + after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) + end + + local pos2 + pos, pos2 = choose_pos(pos) + + if not pos then + return false + end + local do_strike = true + if lightning.on_strike_functions then + for _, func in pairs(lightning.on_strike_functions) do + -- allow on_strike callbacks to destroy entities by re-obtaining objects for each callback + local objects = get_objects_inside_radius(pos2, 3.5) + local p,stop = func(pos, pos2, objects) + if p then + pos = p + pos2 = choose_pos(p) + end + do_strike = do_strike and not stop + end + end + if do_strike then + lightning.strike_func(pos,pos2,get_objects_inside_radius(pos2, 3.5)) + end +end -- if other mods disable auto lightning during initialization, don't trigger the first lightning. after(5, function(dtime) @@ -238,8 +236,8 @@ after(5, function(dtime) end) minetest.register_chatcommand("lightning", { - params = "[ ]", - description = S("Let lightning strike at the specified position or yourself"), + params = "[ | ]", + description = S("Let lightning strike at the specified position or player. No parameter will strike yourself."), privs = { maphack = true }, func = function(name, param) local pos = {} @@ -247,21 +245,21 @@ minetest.register_chatcommand("lightning", { pos.x = tonumber(pos.x) pos.y = tonumber(pos.y) pos.z = tonumber(pos.z) + local player_to_strike if not (pos.x and pos.y and pos.z) then pos = nil + player_to_strike = minetest.get_player_by_name(param) + if not player_to_strike and param == "" then + player_to_strike = minetest.get_player_by_name(name) + end end - if name == "" and pos == nil then + if not player_to_strike and pos == nil then return false, "No position specified and unknown player" end if pos then lightning.strike(pos) - else - local player = minetest.get_player_by_name(name) - if player then - lightning.strike(player:get_pos()) - else - return false, S("No position specified and unknown player") - end + elseif player_to_strike then + lightning.strike(player_to_strike:get_pos()) end return true end, diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.fr.tr b/mods/ENVIRONMENT/lightning/locale/lightning.fr.tr index 18c61d51c..ca0854553 100644 --- a/mods/ENVIRONMENT/lightning/locale/lightning.fr.tr +++ b/mods/ENVIRONMENT/lightning/locale/lightning.fr.tr @@ -1,4 +1,3 @@ # textdomain: lightning -@1 was struck by lightning.=@1 a été frappé par la foudre. -Let lightning strike at the specified position or yourself=Laissez la foudre frapper à la position spécifiée ou sur vous-même +Let lightning strike at the specified position or player. No parameter will strike yourself.=Fait frapper la foudre à la position spécifiée ou sur le joueur. Sans paramètre vous vous frapperez vous-même. No position specified and unknown player=Aucune position spécifiée et joueur inconnu diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.ja.tr b/mods/ENVIRONMENT/lightning/locale/lightning.ja.tr new file mode 100644 index 000000000..b84b27af0 --- /dev/null +++ b/mods/ENVIRONMENT/lightning/locale/lightning.ja.tr @@ -0,0 +1,3 @@ +# textdomain: lightning +Let lightning strike at the specified position or player. No parameter will strike yourself.=指定された位置またはプレイヤーに落雷させます。 どのパラメータも自身を攻撃しません。 +No position specified and unknown player=位置指定なし、プレイヤー不明 diff --git a/mods/ENVIRONMENT/lightning/locale/template.txt b/mods/ENVIRONMENT/lightning/locale/template.txt index 2c07393f6..2e7e5878a 100644 --- a/mods/ENVIRONMENT/lightning/locale/template.txt +++ b/mods/ENVIRONMENT/lightning/locale/template.txt @@ -1,4 +1,3 @@ # textdomain: lightning -@1 was struck by lightning.= -Let lightning strike at the specified position or yourself= +Let lightning strike at the specified position or player. No parameter will strike yourself.= No position specified and unknown player= diff --git a/mods/ENVIRONMENT/mcl_raids/init.lua b/mods/ENVIRONMENT/mcl_raids/init.lua new file mode 100644 index 000000000..8c996f0ce --- /dev/null +++ b/mods/ENVIRONMENT/mcl_raids/init.lua @@ -0,0 +1,396 @@ +-- mcl_raids +mcl_raids = {} +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Define the amount of illagers to spawn each wave. +local waves = { + { + ["mobs_mc:pillager"] = 5, + ["mobs_mc:vindicator"] = 1, + }, + { + ["mobs_mc:pillager"] = 4, + ["mobs_mc:vindicator"] = 3, + }, + { + ["mobs_mc:pillager"] = 4, + ["mobs_mc:vindicator"] = 1, + ["mobs_mc:witch"] = 1, + --["mobs_mc:ravager"] = 1, + }, + { + ["mobs_mc:pillager"] = 5, + ["mobs_mc:vindicator"] = 2, + ["mobs_mc:witch"] = 3, + }, + { + ["mobs_mc:pillager"] = 5, + ["mobs_mc:vindicator"] = 5, + ["mobs_mc:witch"] = 1, + ["mobs_mc:evoker"] = 1, + }, +} + +local extra_wave = { + ["mobs_mc:pillager"] = 5, + ["mobs_mc:vindicator"] = 5, + ["mobs_mc:witch"] = 1, + ["mobs_mc:evoker"] = 1, + --["mobs_mc:ravager"] = 2, +} + +local oban_layers = { + { + pattern = "rhombus", + color = "unicolor_cyan" + }, + { + color = "unicolor_grey", + pattern = "stripe_bottom" + }, + { + pattern = "stripe_center", + color = "unicolor_darkgrey" + }, + { + color = "unicolor_black", + pattern = "stripe_middle" + }, + { + pattern = "half_horizontal", + color = "unicolor_grey" + }, + { + color = "unicolor_grey", + pattern = "circle" + }, + { + pattern = "border", + color = "unicolor_black" + } +} + + +local oban_def = table.copy(minetest.registered_entities["mcl_banners:standing_banner"]) +oban_def.visual_size = { x=1, y=1 } +local old_step = oban_def.on_step +oban_def.on_step = function(self,dtime) + if not self.object:get_attach() then return self.object:remove() end + if old_step then return old_step(self.dtime) end +end + +minetest.register_entity(":mcl_raids:ominous_banner",oban_def) + +function mcl_raids.drop_obanner(pos) + local it = ItemStack("mcl_banners:banner_item_white") + it:get_meta():set_string("layers",minetest.serialize(oban_layers)) + it:get_meta():set_string("name",S("Ominous Banner")) + minetest.add_item(pos,it) +end + +function mcl_raids.promote_to_raidcaptain(c) -- object + if not c or not c:get_pos() then return end + local pos = c:get_pos() + local l = c:get_luaentity() + l._banner = minetest.add_entity(pos,"mcl_raids:ominous_banner") + l._banner:set_properties({textures = {mcl_banners.make_banner_texture("unicolor_white", oban_layers)}}) + l._banner:set_attach(c,"",vector.new(-1,5.5,0),vector.new(0,0,0),true) + l._raidcaptain = true + local old_ondie = l.on_die + l.on_die = function(self, pos, cmi_cause) + if l._banner then + l._banner:remove() + l._banner = nil + mcl_raids.drop_obanner(pos) + if cmi_cause and cmi_cause.type == "punch" and cmi_cause.puncher:is_player() then + awards.unlock(cmi_cause.puncher:get_player_name(), "mcl:voluntary_exile") + local lv = mcl_potions.player_get_effect(cmi_cause.puncher, "bad_omen") + if not lv then lv = 0 + else lv = lv.factor end + lv = math.max(5,lv + 1) + mcl_potions.bad_omen_func(cmi_cause.puncher,lv,6000) + end + end + if old_ondie then return old_ondie(self,pos,cmi_cause) end + end +end + +function mcl_raids.is_raidcaptain_near(pos) + for k,v in pairs(minetest.get_objects_inside_radius(pos,32)) do + local l = v:get_luaentity() + if l and l._raidcaptain then return true end + end +end + +function mcl_raids.register_possible_raidcaptain(mob) + local old_on_spawn = minetest.registered_entities[mob].on_spawn + local old_on_pick_up = minetest.registered_entities[mob].on_pick_up + if not minetest.registered_entities[mob].pick_up then minetest.registered_entities[mob].pick_up = {} end + table.insert(minetest.registered_entities[mob].pick_up,"mcl_banners:banner_item_white") + minetest.registered_entities[mob].on_pick_up = function(self,e) + local stack = ItemStack(e.itemstring) + if not self._raidcaptain and stack:get_meta():get_string("name"):find("Ominous Banner") then + stack:take_item(1) + mcl_raids.promote_to_raidcaptain(self.object) + return stack + end + if old_on_pick_up then return old_on_pick_up(self,e) end + end + minetest.registered_entities[mob].on_spawn = function(self) + if not mcl_raids.is_raidcaptain_near(self.object:get_pos()) then + mcl_raids.promote_to_raidcaptain(self.object) + end + if old_on_spawn then return old_on_spawn(self) end + end +end + +mcl_raids.register_possible_raidcaptain("mobs_mc:pillager") +mcl_raids.register_possible_raidcaptain("mobs_mc:vindicator") +mcl_raids.register_possible_raidcaptain("mobs_mc:evoker") + +function mcl_raids.spawn_raid(event) + local pos = event.pos + local wave = event.stage + local illager_count = 0 + local spawnable = false + local r = 32 + local n = 12 + local i = math.random(1, n) + local raid_pos = vector.offset(pos,r * math.cos(((i-1)/n) * (2*math.pi)),0, r * math.sin(((i-1)/n) * (2*math.pi))) + local sn = minetest.find_nodes_in_area_under_air(vector.offset(raid_pos,-5,-50,-5), vector.offset(raid_pos,5,50,5), {"group:grass_block", "group:grass_block_snow", "group:snow_cover", "group:sand", "mcl_core:ice"}) + mcl_bells.ring_once(pos) + if sn and #sn > 0 then + local spawn_pos = sn[math.random(#sn)] + if spawn_pos then + minetest.log("action", "[mcl_raids] Raid Spawn Position chosen at " .. minetest.pos_to_string(spawn_pos) .. ".") + event.health_max = 0 + local w + if event.stage <= #waves then + w= waves[event.stage] + else + w = extra_wave + end + for m,c in pairs(w) do + for i=1,c do + local p = vector.offset(spawn_pos,0,1,0) + local mob = mcl_mobs.spawn(p,m) + local l = mob:get_luaentity() + if l then + l.raidmob = true + event.health_max = event.health_max + l.health + table.insert(event.mobs,mob) + --minetest.log("action", "[mcl_raids] Here we go. Raid time") + l:gopath(pos) + end + end + end + if event.stage == 1 then + table.shuffle(event.mobs) + mcl_raids.promote_to_raidcaptain(event.mobs[1]) + end + minetest.log("action", "[mcl_raids] Raid Spawned. Illager Count: " .. #event.mobs .. ".") + return #event.mobs == 0 + else + minetest.log("action", "[mcl_raids] Raid Spawn Postion not chosen.") + end + elseif not sn then + minetest.log("action", "[mcl_raids] Raid Spawn Position error, no appropriate site found.") + end + return true +end + +function mcl_raids.find_villager(pos) + local obj = minetest.get_objects_inside_radius(pos, 8) + for _, objects in ipairs(obj) do + local object = objects:get_luaentity() + if object then + if object.name ~= "mobs_mc:villager" then + return + elseif object.name == "mobs_mc:villager" then + --minetest.log("action", "[mcl_raids] Villager Found.") + return true + else + --minetest.log("action", "[mcl_raids] No Villager Found.") + return false + end + end + end +end + +function mcl_raids.find_bed(pos) + return minetest.find_node_near(pos,32,{"mcl_beds:bed_red_bottom"}) +end + +function mcl_raids.find_village(pos) + local bed = mcl_raids.find_bed(pos) + if bed and mcl_raids.find_villager(bed) then + return bed + end +end + +local function get_point_on_circle(pos,r,n) + local rt = {} + for i=1, n do + table.insert(rt,vector.offset(pos,r * math.cos(((i-1)/n) * (2*math.pi)),0, r* math.sin(((i-1)/n) * (2*math.pi)) )) + end + table.shuffle(rt) + return rt[1] +end + +local function start_firework_rocket(pos) + local p = get_point_on_circle(pos,math.random(32,64),32) + local n = minetest.get_node(p) + local l = minetest.get_natural_light(pos,0.5) + if n.name ~= "air" or l <= minetest.LIGHT_MAX then return end + local o = minetest.add_entity(p,"mcl_bows:rocket_entity") + o:get_luaentity()._harmless = true + o:set_acceleration(vector.new(math.random(0,2),math.random(30,50),math.random(0,2))) +end + +local function make_firework(pos,stime) + if os.time() - stime > 60 then return end + for i=1,math.random(25) do + minetest.after(math.random(i),start_firework_rocket,pos) + end + minetest.after(10,make_firework,pos,stime) +end + +local function is_player_near(self) + for _,pl in pairs(minetest.get_connected_players()) do + if self.pos and vector.distance(pl:get_pos(),self.pos) < 64 then return true end + end +end + +local function check_mobs(self) + local m = {} + local h = 0 + for k,o in pairs(self.mobs) do + if o and o:get_pos() then + local l = o:get_luaentity() + h = h + l.health + table.insert(m,o) + end + end + if #m == 0 then --if no valid mobs in table search if there are any (reloaded ones) in the area + for k,o in pairs(minetest.get_objects_inside_radius(self.pos,64)) do + local l = o:get_luaentity() + if l and l.raidmob then + local l = o:get_luaentity() + h = h + l.health + table.insert(m,o) + end + end + end + self.mobs = m + return h +end + +mcl_events.register_event("raid",{ + readable_name = "Raid", + max_stage = 5, + health = 1, + health_max = 1, + exclusive_to_area = 128, + enable_bossbar = true, + cond_start = function(self) + --minetest.log("Cond start raid") + local r = {} + for _,p in pairs(minetest.get_connected_players()) do + if mcl_potions.player_has_effect(p,"bad_omen") then + local raid_pos = mcl_raids.find_village(p:get_pos()) + if raid_pos then + --minetest.log("We have a raid position. Start raid") + table.insert(r,{ player = p:get_player_name(), pos = raid_pos }) + end + end + end + if #r > 0 then return r end + end, + on_start = function(self) + self.mobs = {} + self.health_max = 1 + self.health = 0 + local lv = mcl_potions.player_get_effect(minetest.get_player_by_name(self.player), "bad_omen") + if lv and lv.factor and lv.factor > 1 then self.max_stage = 6 end + end, + cond_progress = function(self) + if not is_player_near(self) then return false end + self.health = check_mobs(self) + self.percent = math.max(0,(self.health / self.health_max ) * 100) + if #self.mobs < 1 then + return true end + end, + on_stage_begin = mcl_raids.spawn_raid, + cond_complete = function(self) + if not is_player_near(self) then return false end + --let the event api handle cancel the event when no players are near + --without this check it would sort out the unloaded mob entities and + --think the raid is defeated. + check_mobs(self) + return self.stage >= self.max_stage and #self.mobs < 1 + end, + on_complete = function(self) + awards.unlock(self.player,"mcl:hero_of_the_village") + mcl_potions.player_clear_effect(minetest.get_player_by_name(self.player),"bad_omen") + make_firework(self.pos,os.time()) + end, +}) + +minetest.register_chatcommand("raidcap",{ + privs = {debug = true}, + func = function(pname,param) + local c = minetest.add_entity(minetest.get_player_by_name(pname):get_pos(),"mobs_mc:pillager") + mcl_raids.promote_to_raidcaptain(c) + end, +}) + +minetest.register_chatcommand("dump_banner_layers",{ + privs = {debug = true}, + func = function(pname,param) + local p = minetest.get_player_by_name(pname) + mcl_raids.drop_obanner(vector.offset(p:get_pos(),1,1,1)) + for k,v in pairs(minetest.get_objects_inside_radius(p:get_pos(),5)) do + local l = v:get_luaentity() + if l and l.name == "mcl_banners:standing_banner" then + minetest.log(dump(l._base_color)) + minetest.log(dump(l._layers)) + end + end + end +}) + +local function is_new_years() + local d = os.date("*t") + return d.month == 1 and d.day == 1 and d.hour < 1 +end + +mcl_events.register_event("new_years",{ + stage = 0, + max_stage = 1, + readable_name = "New Years", + pos = vector.new(0,0,0), + exclusive_to_area = 256, + cond_start = function(event) + if not is_new_years() then return false end + local r = {} + for _,p in pairs(minetest.get_connected_players()) do + table.insert(r,{ player = p:get_player_name(), pos = p:get_pos()}) + end + return r + end, + on_start = function(self) + minetest.chat_send_player(self.player," Happy new year <3") + end, + on_step = function(self,dtime) + if not self.timer or self.timer < 0 then + self.timer = math.random(1,5) + for i=1,math.random(8) do + minetest.after(math.random(i),start_firework_rocket,minetest.get_player_by_name(self.player):get_pos()) + end + end + self.timer = self.timer - dtime + end, + cond_complete = function(event) + return not is_new_years() + end, --return success +}) diff --git a/mods/ENVIRONMENT/mcl_raids/mod.conf b/mods/ENVIRONMENT/mcl_raids/mod.conf new file mode 100644 index 000000000..b4616e56b --- /dev/null +++ b/mods/ENVIRONMENT/mcl_raids/mod.conf @@ -0,0 +1,3 @@ +name = mcl_raids +author = PrairieWind +depends = mcl_events, mobs_mc, mcl_potions, mcl_bells, mcl_achievements diff --git a/mods/ENVIRONMENT/mcl_raids/textures/mcl_raids_hero_of_the_village_icon.png b/mods/ENVIRONMENT/mcl_raids/textures/mcl_raids_hero_of_the_village_icon.png new file mode 100644 index 000000000..0db5d9613 Binary files /dev/null and b/mods/ENVIRONMENT/mcl_raids/textures/mcl_raids_hero_of_the_village_icon.png differ diff --git a/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.ja.tr b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.ja.tr new file mode 100644 index 000000000..f29ff36de --- /dev/null +++ b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_void_damage +The void is off-limits to you!=奈落は立ち入り禁止! +@1 fell into the endless void.=@1は奈落の底に落ちていった。 diff --git a/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ja.tr b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ja.tr new file mode 100644 index 000000000..c4d666aa5 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_weather +Gives ability to control weather=天候操作能力を付与 +Changes the weather to the specified parameter.=指定されたパラメータの天気を変更します。 +Error: No weather specified.=エラー:天候が指定されていません。 +Error: Invalid parameters.=エラー:パラメータが無効です。 +Error: Duration can't be less than 1 second.=エラー:持続時間は1秒以下にはできません。 +Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.=エラー:指定した天候が無効です。「晴天」、「降雨」、「降雪」、「雷雨」のいずれかを使用してください。 +Toggles between clear weather and weather with downfall (randomly rain, thunderstorm or snow)=晴天と荒天(ランダムに降雨・雷雨・降雪)を切替 diff --git a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua index a90c8e96e..023c8b20d 100644 --- a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua +++ b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua @@ -1,8 +1,10 @@ mcl_weather.nether_dust = {} mcl_weather.nether_dust.particlespawners = {} +local PARTICLES_COUNT_NETHER_DUST = tonumber(minetest.settings:get("mcl_weather_dust_particles")) or 150 + local psdef= { - amount = 150, + amount = PARTICLES_COUNT_NETHER_DUST, time = 0, minpos = vector.new(-15,-15,-15), maxpos =vector.new(15,15,15), diff --git a/mods/ENVIRONMENT/mcl_weather/rain.lua b/mods/ENVIRONMENT/mcl_weather/rain.lua index f0be39f6c..7dcc48637 100644 --- a/mods/ENVIRONMENT/mcl_weather/rain.lua +++ b/mods/ENVIRONMENT/mcl_weather/rain.lua @@ -1,7 +1,8 @@ -local PARTICLES_COUNT_RAIN = 800 -local PARTICLES_COUNT_THUNDER = 1200 +local PARTICLES_COUNT_RAIN = tonumber(minetest.settings:get("mcl_weather_rain_particles")) or 500 +local PARTICLES_COUNT_THUNDER = tonumber(minetest.settings:get("mcl_weather_thunder_particles")) or 900 local get_connected_players = minetest.get_connected_players +local mgname = minetest.get_mapgen_setting("mg_name") mcl_weather.rain = { -- max rain particles created at time @@ -20,22 +21,20 @@ 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(-15,20,-15), maxpos = vector.new(15,25,15), - minvel = vector.new(-2,-falling_speed-2,-2), - maxvel = vector.new(2,-falling_speed+2,2), + minvel = vector.new(-2,-17,-2), + maxvel = vector.new(2,-8,2), minacc = vector.new(0,0,0), maxacc = vector.new(0,-0.5,0), - minexptime = 15, - maxexptime = 30, - minsize = size, - maxsize= size*2, + minexptime = 1, + maxexptime = 4, + minsize = 4, + maxsize= 8, collisiondetection = true, collision_removal = true, vertical = true, @@ -43,6 +42,14 @@ local psdef= { local textures = {"weather_pack_rain_raindrop_1.png", "weather_pack_rain_raindrop_2.png"} +function mcl_weather.has_rain(pos) + if not mcl_worlds.has_weather(pos) then return false end + if mgname == "singlenode" or mgname == "v6" then return true end + local bd = minetest.registered_biomes[minetest.get_biome_name(minetest.get_biome_data(pos).biome)] + if bd and bd._mcl_biome_type == "hot" then return false end + return true +end + function mcl_weather.rain.sound_handler(player) return minetest.sound_play("weather_rain", { to_player = player:get_player_name(), @@ -70,9 +77,10 @@ end -- no no no NO NO f*.. no. no manual particle creatin' PLS!! this sends EVERY particle over the net. function mcl_weather.rain.add_rain_particles(player) mcl_weather.rain.last_rp_count = mcl_weather.rain.particles_count + local l = false for k,v in pairs(textures) do psdef.texture=v - mcl_weather.add_spawner_player(player,"rain"..k,psdef) + l = l or mcl_weather.add_spawner_player(player,"rain"..k,psdef) end if l then update_sound[player:get_player_name()]=true @@ -84,7 +92,7 @@ end function mcl_weather.rain.add_player(player) if mcl_weather.players[player:get_player_name()] == nil then local player_meta = {} - player_meta.origin_sky = {player:get_sky()} + player_meta.origin_sky = {player:get_sky(true)} mcl_weather.players[player:get_player_name()] = player_meta update_sound[player:get_player_name()]=true end @@ -167,13 +175,23 @@ function mcl_weather.rain.make_weather() for _, player in pairs(get_connected_players()) do local pos=player:get_pos() - if mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(pos) then + if mcl_weather.is_underwater(player) or not mcl_weather.has_rain(pos) then mcl_weather.rain.remove_sound(player) mcl_weather.remove_spawners_player(player) + if mcl_worlds.has_weather(pos) then + mcl_weather.set_sky_box_clear(player) + end else - mcl_weather.rain.add_player(player) - mcl_weather.rain.add_rain_particles(player) - mcl_weather.rain.update_sound(player) + if mcl_weather.has_snow(pos) then + mcl_weather.rain.remove_sound(player) + mcl_weather.snow.add_player(player) + mcl_weather.snow.set_sky_box() + else + mcl_weather.rain.add_player(player) + mcl_weather.rain.add_rain_particles(player) + mcl_weather.rain.update_sound(player) + mcl_weather.rain.set_sky_box() + end end end end diff --git a/mods/ENVIRONMENT/mcl_weather/skycolor.lua b/mods/ENVIRONMENT/mcl_weather/skycolor.lua index 7b6183d44..3163b0a9d 100644 --- a/mods/ENVIRONMENT/mcl_weather/skycolor.lua +++ b/mods/ENVIRONMENT/mcl_weather/skycolor.lua @@ -1,6 +1,44 @@ local mods_loaded = false local NIGHT_VISION_RATIO = 0.45 +local water_color = "#0b4880" + +local mg_name = minetest.get_mapgen_setting("mg_name") + +function mcl_weather.set_sky_box_clear(player, sky, fog) + local pos = player:get_pos() + if minetest.get_item_group(minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name, "water") ~= 0 then return end + local sc = { + day_sky = "#7BA4FF", + day_horizon = "#C0D8FF", + dawn_sky = "#B4BAFA", + dawn_horizon = "#BAC1F0", + night_sky = "#000000", + night_horizon = "#4A6790", + } + if sky then + sc.day_sky = sky + end + if fog then + sc.day_horizon = fog + end + player:set_sky({ + type = "regular", + sky_color = sc, + clouds = true, + }) +end + +function mcl_weather.set_sky_color(player, def) + local pos = player:get_pos() + if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1.5, 0)).name, "water") ~= 0 then return end + player:set_sky({ + type = def.type, + sky_color = def.sky_color, + clouds = def.clouds, + }) +end + mcl_weather.skycolor = { -- Should be activated before do any effect. active = true, @@ -9,7 +47,7 @@ mcl_weather.skycolor = { force_update = true, -- Update interval. - update_interval = 15, + update_interval = 3, -- Main sky colors: starts from midnight to midnight. -- Please do not set directly. Use add_layer instead. @@ -80,31 +118,68 @@ mcl_weather.skycolor = { for _, player in ipairs(players) do local pos = player:get_pos() local dim = mcl_worlds.pos_to_dimension(pos) + local has_weather = (mcl_worlds.has_weather(pos) and (mcl_weather.state == "snow" or mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_snow(pos)) or ((mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_rain(pos)) + if minetest.get_item_group(minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name, "water") ~= 0 then + player:set_sky({ type = "regular", + sky_color = { + day_sky = water_color, + day_horizon = water_color, + dawn_sky = water_color, + dawn_horizon = water_color, + night_sky = water_color, + night_horizon = water_color, + }, + clouds = true, + }) + end if dim == "overworld" then + local biomesky + local biomefog + if mg_name ~= "v6" and mg_name ~= "singlenode" then + local biome_index = minetest.get_biome_data(player:get_pos()).biome + local biome_name = minetest.get_biome_name(biome_index) + local biome = minetest.registered_biomes[biome_name] + if biome then + --minetest.log("action", string.format("Biome found for number: %s in biome: %s", tostring(biome_index), biome_name)) + biomesky = biome._mcl_skycolor + biomefog = biome._mcl_fogcolor + else + --minetest.log("action", string.format("No biome for number: %s in biome: %s", tostring(biome_index), biome_name)) + end + end if (mcl_weather.state == "none") then -- Clear weather - player:set_sky({ - type = "regular", - sky_color = { - day_sky = "#92B9FF", - day_horizon = "#B4D0FF", - dawn_sky = "#B4BAFA", - dawn_horizon = "#BAC1F0", - night_sky = "#006AFF", - night_horizon = "#4090FF", - }, - clouds = true, - }) + mcl_weather.set_sky_box_clear(player,biomesky,biomefog) player:set_sun({visible = true, sunrise_visible = true}) player:set_moon({visible = true}) player:set_stars({visible = true}) mcl_weather.skycolor.override_day_night_ratio(player, nil) - else + elseif not has_weather then + local day_color = mcl_weather.skycolor.get_sky_layer_color(0.15) + local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27) + local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1) + mcl_weather.set_sky_color(player, { + type = "regular", + sky_color = { + day_sky = day_color, + day_horizon = day_color, + dawn_sky = dawn_color, + dawn_horizon = dawn_color, + night_sky = night_color, + night_horizon = night_color, + }, + clouds = true, + }) + player:set_sun({visible = false, sunrise_visible = false}) + player:set_moon({visible = false}) + player:set_stars({visible = false}) + elseif has_weather then -- Weather skies local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5) local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75) local night_color = mcl_weather.skycolor.get_sky_layer_color(0) - player:set_sky({ type = "regular", + mcl_weather.set_sky_color(player, { + type = "regular", sky_color = { day_sky = day_color, day_horizon = day_color, @@ -146,8 +221,25 @@ mcl_weather.skycolor = { player:set_stars({visible = false}) mcl_weather.skycolor.override_day_night_ratio(player, 0.5) elseif dim == "nether" then - player:set_sky({ type = "plain", - base_color = "#300808", + local nether_sky = { + Nether = "#300808", + BasaltDelta = "#685F70", + SoulsandValley = "#1B4745", + CrimsonForest = "#330303", + WarpedForest = "#1A051A" + } + local biometint = nether_sky[minetest.get_biome_name(minetest.get_biome_data(player:get_pos()).biome)] + + mcl_weather.set_sky_color(player, { + type = "regular", + sky_color = { + day_sky = "#300808", + day_horizon = biometint, + dawn_sky = "#300808", + dawn_horizon = biometint, + night_sky = "#300808", + night_horizon = biometint, + }, clouds = false, }) player:set_sun({visible = false , sunrise_visible = false}) @@ -206,7 +298,7 @@ mcl_weather.skycolor = { get_current_bg_color = function() local players = mcl_weather.skycolor.utils.get_players(nil) if players[1] then - return players[1]:get_sky() + return players[1]:get_sky(true).sky_color end return nil end @@ -236,6 +328,11 @@ minetest.register_globalstep(function(dtime) end) local function initsky(player) + + if player.set_lighting then + player:set_lighting({ shadows = { intensity = tonumber(minetest.settings:get("mcl_default_shadow_intensity") or 0.33) } }) + end + if (mcl_weather.skycolor.active) then mcl_weather.skycolor.force_update = true end diff --git a/mods/ENVIRONMENT/mcl_weather/snow.lua b/mods/ENVIRONMENT/mcl_weather/snow.lua index a55428996..8de0dc0ae 100644 --- a/mods/ENVIRONMENT/mcl_weather/snow.lua +++ b/mods/ENVIRONMENT/mcl_weather/snow.lua @@ -2,11 +2,47 @@ local get_connected_players = minetest.get_connected_players mcl_weather.snow = {} -mcl_weather.snow.particles_count = 15 +local PARTICLES_COUNT_SNOW = tonumber(minetest.settings:get("mcl_weather_snow_particles")) or 100 mcl_weather.snow.init_done = false +local mgname = minetest.get_mapgen_setting("mg_name") + +local snow_biomes = { + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "IcePlains_deep_ocean", + "MegaSpruceTaiga_deep_ocean", + "IcePlainsSpikes_ocean", + "StoneBeach_ocean", + "ColdTaiga_deep_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "MegaTaiga_deep_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "IcePlains_ocean", + "Taiga_ocean", + "Taiga_deep_ocean", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "ColdTaiga_beach", + "Taiga", + "ExtremeHills+_snowtop", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "ColdTaiga", + "IcePlainsSpikes", + "IcePlains", +} local psdef= { - amount = 99, + amount = PARTICLES_COUNT_SNOW, time = 0, --stay on til we turn it off minpos = vector.new(-25,20,-25), maxpos =vector.new(25,25,25), @@ -14,9 +50,9 @@ local psdef= { maxvel = vector.new(0.2,-4,0.2), minacc = vector.new(0,-1,0), maxacc = vector.new(0,-4,0), - minexptime = 15, - maxexptime = 30, - minsize = 0.5, + minexptime = 3, + maxexptime = 5, + minsize = 2, maxsize = 5, collisiondetection = true, collision_removal = true, @@ -25,6 +61,19 @@ local psdef= { glow = 1 } +function mcl_weather.has_snow(pos) + if not mcl_worlds.has_weather(pos) then return false end + if mgname == "singlenode" or mgname == "v6" then return false end + local bn = minetest.get_biome_name(minetest.get_biome_data(pos).biome) + local bd = minetest.registered_biomes[bn] + if bd and bd._mcl_biome_type == "snowy" then return true end + if bd and bd._mcl_biome_type == "cold" then + if bn == "Taiga" and pos.y > 140 then return true end + if bn == "MegaSpruceTaiga" and pos.y > 100 then return true end + end + return false +end + function mcl_weather.snow.set_sky_box() mcl_weather.skycolor.add_layer( "weather-pack-snow-sky", @@ -46,9 +95,11 @@ function mcl_weather.snow.clear() mcl_weather.remove_all_spawners() end --- Simple random texture getter -function mcl_weather.snow.get_texture() - return "weather_pack_snow_snowflake"..math.random(1,2)..".png" +function mcl_weather.snow.add_player(player) + for i=1,2 do + psdef.texture="weather_pack_snow_snowflake"..i..".png" + mcl_weather.add_spawner_player(player,"snow"..i,psdef) + end end local timer = 0 @@ -70,13 +121,12 @@ 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_weather.has_snow(player:get_pos()) then mcl_weather.remove_spawners_player(player) + mcl_weather.set_sky_box_clear(player) else - for i=1,2 do - psdef.texture="weather_pack_snow_snowflake"..i..".png" - mcl_weather.add_spawner_player(player,"snow"..i,psdef) - end + mcl_weather.snow.add_player(player) + mcl_weather.snow.set_sky_box() end end end) @@ -96,3 +146,39 @@ if mcl_weather.reg_weathers.snow == nil then } } end + +minetest.register_abm({ + label = "Snow piles up", + nodenames = {"group:opaque","group:leaves","group:snow_cover"}, + neighbors = {"air"}, + interval = 27, + chance = 33, + min_y = mcl_vars.mg_overworld_min, + action = function(pos, node, active_object_count, active_object_count_wider) + if (mcl_weather.state ~= "rain" and mcl_weather.state ~= "thunder" and mcl_weather.state ~= "snow") + or not mcl_weather.has_snow(pos) + or node.name == "mcl_core:snowblock" then + return end + + local above = vector.offset(pos,0,1,0) + local above_node = minetest.get_node(above) + + if above_node.name == "air" and mcl_weather.is_outdoor(pos) then + local nn = nil + if node.name:find("snow") then + local l = node.name:sub(-1) + l = tonumber(l) + if node.name == "mcl_core:snow" then + nn={name = "mcl_core:snow_2"} + elseif l and l < 7 then + nn={name="mcl_core:snow_"..tostring(math.min(8,l + 1))} + elseif l and l >= 7 then + nn={name = "mcl_core:snowblock"} + end + if nn then minetest.set_node(pos,nn) end + else + minetest.set_node(above,{name = "mcl_core:snow"}) + end + end + end +}) diff --git a/mods/ENVIRONMENT/mcl_weather/weather_core.lua b/mods/ENVIRONMENT/mcl_weather/weather_core.lua index f7316bcfb..32d8db4df 100644 --- a/mods/ENVIRONMENT/mcl_weather/weather_core.lua +++ b/mods/ENVIRONMENT/mcl_weather/weather_core.lua @@ -54,6 +54,8 @@ function mcl_weather.add_spawner_player(pl,id,ps) particlespawners[name] = {} end if not particlespawners[name][id] then + mcl_weather.remove_spawners_player(pl) + particlespawners[name] = {} ps.playername =name ps.attached = pl particlespawners[name][id]=minetest.add_particlespawner(ps) diff --git a/mods/ENVIRONMENT/mcl_zombie_sieges/init.lua b/mods/ENVIRONMENT/mcl_zombie_sieges/init.lua new file mode 100644 index 000000000..21c644cda --- /dev/null +++ b/mods/ENVIRONMENT/mcl_zombie_sieges/init.lua @@ -0,0 +1,90 @@ + +local function check_spawn_pos(pos) + return minetest.get_natural_light(pos) < 7 +end + +local function spawn_zombies(self) + local nn = minetest.find_nodes_in_area_under_air(vector.offset(self.pos,-16,-16,-16),vector.offset(self.pos,16,16,16),{"group:solid"}) + table.shuffle(nn) + for i=1,20 do + local p = vector.offset(nn[i%#nn],0,1,0) + if check_spawn_pos(p) then + local m = mcl_mobs.spawn(p,"mobs_mc:zombie") + if m then + local l = m:get_luaentity() + l:gopath(self.pos) + table.insert(self.mobs, m) + self.health_max = self.health_max + l.health + else + --minetest.log("Failed to spawn zombie at location: " .. minetest.pos_to_string(p)) + end + end + end +end + +mcl_events.register_event("zombie_siege",{ + readable_name = "Zombie Siege", + max_stage = 1, + health = 1, + health_max = 1, + exclusive_to_area = 128, + enable_bossbar = false, + cond_start = function(self) + --minetest.log("Cond start zs") + local r = {} + + local t = minetest.get_timeofday() + local pr = PseudoRandom(minetest.get_day_count()) + local rnd = pr:next(1,10) + + if t < 0.04 and rnd == 1 then + --minetest.log("Well, it's siege time") + for _,p in pairs(minetest.get_connected_players()) do + local village = mcl_raids.find_village(p:get_pos()) + if village then + --minetest.log("Found village") + table.insert(r,{ player = p:get_player_name(), pos = village}) + end + end + else + --minetest.log("Not night for a siege, or not success") + end + if #r > 0 then return r end + end, + on_start = function(self) + self.mobs = {} + self.health_max = 1 + self.health = 0 + end, + cond_progress = function(self) + local m = {} + local h = 0 + for k,o in pairs(self.mobs) do + if o and o:get_pos() then + local l = o:get_luaentity() + h = h + l.health + table.insert(m,o) + end + end + self.mobs = m + self.health = h + self.percent = math.max(0,(self.health / self.health_max ) * 100) + if #m < 1 then + return true end + end, + on_stage_begin = spawn_zombies, + cond_complete = function(self) + local m = {} + for k,o in pairs(self.mobs) do + if o and o:get_pos() then + local l = o:get_luaentity() + table.insert(m,o) + end + end + return self.stage >= self.max_stage and #m < 1 + end, + on_complete = function(self) + --minetest.log("SIEGE complete") + --awards.unlock(self.player,"mcl:hero_of_the_village") + end, +}) diff --git a/mods/ENVIRONMENT/mcl_zombie_sieges/mod.conf b/mods/ENVIRONMENT/mcl_zombie_sieges/mod.conf new file mode 100644 index 000000000..0263d367a --- /dev/null +++ b/mods/ENVIRONMENT/mcl_zombie_sieges/mod.conf @@ -0,0 +1,3 @@ +name = mcl_zombie_sieges +author = cora +depends = mcl_events, mcl_raids diff --git a/mods/HELP/doc/doc/locale/doc.ja.tr b/mods/HELP/doc/doc/locale/doc.ja.tr new file mode 100644 index 000000000..68cc90232 --- /dev/null +++ b/mods/HELP/doc/doc/locale/doc.ja.tr @@ -0,0 +1,51 @@ +# textdomain:doc +<=< +>=> +Access to the requested entry has been denied; this entry is secret. You may unlock access by progressing in the game. Figure out on your own how to unlock this entry.=リクエストされたエントリーへのアクセスは拒否されました:このエントリーはシークレット要素です。ゲームを進行することでアクセスのロックを解除できるでしょう。このエントリーをアンロックする方法は、ご自身で見当をつけてみてください。 +All entries read.=すべてのエントリーを読みます。 +All help entries revealed!=ヘルプの全エントリーを公開! +All help entries are already revealed.=ヘルプのエントリーはすべて公開済みです。 +Allows you to reveal all hidden help entries with /help_reveal=/help_reveal で隠れているヘルプエントリーをすべて表示できるようにする +Category list=カテゴリーリスト +Currently all entries in this category are hidden from you.=現在、このカテゴリのエントリーはすべて非表示になっています。 +Unlock new entries by progressing in the game.=ゲームを進めることで、新たな項目をアンロックできます。 +Help=ヘルプ +Entry=エントリー +Entry list=エントリーリスト +Error: Access denied.=エラー:アクセスが拒否されました。 +Error: No help available.=エラー:利用可能なヘルプはありません。 +Go to category list=カテゴリーリストへ +Go to entry list=エントリーリストへ +Help > @1=ヘルプ > @1 +Help > @1 > @2=ヘルプ > @1 > @2 +Help > @1 > (No Entry)=ヘルプ > @1 > (エントリーなし) +Help > (No Category)=ヘルプ > (カテゴリーなし) +Hidden entries: @1=隠れているエントリー:@1 +Nameless entry (@1)=名無しのエントリー (@1) +New entries: @1=新しいエントリー:@1 +New help entry unlocked: @1 > @2=新しいヘルプエントリーがアンロックされた:@1 > @2 +No categories have been registered, but they are required to provide help.=カテゴリーは登録されてませんが、ヘルプを提供することが求められています。 +The Documentation System [doc] does not come with help contents on its own, it needs additional mods to add help content. Please make sure such mods are enabled on for this world, and try again.=ドキュメンテーションシステム[doc]は、それ自体ではヘルプコンテンツを備えておらず、ヘルプコンテンツを追加するための追加MODが必要です。そのようなMODがこのワールドで有効になっていることを確認し、もう一度試してみてください。 +Number of entries: @1=エントリー数:@1 +OK=OK +Open a window providing help entries about Minetest and more=Minetestに関するヘルプなどを表示するウィンドウを開く +Please select a category you wish to learn more about:=詳細を知りたいカテゴリーを選択してください: +Recommended mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia.=推奨MOD:doc_basics、doc_items、doc_identifier、doc_encyclopedia +Reveal all hidden help entries to you=隠れているヘルプをすべて表示する +Show entry=エントリーを表示 +Show category=カテゴリーを表示 +Show next entry=次のエントリーを表示 +Show previous entry=前のエントリーを表示 +This category does not have any entries.=このカテゴリにはエントリーがありません。 +This category has the following entries:=このカテゴリには以下のエントリーがあります: +This category is empty.=このカテゴリは空っぽです。 +This is the help.=これはヘルプです。 +You haven't chosen a category yet. Please choose one in the category list first.=まだカテゴリーが選択されていません。まずはカテゴリーリストからひとつ選択してください。 +You haven't chosen an entry yet. Please choose one in the entry list first.=まだエントリーが選択されていません。まずはエントリーリストからひとつ選択してください。 +Collection of help texts=ヘルプテキスト集 +Notify me when new help is available=新しいヘルプが利用可能になったら通知する +Play notification sound when new help is available=新しいヘルプが利用可能になったときに通知音を再生する +Show previous image=前の画像を表示 +Show previous gallery page=前のギャラリーページを表示 +Show next image=次の画像を表示 +Show next gallery page=次のギャラリーページを表示 diff --git a/mods/HELP/doc/doc_identifier/locale/doc_identifier.ja.tr b/mods/HELP/doc/doc_identifier/locale/doc_identifier.ja.tr new file mode 100644 index 000000000..2a545f742 --- /dev/null +++ b/mods/HELP/doc/doc_identifier/locale/doc_identifier.ja.tr @@ -0,0 +1,18 @@ +# textdomain:doc_identifier +Error: This node, item or object is undefined. This is always an error.=エラー:このノード、アイテム、またはオブジェクトは未定義です。これは常にエラーになります。 +This can happen for the following reasons:=これは、次のような理由で起こり得ます: +• The mod which is required for it is not enabled=・そのために必要なMODが有効になっていない +• The author of the game or a mod has made a mistake=・ゲームの作者やMODがミスをした場合 +It appears to originate from the mod “@1”, which is enabled.=有効になっているMOD“@1”から発生しているようです。 +It appears to originate from the mod “@1”, which is not enabled!=有効化されていないMOD“@1”から発生しているようです! +Its identifier is “@1”.=その識別子は“@1”です。. +Lookup Tool=検索ツール +No help entry for this block could be found.=このブロックのヘルプエントリーは見つかりませんでした。 +No help entry for this item could be found.=このアイテムのヘルプエントリーは見つかりませんでした。 +No help entry for this object could be found.=このオブジェクトのヘルプエントリーは見つかりませんでした。 +OK=OK +Punch any block, item or other thing about you wish to learn more about. This will open up the appropriate help entry. The tool comes in two modes which are changed by using. In liquid mode, this tool points to liquids as well while in solid mode this is not the case.=ブロックやアイテムなど、詳しく知りたいものをパンチしてください。すると適切なヘルプエントリーが表示されます。この道具には2つのモードがあり、使用することで変更されます。液体モードでは、この道具は液体もポイントしますが、固体モードではそのようなことはありません。 +This block cannot be identified because the world has not materialized at this point yet. Try again in a few seconds.= +This is a player.=このブロックは、この時点ではまだ世界が具現化されていないため、識別できません。数秒後に再試行してください。 +This useful little helper can be used to quickly learn more about about one's closer environment. It identifies and analyzes blocks, items and other things and it shows extensive information about the thing on which it is used.=この便利な小さいヘルプ機能は、自分の身近な環境について手っ取り早く知るために使えます。ブロックやアイテムなどを識別して分析し、使用されているものに関する幅広い情報を表示します。 +Show help for pointed thing=ポイントしたものをヘルプで表示する diff --git a/mods/HELP/doc/doc_items/locale/doc_items.ja.tr b/mods/HELP/doc/doc_items/locale/doc_items.ja.tr new file mode 100644 index 000000000..a2e1107de --- /dev/null +++ b/mods/HELP/doc/doc_items/locale/doc_items.ja.tr @@ -0,0 +1,143 @@ +# textdomain:doc_items +Using it as fuel turns it into: @1.=燃料として使うと次のように変化します:@1. +@1 seconds=@1秒 +# Item count times item name +@1×@2=@1×@2 +# Itemname (25%) +@1 (@2%)=@1 (@2%) +# Itemname (<0.5%) +@1 (<0.5%)=@1 (<0.5%) +# Itemname (ca. 25%) +@1 (ca. @2%)=@1 (ca. @2%) +# List separator (e.g. “one, two, three”) +, =、 +# Final list separator (e.g. “One, two and three”) + and =& +1 second=1秒 +A transparent block, basically empty space. It is usually left behind after digging something.=透明なブロックで、基本的には何もない空間です。たいていは何かを掘った後に残ります。 +Air=空気 +Blocks=ブロック +Building another block at this block will place it inside and replace it.=このブロックのところに別のブロックを構築すると、中に入って置き換わります。 +Building this block is completely silent.=このブロックの構築は、完全に無音です。 +Collidable: @1=衝突性:@1 +Description: @1=概要:@1 +Falling blocks can go through this block; they destroy it when doing so.=落下したブロックは、このブロックをスルーできますが、その際にブロックを破壊してしまいます。 +Full punch interval: @1 s=全力攻撃の間隔:@1秒 +Hand=手 +Hold it in your hand, then leftclick to eat it.=手に持って、左クリックで食べます。 +Hold it in your hand, then leftclick to eat it. But why would you want to do this?=手に持って、左クリックで食べます。しかし、なぜこんなことをしたいのでしょうか? +Item reference of all wieldable tools and weapons=すべての携行可能な道具と武器の、アイテム参照 +Item reference of blocks and other things which are capable of occupying space=空間の占有が可能なブロックその他の、アイテム参照 +Item reference of items which are neither blocks, tools or weapons (esp. crafting items)=ブロックでも道具でも武器でもないアイテム(特にクラフトアイテム)の、アイテム参照 +Liquids can flow into this block and destroy it.=このブロックに液体が流れ込み、破壊されることがあります。 +Maximum stack size: @1=最大スタックサイズ:@1 +Mining level: @1=採掘レベル:@1 +Mining ratings:=採掘レート: +• @1, rating @2: @3 s - @4 s=・ @1, レート @2:@3秒 - @4秒 +• @1, rating @2: @3 s=・ @1, レート @2:@3秒 +Mining times:=採掘時間: +Mining this block is completely silent.=このブロックの採掘は、完全に無音です。 +Miscellaneous items=その他の雑多なアイテム +No=いいえ +Pointable: No=ポイント可能:いいえ +Pointable: Only by special items=ポイント可能:特殊なアイテムのみ +Pointable: Yes=ポイント可能:はい +Punches with this block don't work as usual; melee combat and mining are either not possible or work differently.=このブロックでのパンチは、普段通りには機能しません:近接戦闘と採掘は不可能か、動作が異なります。 +Punches with this item don't work as usual; melee combat and mining are either not possible or work differently.=このアイテムでのパンチは、普段通りには機能しません:近接戦闘と採掘は不可能か、動作が異なります。 +Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently.=この道具でのパンチは、普段通りには機能しません:近接戦闘と採掘は不可能か、動作が異なります。 +Range: @1=範囲:@1 +# Range: () +Range: @1 (@2)=範囲:@1 (@2) +Range: 4=範囲:4 +# Rating used for digging times +Rating @1=レート@1 +# @1 is minimal rating, @2 is maximum rating +Rating @1-@2=レート@1-@2 +The fall damage on this block is increased by @1%.=このブロックでの落下ダメージが@1%増加する。 +The fall damage on this block is reduced by @1%.=このブロックでの落下ダメージが@1%軽減する。 +This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly.=このブロックは、明るさのロスが少ない光の伝搬を可能にし、太陽光であればロスなしで通過することさえできます。 +This block allows light to propagate with a small loss of brightness.=このブロックは、明るさのロスが少ない光の伝搬を可能にします。 +This block allows sunlight to propagate without loss in brightness.=このブロックは、太陽光を明るさのロスなしで伝搬させることができます。 +This block belongs to the @1 group.=このブロックは、@1グループに属しています。 +This block belongs to these groups: @1.=このブロックは、次のグループに属しています:@1 +This block can be climbed.=このブロックはよじ登ることができます。 +This block can be destroyed by any mining tool immediately.=このブロックは、どの採掘道具でも即座に壊せます。 +This block can be destroyed by any mining tool in half a second.=このブロックは、どの採掘道具でもコンマ5秒で壊せます。 +This block can be mined by any mining tool immediately.=このブロックは、どの採掘道具でも即座に掘れます。 +This block can be mined by any mining tool in half a second.=このブロックは、どの採掘道具でもコンマ5秒で掘れます。 +This block can be mined by mining tools which match any of the following mining ratings and its toughness level.=このブロックは、以下の採掘レートとタフネスレベルのいずれかに合致する採掘道具で掘れます。 +This block can not be destroyed by ordinary mining tools.=このブロックは、通常の採掘道具では壊せません。 +This block can not be mined by ordinary mining tools.=このブロックは、通常の採掘道具では掘れません。 +This block can serve as a smelting fuel with a burning time of @1.=このブロックは、燃焼時間@1の製錬燃料として使用できます。 +This block causes a damage of @1 hit point per second.=このブロックは、毎秒@1HPのダメージを生じます。 +This block causes a damage of @1 hit points per second.=このブロックは、毎秒@1HPのダメージを生じます。 +This block connects to blocks of the @1 group.=このブロックは、@1グループのブロックに接続します。 +This block connects to blocks of the following groups: @1.=このブロックは、次のグループのブロックに接続します:@1 +This block connects to these blocks: @1.=このブロックは、次のブロックに接続します:@1 +This block connects to this block: @1.=このブロックは、このブロックに接続します:@1 +This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds.=このブロックは呼吸を減少させ, 2秒毎に@1HPの窒息ダメージを与えます. +This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.=このブロックは呼吸を減少させ, 2秒毎に@1HPの窒息ダメージを与えます. +This block is a light source with a light level of @1.=このブロックは、明るさ@1の光源です。 +This block glows faintly with a light level of @1.=このブロックは、明るさ@1でぼんやりと光ります。 +This block is a building block for creating various buildings.=このブロックは、さまざまな建物を作るための建築ブロックです。 +This block is a liquid with these properties:=このブロックは、こうした性質を持つ液体です: +This block is affected by gravity and can fall.=このブロックは重力の影響を受け、落下することがあります。 +This block is completely silent when mined or built.=このブロックを採掘や建設する時は、完全に無音です。 +This block is completely silent when walked on, mined or built.=このブロックを採掘・建設・歩行する時は、完全に無音です。 +This block is destroyed when a falling block ends up inside it.=このブロックは、落下してきたブロックがその中に入ってしまうと破壊されます。 +This block negates all fall damage.=このブロックは、すべての落下ダメージを無効化します。 +This block points to liquids.=このブロックは液体を指します。 +This block will drop as an item when a falling block ends up inside it.=このブロックは、落下してきたブロックがその中に入ってしまうと、アイテムとしてドロップされます。 +This block will drop as an item when it is not attached to a surrounding block.=このブロックは、周囲のブロックとくっついていないときに、アイテムとしてドロップされます。 +This block will drop as an item when no collidable block is below it.=このブロックは、その下に衝突可能なブロックがない場合、アイテムとしてドロップされます。 +This block will drop the following items when mined: @1.=このブロックを掘ると、次のアイテムをドロップします:@1 +This block will drop the following when mined: @1×@2.=このブロックを掘ると、次のものをドロップします:@1×@2 +This block will drop the following when mined: @1.=このブロックを掘ると、次のものをドロップします:@1 +This block will drop the following when mined: @1.=このブロックを掘ると、次のものをドロップします:@1 +This block will make you bounce off with an elasticity of @1%.=このブロックは、@1%の弾力性で跳ね返します。 +This block will randomly drop one of the following when mined: @1.=このブロックを掘ると、次のいずれかがランダムにドロップされます:@1 +This block will randomly drop up to @1 drops of the following possible drops when mined: @2.=このブロックを掘ると、次の可能なドロップのうち、最大@1個をランダムにドロップします:@2 +This block won't drop anything when mined.=このブロックは、掘っても何もドロップしません。 +This is a decorational block.=これは装飾用のブロックです。 +This is a melee weapon which deals damage by punching.=これは殴りつけることでダメージを与える近接武器です。 +Maximum damage per hit:=一発あたりの最大ダメージ: +This item belongs to the @1 group.=このアイテムは、@1グループに属しています。 +This item belongs to these groups: @1.=このアイテムは、次のグループに属しています:@1 +This item can serve as a smelting fuel with a burning time of @1.=このアイテムは、燃焼時間@1の製錬燃料として使用できます。 +This item is primarily used for crafting other items.=このアイテムは主に、他のアイテムのクラフトに使われます。 +This item points to liquids.=このアイテムは液体を指します。 +This tool belongs to the @1 group.=この道具は、@1グループに属しています。 +This tool belongs to these groups: @1.=この道具は、次のグループに属しています:@1 +This tool can serve as a smelting fuel with a burning time of @1.=この道具は、燃焼時間@1の製錬燃料として使用できます。 +This tool is capable of mining.=この道具は採掘が可能です。 +Maximum toughness levels:=最大タフネスレベル: +This tool points to liquids.=この道具は液体を指します。 +Tools and weapons=道具と武器 +Unknown Node=不明なノード +Usage help: @1=使用方法のヘルプ:@1 +Walking on this block is completely silent.=このブロックを歩くと、完全に無音です。 +Whenever you are not wielding any item, you use the hand which acts as a tool with its own capabilities. When you are wielding an item which is not a mining tool or a weapon it will behave as if it would be the hand.=アイテムを手に持っていない時は、なんどきでも素手を道具として使えます。採掘道具でも武器でもないアイテムを手に持っている時は、あたかも素手であるかのように振る舞います。 +Yes=はい +You can not jump while standing on this block.=このブロックの上に立っている間は、ジャンプできません。 +any level=任意のレベル +level 0=レベル 0 +level 0-@1=レベル 0-@1 +unknown=不明 +Unknown item (@1)=不明なアイテム (@1) +• @1: @2=・@1:@2 +• @1: @2 HP=・@1:@2 HP +• @1: @2, @3=・@1:@2, @3 +• Flowing range: @1=・流動範囲:@1 +• No flowing=・流れない +• Not renewable=・再生不能 +• Renewable=・再生可能 +• Viscosity: @1=・粘度:@1 +Itemstring: "@1"=アイテム文字列:"@1" +Durability: @1 uses=耐久度:@1回 使用 +Durability: @1=耐久度:@1 +Mining durability:=採掘耐久度: +• @1, level @2: @3 uses=・@1, レベル @2:@3回 使用 +• @1, level @2: Unlimited=・@1, レベル @2:無限 +This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.=このブロックの回転は、置き方に影響されます:床や天井に置くと垂直方向、横に置くと水平方向になります。スニークしながら置くと、代わって直角の方向に向きます。 +Toughness level: @1=タフネスレベル:@1 +This block is slippery.=このブロックは滑りやすいです。 diff --git a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ja.tr b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ja.tr new file mode 100644 index 000000000..213a68f61 --- /dev/null +++ b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ja.tr @@ -0,0 +1,37 @@ +# textdomain: craftguide +Any shulker box=シュルカーボックス +Any wool=羊毛 +Any wood planks=板材 +Any wood=木 +Any sand=砂 +Any normal sandstone=普通の砂岩 +Any red sandstone=赤い砂岩 +Any carpet=カーペット +Any dye=染料 +Any water bucket=水入りバケツ +Any flower=花 +Any mushroom=キノコ +Any wooden slab=木製のスラブ +Any wooden stairs=木製の階段 +Any coal=石炭 +Any kind of quartz block=クォーツブロック +Any kind of purpur block=プルプァブロック +Any stone bricks=石レンガ +Any stick=棒 +Any item belonging to the @1 group=@1 グループに属する任意のアイテム +Any item belonging to the groups: @1=次のグループに属する任意のアイテム:@1 +Search=検索 +Reset=リセット +Previous page=前ページ +Next page=次ページ +Usage @1 of @2=使用方法 @1/@2 +Recipe @1 of @2=レシピ @1/@2 +Burning time: @1=燃焼時間:@1 +Cooking time: @1=調理時間:@1 +Recipe is too big to be displayed (@1×@2)=レシピを表示するには大きすぎる (@1×@2) +Shapeless=不定形 +Cooking=調理 +Increase window size=ウィンドウサイズ拡大 +Decrease window size=ウィンドウサイズ縮小 +No item to show=表示するアイテムなし +Collect items to reveal more recipes=アイテムを集めて、より多くのレシピを明かす diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr b/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr new file mode 100644 index 000000000..0cef853c8 --- /dev/null +++ b/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr @@ -0,0 +1,79 @@ +# textdomain: mcl_doc +Water can flow into this block and cause it to drop as an item.=このブロックに水が流れ込むと、アイテムとしてドロップすることがあります。 +This block can be turned into dirt with a hoe.=このブロックは、クワで土に変えられます。 +This block can be turned into farmland with a hoe.=このブロックは、クワで農地に変えられます。 +This block acts as a soil for all saplings.=このブロックは、あらゆる苗木の土壌として作用します。 +This block acts as a soil for some saplings.=このブロックは、いくつかの苗木の土壌として作用します。 +Sugar canes will grow on this block.=このブロックには、サトウキビが生育します。 +Nether wart will grow on this block.=このブロックには、ネザーウォートが生育します。 +This block quickly decays when there is no wood block of any species within a distance of @1. When decaying, it disappears and may drop one of its regular drops. The block does not decay when the block has been placed by a player.=このブロックは、@1の距離内にどの種の木材ブロックもないとき、たちまち腐敗します。 腐敗すると消滅し、通常のドロップを1つ落とすことがあります。ブロックがプレイヤーによって置かれているときは、朽ちることはありません。 +This block quickly decays and disappears when there is no wood block of any species within a distance of @1. The block does not decay when the block has been placed by a player.=このブロックは、@1の距離内にどの種の木材ブロックもないとき、すぐさま腐敗して消滅します。 +This plant can only grow on grass blocks and dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher.=この植物は、草原や土の上にしか生育できません。生え抜くためには、上空に遮るものがないか、明るさ8以上で照らされる環境が必要です。 +This plant can grow on grass blocks, podzol, dirt and coarse dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher.=この植物は、草原、ポドゾル、土、粗い土の上に生育できます。生え抜くためには、上空に遮るものがないか、明るさ8以上で照らされる環境が必要です。 +This block is flammable.=このブロックは可燃性です。 +This block destroys any item it touches.=このブロックは、それに触れたどんなアイテムも壊します。 +To eat it, wield it, then rightclick.=食べるには、手に持ってから右クリックします。 +You can eat this even when your hunger bar is full.=満腹ゲージが満タンでも、これは食べられます。 +You cannot eat this when your hunger bar is full.=満腹ゲージが満タンなら、これは食べられません。 +To drink it, wield it, then rightclick.=飲むには、手に持ってから右クリックします。 +You cannot drink this when your hunger bar is full.=満腹ゲージが満タンなら、これは飲めません。 +To consume it, wield it, then rightclick.=消費するには、手に持ってから右クリックします。 +You cannot consume this when your hunger bar is full.=満腹ゲージが満タンなら、これは消費できません。 +You have to wait for about 2 seconds before you can eat or drink again.=また飲み食いできるようになるまで、2秒くらい待たねばなりません。 +Hunger points restored: @1=満腹度回復:@1 +Saturation points restored: @1%.1f=隠し満腹度回復:@1.1f +This item can be repaired at an anvil with: @1.=このアイテムは、金床と次のもので修理できます:@1 +This item can be repaired at an anvil with any wooden planks.=このアイテムは、金床と板材で修理できます。 +This item can be repaired at an anvil with any item in the “@1” group.=このアイテムは、金床と"@1"グループのアイテムで修理できます。 +This item cannot be renamed at an anvil.=このアイテムは、金床で名前を変更できません。 +This block crushes any block it falls into.=このブロックが落ちると、どんなブロックでも潰します。 +When this block falls deeper than 1 block, it causes damage to any player it hits. The damage dealt is B×2−2 hit points with B @= number of blocks fallen. The damage can never be more than 40 HP.=このブロックが1ブロックより深く落ちたとき、当たったプレイヤーにダメージを与えます。受けるダメージは B×2 -2HP と B @=落ちたブロック数。ダメージは40HP以上になることはありません。 +Diamond Pickaxe=ダイヤモンドのツルハシ +Iron Pickaxe=鉄のツルハシ +Stone Pickaxe=石のツルハシ +Golden Pickaxe=金のツルハシ +Wooden Pickaxe=木製のツルハシ +Diamond Axe=ダイヤモンドの斧 +Iron Axe=鉄の斧 +Stone Axe=石の斧 +Golden Axe=金の斧 +Wooden Axe=木製の斧 +Diamond Shovel=ダイヤモンドのシャベル +Iron Shovel=鉄のシャベル +Stone Shovel=石のシャベル +Golden Shovel=金のシャベル +Wooden Shovel=木製のシャベル +This block can be mined by any tool instantly.=このブロックは、どんな道具を使ってもすぐに掘れます。 +This block can be mined by:=このブロックは次のもので掘れます: +Hardness: ∞=硬さ:∞ +Hardness: @1=硬さ:@1 +This block will not be destroyed by TNT explosions.=このブロックは、TNTの爆発では壊れません。 +This block drops itself when mined by shears.=このブロックはハサミで掘ると、それ自体をドロップします。 +@1×@2=@1×@2 +This blocks drops the following when mined by shears: @1=このブロックはハサミで掘ると、次のものをドロップします:@1 +, =, +• Shears=・ハサミ +• Sword=・剣 +• Hand=・手 +This is a melee weapon which deals damage by punching.=これは殴りつけることでダメージを与える近接武器です。 +Maximum damage: @1 HP=最大ダメージ:@1 HP +Full punch interval: @1 s=全力攻撃の間隔:@1秒 +This tool is capable of mining.=この道具は採掘が可能です。 +Mining speed: @1=採掘速度:@1 +Painfully slow=苦痛レベルで遅い +Very slow=とても遅い +Slow=遅い +Fast=速い +Very fast=とても速い +Extremely fast=とてつもなく速い +Instantaneous=瞬間的 +@1 uses=@1 使用 +Unlimited uses=無限に使用可能 +Block breaking strength: @1=ブロック破壊力:@1 +Mining durability: @1=採掘耐久度:@1 +Armor points: @1=防具値:@1 +Armor durability: @1=防具耐久度:@1 +It can be worn on the head.=頭に装着することもできます。 +It can be worn on the torso.=胴体に装着することもできます。 +It can be worn on the legs.=脚部に装着することもできます。 +It can be worn on the feet.=足に装着することもできます。 diff --git a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ja.tr b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ja.tr new file mode 100644 index 000000000..bde6e2152 --- /dev/null +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ja.tr @@ -0,0 +1,511 @@ +# textdomain: mcl_doc_basics +Basics=基礎編 +Everything you need to know to get started with playing=プレイを始めるために必要なすべてのこと +Advanced usage=高度な使用方法 +Advanced information which may be nice to know, but is not crucial to gameplay=知っておくと便利だが、ゲームプレイには重要でない高度な情報 +Quick start=クイックスタート +This is a very brief introduction to the basic gameplay:=基本的なゲームプレイの簡素な紹介: +Basic controls:=基本操作: +• Move mouse to look=・マウスを動かして見る +• [W], [A], [S] and [D] to move=・[W]、[A]、[S]、[D]で移動 +• [E] to sprint=・[E]で走る +• [Space] to jump or move upwards=・[Space]でジャンプ / 上昇 +• [Shift] to sneak or move downwards=・[Shift]でスニーク / 下降 +• Mouse wheel or [1]-[9] to select item=・マウスホイールか[1]-[9]でアイテム選択 +• Left-click to mine blocks or attack=・左クリックでブロックを掘る / 攻撃 +• Recover from swings to deal full damage=・最大ダメージを与えるには攻撃間隔にインターバルが必要 +• Right-click to build blocks and use things=・右クリックでブロックを積む / モノを使う +• [I] for the inventory=・[I]でインベントリ画面 +• First items in inventory appear in hotbar below=・インベントリの最初のアイテムが、下のホットバーに表示される +• Lowest row in inventory appears in hotbar below=・インベントリ最後尾のアイテムが、下のホットバーに表示される +• [Esc] to close this window=・[Esc]でこのウィンドウを閉じる +How to play:=プレイ方法 +• Punch a tree trunk until it breaks and collect wood=・木の幹が折れるまで叩き、木材を集める +• Place the wood into the 2×2 grid (your “crafting grid”) in your inventory menu and craft 4 wood planks=・インベントリメニューの2×2グリッド(クラフト用グリッド)に木を置き、板材を4枚クラフト +• Place them in a 2×2 shape in the crafting grid to craft a crafting table=・それらをクラフトグリッドに2×2の形で配置し、作業台をクラフト +• Place the crafting table on the ground=・作業台を地面に置く +• Rightclick it for a 3×3 crafting grid=・それを右クリックで、3×3のクラフトグリッドが表示される +• Use the crafting guide (book icon) to learn all the possible crafting recipes=・クラフトガイド(本のアイコン)を使い、可能な限りのクラフトレシピを学ぶ +• Craft a wooden pickaxe so you can dig stone=・石を掘れるようになるために、木製のツルハシをクラフト +• Different tools break different kinds of blocks. Try them out!=・道具によって壊せるブロックの種類が異なる。試してみよう! +• Read entries in this help to learn the rest=・続きを学ぶには、このヘルプのエントリーを読む +• Continue playing as you wish. There's no goal. Have fun!=・思いのままにプレイを続けよう。ゴールはありません。楽しんで! +Minetest=Minetest(マインテスト) +Minetest is a free software game engine for games based on voxel gameplay, inspired by InfiniMiner, Minecraft, and the like. Minetest was originally created by Perttu Ahola (alias “celeron55”).=Minetestは、InfiniMinerやMinecraftなどに影響を受けた、ボクセルゲームプレイに基づいたゲームのためのフリーソフトウェア・ゲームエンジンです。Minetestのオリジナルは、Perttu Ahola (別名"celeron55") によって作成されました。 +The player is thrown into a huge world made out of cubes or blocks. These cubes usually make the landscape they blocks can be removed and placed almost entirely freely. Using the collected items, new tools and other items can be crafted. Games in Minetest can, however, be much more complex than this.=プレイヤーは、立方体やブロックでできた巨大な世界に放り込まれます。これらのキューブは大抵、ほぼ自由にブロックを削除・配置でき、景観を作りあげます。収集したアイテムを使って、新しい道具や他のアイテムを作れます。Minetestのゲームは、しかし、これよりもはるかに複雑にできます。 +A core feature of Minetest is the built-in modding capability. Mods modify existing gameplay. They can be as simple as adding a few decorational blocks or be very complex by e.g. introducing completely new gameplay concepts, generating a completely different kind of world, and many other things.=Minetestの中核を成すのは、組み込みのMOD(モディファイ)機能です。MODとは、既存のゲームプレイを改造するものです。装飾ブロックを追加するだけの簡単なものから、全く新しいゲームプレイコンセプトを導入したり、全く異なる種類の世界を生成したりする非常に複雑なものまで、多岐にわたります。 +Minetest can be played alone or online together with multiple players. Online play will work out of the box with any mods, with no need for additional software as they are entirely provided by the server.=Minetestは、一人でプレイすることも、複数のプレイヤーと一緒にオンラインでプレイすることも可能です。サーバーが全てを提供するため、どんなMODでもオンラインプレイはそのまま動作し、追加のソフトウェアも要りません。 +Minetest is usually bundled with a simple default game, named “Minetest Game” (shown in images 1 and 2). You probably already have it. Other games for Minetest can be downloaded from the official Minetest forums .=Minetestには通常、「Minetest Game」という名前のシンプルな基本のゲームが同梱されています(画像1、2のとおり)。おそらく、すでにお持ちでしょう。Minetest用の他のゲームは、Minetestの公式フォーラム からダウンロードできます。 +Minetest as well as Minetest Game are both unfinished at the moment, so please forgive us when not everything works out perfectly.=MinetestもMinetest Gameも現在未完成なので、すべてが完璧とは言えませんが、ご容赦を。 +Sneaking=スニーキング +Sneaking makes you walk slower and prevents you from falling off the edge of a block.=スニークすると遅く歩くようになり、またブロックの端から落下するのを防ぐ効果もあります。 +To sneak, hold down the sneak key (default: [Shift]). When you release it, you stop sneaking. Careful: When you release the sneak key at a ledge, you might fall!=スニークするには、スニークキー(デフォルト:[Shift])を押してください。離すとスニーキングをやめます。注:崖っぷちでスニークキーを離すと、落ちるかもしれません! +• Sneak: [Shift]=・スニーク:[Shift] +Sneaking only works when you stand on solid ground, are not in a liquid and don't climb.=スニーキングは、固い地面の上に立ち、液体の中におらず、よじ登ったりしていない場合にのみ有効です。 +If you jump while holding the sneak key, you also jump slightly higher than usual.=スニークキーを押しながらジャンプすると、通常より少し高くジャンプするようにもなっています。 +Sneaking might be disabled by mods. In this case, you still walk slower by sneaking, but you will no longer be stopped at ledges.=スニーキングはMODによって無効化される場合があります。この場合、歩行の鈍化は残りますが、崖っぷちに留まる機能は無くなっています。 +Controls=操作 +These are the default controls:=デフォルトの操作: +Basic movement:=基本的な移動: +• Moving the mouse around: Look around=・マウスの移動:周りを見る +• W: Move forwards=・W:前方移動 +• A: Move to the left=・A:左移動 +• D: Move to the right=・D:右移動 +• S: Move backwards=・S:後方移動 +• E: Sprint=・E:走る +While standing on solid ground:=固い地面に立ちながら: +• Space: Jump=・Space:ジャンプ +• Shift: Sneak=・Shift:スニーク +While on a ladder, swimming in a liquid or fly mode is active=ハシゴに登上・液中で遊泳・飛行モードが有効などの間: +• Space: Move up=・Space:上昇 +• Shift: Move down=・Shift:下降 +Extended movement (requires privileges):=拡張移動(要権限): +• J: Toggle fast mode, makes you run or fly fast (requires “fast” privilege)=・J:高速モードに切替えで、走行・飛行が速くなる(要 "fast" 権限) +• K: Toggle fly mode, makes you move freely in all directions (requires “fly” privilege)=・K:飛行モードに切替えで、全方向に自由移動が可能(要 "fly" 権限) +• H: Toggle noclip mode, makes you go through walls in fly mode (requires “noclip” privilege)=・H:壁抜けモードに切替えで、飛行モード中に壁抜けが可能(要 "noclip" 権限) +• E: Move even faster when in fast mode=・E:高速モードではさらに速く移動 +• E: Walk fast in fast mode=・E:高速モードで早歩き +World interaction:=ワールドでの作用: +• Left mouse button: Punch / mine blocks / take items=・左クリック:叩く / ブロック採掘 / アイテム取得 +• Left mouse button: Punch / mine blocks=・左クリック:叩く / ブロック採掘 +• Right mouse button: Build or use pointed block=・右クリック:指定したブロックを設置または使用 +• Shift+Right mouse button: Build=・Shift + 右クリック:設置 +• Roll mouse wheel: Select next/previous item in hotbar=・マウスホイール回転:ホットバーのアイテム選択 次/前 +• Roll mouse wheel / B / N: Select next/previous item in hotbar=・マウスホイール回転 / B / N:ホットバーのアイテム選択 次/前 +• 1-9: Select item in hotbar directly=・1-9:ホットバーのアイテムを直で選択 +• Q: Drop item stack=・Q:アイテムをスタック一括でドロップ +• Shift+Q: Drop 1 item=・Shift + Q:アイテムを一個単位でドロップ +• I: Show/hide inventory menu=・I:インベントリメニューの表示/非表示 +Inventory interaction:=インベントリでの作用: +See the entry “Basics > Inventory”.=エントリー“Basics > Inventory”を参照の事。 +Camera:=カメラ: +• Z: Zoom=・Z:ズーム +• F7: Toggle camera mode=・F7:カメラモード切替 +• F8: Toggle cinematic mode=・F8:シネマティックモード切替 +Interface:=インターフェイス: +• Esc: Open menu window (pauses in single-player mode) or close window=・Esc: +• F1: Show/hide HUD=・F1:HUDの表示/非表示 +• F2: Show/hide chat=・F2:チャットの表示/非表示 +• F9: Toggle minimap=・F9:ミニマップ切替 +• Shift+F9: Toggle minimap rotation mode=・Shift + F9:ミニマップの回転モード切替 +• F10: Open/close console/chat log=・F10:コンソール/チャットログの開/閉 +• F12: Take a screenshot=・F12:スクリーンショットを撮る +Server interaction:=サーバーでの作用: +• T: Open chat window (chat requires the “shout” privilege)=・T:チャットウィンドウを開く(チャットには "shout" 権限が必要) +• /: Start issuing a server command=・/:サーバーコマンドの発行開始 +Technical:=技術的なやつ: +• R: Toggle far view (disables all fog and allows viewing far away, can make game very slow)=・R:遠景の切替え(すべてのフォグを無効にして遠景を望めるが、ゲームを非常に遅くする場合あり) +• +: Increase minimal viewing distance=・+:最短視野距離の拡大 +• -: Decrease minimal viewing distance=・-:最短視野距離の縮小 +• F3: Enable/disable fog=・F3:フォグの有効/無効 +• F5: Enable/disable debug screen which also shows your coordinates=・F5:座標表示付デバッグ画面の有効/無効 +• F6: Only useful for developers. Enables/disables profiler=・F6:開発者のみに有用。プロファイラの有効化/無効化 +• P: Only useful for developers. Writes current stack traces=・P:開発者のみに有用。現在のスタックトレースを書き込む +Players=プレイヤー +Players (actually: “player characters”) are the characters which users control.=プレイヤー(正しくは「プレイヤーキャラクター」)とは、ユーザーが操作するキャラクターを指します。 +Players are living beings. They start with a number of health points (HP) and a number of breath points (BP).=プレイヤーは生きている存在です。多数のHP(ヘルスポイント)とBP(ブレスポイント)でスタートします。 +Players are capable of walking, sneaking, jumping, climbing, swimming, diving, mining, building, fighting and using tools and blocks.=プレイヤーは、歩く、忍び寄る、ジャンプする、よじ登る、泳ぐ、潜る、採掘する、建てる、戦う、そして道具やブロックを使うことができます。 +Players can take damage for a variety of reasons, here are some:=プレイヤーはさまざまな理由でダメージを受けますが、いくつか紹介します: +• Taking fall damage=・落下ダメージを受ける +• Touching a block which causes direct damage=・直接ダメージを与えるブロックに触れる +• Drowning=・溺れる +• Being attacked by another player=・他のプレイヤーから攻撃される +• Being attacked by a computer enemy=・コンピュータの敵から攻撃される +At a health of 0, the player dies. The player can just respawn in the world.=体力が0になると、プレイヤーは死亡します。プレイヤーはワールドにただリスポーンします。 +Other consequences of death depend on the game. The player could lose all items, or lose the round in a competitive game.=その他、死亡した場合の結果はゲームによって異なります。プレイヤーはすべてのアイテムを失ったり、対戦ゲームでは失点する可能性があります。 +Some blocks reduce breath. While being with the head in a block which causes drowning, the breath points are reduced by 1 for every 2 seconds. When all breath is gone, the player starts to suffer drowning damage. Breath is quickly restored in any other block.=いくつかの溺れる効果のあるブロックに頭を入れている間は、2秒ごとにBP(ブレスポイント)が1ずつ減少します。息がなくなると、溺水ダメージを受けるようになります。そのほかのブロックではすぐに呼吸が回復します。 +Damage can be disabled on any world. Without damage, players are immortal and health and breath are unimportant.=ダメージはどのワールドでも無効にできます。 ダメージがなければプレイヤーは不死であり、ヘルスやブレスは重要ではありません。 +In multi-player mode, the name of other players is written above their head.=マルチプレイモードでは、他のプレイヤーの頭上に名前が表示されます。 +Items=アイテム +Items are things you can carry along and store in inventories. They can be used for crafting, smelting, building, mining, and more. Types of items include blocks, tools, weapons and items only used for crafting.=アイテムは、携行したりインベントリに格納したりできるものです。クラフト、製錬、建築、採掘などに使えます。アイテムの分類としては、ブロック、ツール、武器、そしてクラフト専用アイテム等があります。 +An item stack is a collection of items of the same type which fits into a single item slot. Item stacks can be dropped on the ground. Items which drop into the same coordinates will form an item stack.=アイテムスタックとは、1つのアイテムスロットに入る、同一種アイテムのまとまりです。アイテムスタックは地面に落とせます。同じ座標にドロップしたアイテムは、アイテムスタックを形成します。 +Dropped item stacks will be collected automatically when you stand close to them.=ドロップしたアイテムスタックは、近くに立つと自動的に回収されます。 +Items have several properties, including the following:=アイテムには、次のようないくつかのプロパティが含まれます: +• Maximum stack size: Number of items which fit on 1 item stack=・最大スタックサイズ:1アイテムスタックに収まるアイテム数 +• Pointing range: How close things must be to be pointed while wielding this item=・ポイント範囲:このアイテムを手に持っている時、モノがどのくらい近くにあればポイントできるか +• Group memberships: See “Basics > Groups”=・グループのメンバーシップ:“Basics > Groups”参照 +• May be used for crafting or cooking=・クラフトや調理に使えるかも +Tools=道具 +Some items may serve as a tool when wielded. Any item which has some special use which can be directly used by its wielder is considered a tool.=アイテムによっては、手に持つことで道具として役目を果たすことがあります。使い手が直接使用できる何らかの特有な用途を持つアイテムは、道具とみなされます。 +A common subset of tools is mining tools. These are important to break all kinds of blocks. Weapons are a kind of tool. There are of course many other possible tools. Special actions of tools are usually done by left-click or right-click.=道具の中の分類で一般的なのは、採掘道具です。これらは、あらゆるブロックを壊すために重要です。武器も道具の一種です。もちろん、他にも多くの道具があります。道具の特殊な操作は、通常、左クリックか右クリックで行います。 +When nothing is wielded, players use their hand which may act as tool and weapon.=何も手に持っていないとき、プレイヤーは、道具や武器としても振る舞う自分の手を使います。 +Mining tools are important to break all kinds of blocks. Weapons are another kind of tool. There are some other more specialized tools. Special actions of tools are usually done by right-click.=採掘道具は、あらゆるブロックを壊すために重要な道具です。武器も道具の一種です。その他にも、より専門的な道具があります。道具の特殊な動作は、たいてい右クリックで行います。 +When nothing is wielded, players use their hand which may act as tool and weapon. The hand is capable of punching and deals minimum damage.=何も手に持っていないとき、プレイヤーは、道具や武器としても機能する自分の手を使います。手は、最小限のダメージを与える攻撃ができます。 +Many tools will wear off when using them and may eventually get destroyed. The damage is displayed in a damage bar below the tool icon. If no damage bar is shown, the tool is in mint condition. Tools may be repairable by crafting, see “Basics > Crafting”.=多くの道具は使っていると消耗していき、ついには壊れてしまうこともあります。ダメージは、道具のアイコンの下にあるダメージバーで表示されます。ダメージバーが表示されていない場合、その道具は新品同様です。道具はクラフトで修理できる場合があります。“Basics > Crafting”を参照してください。 +Weapons=武器 +Some items are usable as a melee weapon when wielded. Weapons share most of the properties of tools.=一部のアイテムは、手に持つと近接武器として使えます。武器は、道具のプロパティのほとんどを共有しています。 +Melee weapons deal damage by punching players and other animate objects. There are two ways to attack:=近接武器は、プレイヤーや他のMOBを叩くことでダメージを与えることができます。攻撃方法は次の2つ: +• Single punch: Left-click once to deal a single punch=・単発攻撃:左クリック1回で、単一の攻撃 +• Quick punching: Hold down the left mouse button to deal quick repeated punches=・連続攻撃:マウスの左ボタンを押したままで、攻撃を素早く繰り返す +There are two core attributes of melee weapons:=近接武器の核となる性質は次の2つ: +• Maximum damage: Damage which is dealt after a hit when the weapon was fully recovered=・最大ダメージ:武器の力が完全に復帰している場合の、ヒット後の与ダメージ +• Full punch interval: Time it takes for fully recovering from a punch=・全力攻撃間隔:攻撃後、力が完全に復帰するまでの時間 +A weapon only deals full damage when it has fully recovered from a previous punch. Otherwise, the weapon will deal only reduced damage. This means, quick punching is very fast, but also deals rather low damage. Note the full punch interval does not limit how fast you can attack.=武器は、前の攻撃から完全に復帰したときのみ、全力でダメージを与えます。そうでない場合、武器が与えられるダメージは減少します。つまり、連続攻撃は非常に速いですが、与えるダメージはむしろ低くなります。なお、全力攻撃の間隔は、攻撃できる速さを制限するものではありません。 +There is a rule which sometimes makes attacks impossible: Players, animate objects and weapons belong to damage groups. A weapon only deals damage to those who share at least one damage group with it. So if you're using the wrong weapon, you might not deal any damage at all.=時々、攻撃が不可能になるルール:プレイヤー、MOB、武器はダメージグループに属します。武器は、少なくとも1つのダメージグループを共有している相手にしか、ダメージを与えません。なので使う武器が悪いと、なんのダメージも与えられないことがあります。 +Pointing=ポイントする +“Pointing” means looking at something in range with the crosshair. Pointing is needed for interaction, like mining, punching, using, etc. Pointable things include blocks, players, computer enemies and objects.=「ポイントする」とは、 十字線で範囲内の何かを指すことです。採掘、攻撃、使う、等といった相互作用に必要です。ポイント可能なものには、ブロック、プレイヤー、コンピュータの敵やオブジェクトがあります。 +To point something, it must be in the pointing range (also just called “range”) of your wielded item. There's a default range when you are not wielding anything. A pointed thing will be outlined or highlighted (depending on your settings). Pointing is not possible with the 3rd person front camera.=何かをポイントするためには、その何かが、手に持っているアイテムのポイント範囲(単に「範囲」とも呼ばれます)内にある必要があります。何も手に持っていない時のデフォルトの範囲もあります。ポイントされたものは、輪郭が強調されるか、またはハイライトされます(設定による)。3人称視点のフロントカメラでは、ポイントする事はできません。 +A few things can not be pointed. Most blocks are pointable. A few blocks, like air, can never be pointed. Other blocks, like liquids can only be pointed by special items.=いくつかのものはポイントできません。ほとんどのブロックはポイント可能です。空気のようないくつかのブロックは、決して指すことができません。液体のような他のブロックは、特別なアイテムによってのみ指さすことができます。 +Camera=カメラ +There are 3 different views which determine the way you see the world. The modes are:=ワールドの見方を決める3つの視点があります。モードは次のとおり: +• 1: First-person view (default)=・1:一人称視点(デフォルト) +• 2: Third-person view from behind=・:背後からの三人称視点 +• 3: Third-person view from the front=・:前面からの三人称視点 +You can change the camera mode by pressing [F7].=[F7]を押すと、カメラモードを変更できます。 +You might be able to zoom with [Z] to zoom the view at the crosshair. This allows you to look further.=[Z]を押すと十字線に沿った視界をズームできる、かもしれません。これによって、より遠くを望めます。 +Zooming is a gameplay feature that might be enabled or disabled by the game. By default, zooming is enabled when in Creative Mode but disabled otherwise.=ズーム操作は、ゲームによって有効または無効になる可能性のあるゲームプレイ機能です。デフォルトでは、ズームが有効なのはクリエイティブモードのみで、それ以外なら無効化されています。 +There is also Cinematic Mode which can be toggled with [F8]. With Cinematic Mode enabled, the camera movements become more smooth. Some players don't like it, it is a matter of taste.=また、[F8]で切替え可能なシネマティックモードもあります。シネマティックモードを有効にすると、カメラの動きがより滑らかになります。好みによりますが、苦手なプレイヤーもいるようです。 +By holding down [Z], you can zoom the view at your crosshair. You need the “zoom” privilege to do this.=[Z]を押していると、 十字線に沿った視界をズームできます。このためには“zoom”権限が必要です。 +• Switch camera mode: [F7]=・カメラモードの切替:[F7] +• Toggle Cinematic Mode: [F8]=・シネマティックモードの切替:[F8] +• Zoom: [Z]=・ズーム:[Z] +Blocks=ブロック +The world of MineClone 2 is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=MineClone 2のワールドは、すべてがブロック(正確にはボクセル)で構成されています。ブロックは、適切なツールで追加や削除ができます。 +The world is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=ワールドは、すべてがブロック(正確にはボクセル)で構成されています。ブロックは、適切なツールで追加や削除ができます。 +Blocks can have a wide range of different properties which determine mining times, behavior, looks, shape, and much more. Their properties include:=ブロックは幅広く多様なプロパティを持つことができ、採掘時間、動作、外観、形状などが定まります。プロパティは次のとおり: +• Collidable: Collidable blocks can not be passed through; players can walk on them. Non-collidable blocks can be passed through freely=・衝突性:衝突性ブロックは通過できず、プレイヤーはその上を歩ける。非衝突性ブロックは、自由に通り抜けられる +• Pointable: Pointable blocks show a wireframe or a halo box when pointed. But you will just point through non-pointable blocks. Liquids are usually non-pointable but they can be pointed at by some special tools=・ポイント可能なブロックは、ポイントするとワイヤーフレームまたはハイライトボックスが表示される。しかしポイント不可能なブロックでは、判定がただ通り抜ける。液体はたいていポイント不可能だが、いくつかの特殊な道具ならポイントできる +• Mining properties: By which tools it can be mined, how fast and how much it wears off tools=・採掘のプロパティ:どのような道具で採掘できるか、道具の消耗はどの程度か、など +• Climbable: While you are at a climbable block, you won't fall and you can move up and down with the jump and sneak keys=・よじ登り可能:よじ登り可能なブロックにいる間は落下せず、ジャンプキーとスニークキーで上下に移動できる +• Drowning damage: See the entry “Basics > Player”=・溺水ダメージ:エントリー“Basics > Player”参照 +• Liquids: See the entry “Basics > Liquids”=・液体:エントリー“Basics > Liquids”参照 +• Group memberships: Group memberships are used to determine mining properties, crafting, interactions between blocks and more=・グループの帰属関係:グループの帰属関係は、採掘のプロパティ、クラフト、ブロック間の相互作用などを定めるために用いられる +Mining=採掘 +Mining (or digging) is the process of breaking blocks to remove them. To mine a block, point it and hold down the left mouse button until it breaks.=採掘(または掘削)とは、ブロックを掘り壊して取り除く工程のことです。ブロックを掘るには、ブロックをポイントし、それが壊れるまでマウスの左ボタンを押し続けます。 +Blocks require a mining tool to be mined. Different blocks are mined by different mining tools, and some blocks can not be mined by any tool. Blocks vary in hardness and tools vary in strength. Mining tools will wear off over time. The mining time and the tool wear depend on the block and the mining tool. The fastest way to find out how efficient your mining tools are is by just trying them out on various blocks. Any items you gather by mining will drop on the ground, ready to be collected.=ブロックを掘るには、採掘道具を要します。採掘道具によって掘れるブロックが異なり、どんな道具でも掘れないブロックもあります。ブロックの硬さはさまざまで、道具の強さもさまざまです。採掘道具は使用時間に応じて消耗します。採掘時間と道具の消耗は、ブロックと採掘道具によって異なります。採掘道具の効率を知るには、様々なブロックで試してみるのが一番早いでしょう。アイテムは採掘によって地面に落ちるので、すぐに収集できます。 +After mining, a block may leave a “drop” behind. This is a number of items you get after mining. Most commonly, you will get the block itself. There are other possibilities for a drop which depends on the block type. The following drops are possible:=採掘後、ブロックが「ドロップ」を残すことがあります。これは、採掘後に得られるアイテムの数々です。最も一般的なのは、そのブロックそのものを入手することです。その他にも、ブロックの種類によってドロップの可能性があります。考えられるドロップは次の通り: +• Always drops itself (the usual case)=・常にそれ自身をドロップ(大抵の場合) +• Always drops the same items=・常に同じアイテムをドロップ +• Drops items based on probability=・確率でアイテムをドロップ +• Drops nothing=・ドロップなし +Building=構築 +Almost all blocks can be built (or placed). Building is very simple and has no delay.=ほぼすべてのブロックが構築(配置)可能です。構築はとてもシンプルで、遅延もありません。 +To build your wielded block, point at a block in the world and right-click. If this is not possible because the pointed block has a special right-click action, hold down the sneak key before right-clicking.=手に持ったブロックを構築するには、ワールド内のブロックをポイントして右クリックします。これができない場合は、ポイントしたブロックが特殊な右クリックアクションを持っているせいである為、スニークキーを押しながら右クリックしてください。 +Blocks can almost always be built at pointable blocks. One exception are blocks attached to the floor; these can only be built on the floor.=ブロックは、ほとんどの場合、ポイント可能なブロックに構築できます。例外として、床に付属するブロックは、床の上にしか構築できません。 +Normally, blocks are built in front of the pointed side of the pointed block. A few blocks are different: When you try to build at them, they are replaced.=通常、ブロックはポイントした側を前にして構築されます。一部の違うブロック:そのブロックに向かって構築しようとすると、置き換えられます。 +Liquids=液体 +Liquids are special dynamic blocks. Liquids like to spread and flow to their surrounding blocks. Players can swim and drown in them.=液体は特殊な動的ブロックです。液体は周囲のブロックに広がり、流れていく習性があります。プレイヤーはその中で泳いだり、溺れたりできます。 +Liquids usually come in two forms: In source form (S) and in flowing form (F).=液体が通常取りうる2つの形態:源泉型(S)と流動型(F)である。 +Liquid sources have the shape of a full cube. A liquid source will generate flowing liquids around it from time to time, and, if the liquid is renewable, it also generates liquid sources. A liquid source can sustain itself. As long it is left alone, a liquid source will normally keep its place and does not drain out.=液体源は完全な立方体の形を持っています。液体源は時々その周りに流動液体を発生させ、もし液体が再生可能であれば、液体源も発生させます。液体源は自身を維持できます。放っておく限り、液体源は通常その場所を保ち、流出しません。 +Flowing liquids take a sloped form. Flowing liquids spread around the world until they drain. A flowing liquid can not sustain itself and always comes from a liquid source, either directly or indirectly. Without a liquid source, a flowing liquid will eventually drain out and disappear.=流動液体は、傾斜した形状をとります。それらは枯渇するまでワールド中に広がります。流動液体は自身を維持できず、常に直接的または間接的に液体源から生じます。液体源がなければ、流動液体はやがて流出しきって消えます。 +All liquids share the following properties:=すべての液体に共通するプロパティは次のとおり: +• All properties of blocks (including drowning damage)=・ブロックのプロパティ全般(溺水ダメージ含む) +• Renewability: Renewable liquids can create new sources=・再生可能性:再生可能な液体は、新たな源泉を生み出せる +• Flowing range: How many flowing liquids are created at maximum per liquid source, it determines how far the liquid will spread. Possible are ranges from 0 to 8. At 0, no flowing liquids will be created. Image 5 shows a liquid of flowing range 2=・流動範囲:液体源1つにつき、最大でどれだけの流動液体を生むか、液体がどこまで広がるかの設定。可能な範囲は0から8まで。0の場合、流動液体は発生しない。画像5は、流動範囲2の液体 +• Viscosity: How slow players move through it and how slow the liquid spreads=・粘性:プレイヤーがその中を移動する際の遅さ、液体が広がる際の遅さ +Renewable liquids create new liquid sources at open spaces (image 2). A new liquid source is created when:=再生可能な液体は、空きスペースに新たな液体源を生み出します(画像2)。新しい液体源ができる時は次のとおり: +• Two renewable liquid blocks of the same type touch each other diagonally=・同じ種類の再生可能な液体ブロック2個が、斜めに接する +• These blocks are also on the same height=・これらのブロックも同じ高さにある +• One of the two “corners” is open space which allows liquids to flow in=・2つの「かど」のうち1つは、液体が流れ込む空きスペース +When those criteria are met, the open space is filled with a new liquid source of the same type (image 3).=それらの条件を満たすと、空きスペースに同じ種類の新しい液体源が充填されます(画像3)。 +Swimming in a liquid is fairly straightforward: The usual direction keys for basic movement, the jump key for rising and the sneak key for sinking.=液体の中を泳ぐのはとても直感的:基本的な動きは通常の方向キー、浮上はジャンプキー、潜水はスニークキーで行います。 +The physics for swimming and diving in a liquid are:=液体の中を泳いだり潜ったりするときの物理は: +• The higher the viscosity, the slower you move=・粘度が高いほど、動きが遅くなる +• If you rest, you'll slowly sink=・休んでいると、じわじわと沈む +• There is no fall damage for falling into a liquid as such=・このように、液体に落下しても落下ダメージはない +• If you fall into a liquid, you will be slowed down on impact (but don't stop instantly). Your impact depth is determined by your speed and the liquid viscosity. For a safe high drop into a liquid, make sure there is enough liquid above the ground, otherwise you might hit the ground and take fall damage=液中に落ちると衝撃で速度が落ちる(但し瞬時には止まらない)。衝撃の深さは、速度と液体の粘性によって決まる。液体へ安全に高飛び込みするには、地面より上に十分な液体があることを確認する。そうでなければ、地面に衝突して落下ダメージを受ける可能性がある +Liquids are often not pointable. But some special items are able to point all liquids.=液体は往々にしてポイント不可能です。しかし一部の特殊なアイテムは、すべての液体をポイントすることができます。 +Crafting=クラフト +Crafting is the task of combining several items to form a new item.=クラフトとは、複数のアイテムを組み合わせて新しいアイテムを作りだす作業です。 +To craft something, you need one or more items, a crafting grid (C) and a crafting recipe. A crafting grid is like a normal inventory which can also be used for crafting. Items need to be put in a certain pattern into the crafting grid. Next to the crafting grid is an output slot (O). Here the result will appear when you placed items correctly. This is just a preview, not the actual item. Crafting grids can come in different sizes which limits the possible recipes you can craft.=何かをクラフトするには、1つ以上のアイテム、クラフトグリッド(C)、クラフトレシピが必要です。クラフトグリッドは通常のインベントリのようなもので、クラフトにも使えます。アイテムは、クラフトグリッドに一定のパターンで配置する必要があります。クラフトグリッドの隣には、アウトプットスロット(O)があります。ここにアイテムを正しく配置すると、結果が表示されます。これはあくまでプレビューであり、実際のアイテムではありません。クラフトグリッドの大きさはまちまちなため、クラフトできるレシピが制限されたりもします。 +To complete the craft, take the result item from the output slot, which will consume items from the crafting grid and creates a new item. It is not possible to place items into the output slot.=クラフトを完成させるには、出力スロットから結果のアイテムを取ります。このとき、クラフトグリッドからアイテムが消費され、新しいアイテムが作成されます。出力スロットにはアイテムを配置できません。 +A description on how to craft an item is called a “crafting recipe”. You need this knowledge to craft. There are multiple ways to learn crafting recipes. One way is by using a crafting guide, which contains a list of available crafting recipes. Some games provide crafting guides. There are also some mods which you can download online for installing a crafting guide. Another way is by reading the online manual of the game (if one is available).=アイテムのクラフト方法を記したものを「クラフトレシピ」と呼びます。この知識は、クラフトをするのに必要です。クラフトレシピを覚えるには、複数の方法があります。1つは、クラフトレシピの使用可能なリストを含むクラフトガイドを使用する方法です。いくつかのゲームではクラフトガイドを提供しています。また、クラフトガイドをインストールするために、オンラインでダウンロードできるMODがいくつかあります。もう1つの方法は、ゲームのオンラインマニュアルを読むことです(利用可能な場合)。 +Crafting recipes consist of at least one input item and exactly one stack of output items. When performing a single craft, it will consume exactly one item from each stack of the crafting grid, unless the crafting recipe defines replacements.=クラフトレシピは、少なくとも1つの入力アイテムと、ちょうど1つの出力アイテムのスタックから成ります。1つのクラフトを実行するとき、クラフトレシピが置換を定義していない限り、クラフトグリッドの各スタックから正確に1つのアイテムを消費します。 +There are multiple types of crafting recipes:=クラフトレシピは次のような複数の種類がある: +• Shaped (image 2): Items need to be placed in a particular shape=・整形(画像2):アイテムは特定の形に配置する必要がある +• Shapeless (images 3 and 4): Items need to be placed somewhere in input (both images show the same recipe)=形なし(画像3、4):アイテムは入力のどこかしらに置く必要がある(両画像とも同じレシピを表示) +• Cooking: Explained in “Basics > Cooking”=・調理:“Basics > Cooking”に解説あり +• Repairing (image 5): Place two damaged tools into the crafting grid anywhere to get a tool which is repaired by 5%=修復(画像5):損傷した道具を2つ、任意のクラフトグリッドに置くと、5%修復された道具が手に入る +In some crafting recipes, some input items do not need to be a concrete item, instead they need to be a member of a group (see “Basics > Groups”). These recipes offer a bit more freedom in the input items. Images 6-8 show the same group-based recipe. Here, 8 items of the “stone” group are required, which is true for all of the shown items.=・クラフトレシピの中には、入力アイテムが具体的でなくてもよいものがあり、その代わりグループに属している必要があります(“Basics > Groups”参照)。これらのレシピでは、入力アイテムにいくらか自由度があります。画像6-8は、同じグループ基準のレシピを示したものです。ここでは"stone "グループのアイテムが8つ必要であり、これは表示されているすべてのアイテムに当てはまります。 +Rarely, crafting recipes have replacements. This means, whenever you perform a craft, some items in the crafting grid will not be consumed, but instead will be replaced by another item.=まれに、クラフトレシピには置換があります。これは、クラフトを実行するたびに、クラフトグリッド内の一部のアイテムが消費されず、代わりに別のアイテムに置き換わることを意味します。 +Cooking=調理 +Cooking (or smelting) is a form of crafting which does not involve a crafting grid. Cooking is done with a special block (like a furnace), an cookable item, a fuel item and time in order to yield a new item.=調理(または製錬)は、クラフトグリッドを使用しないクラフトの一形態です。調理は、新しいアイテムを作るために、特別なブロック(かまどみたいな)、調理可能なアイテム、燃料アイテム、時間を使って行われます。 +Each fuel item has a burning time. This is the time a single item of the fuel keeps a furnace burning.=各燃料には燃焼時間があります。これは、1つの燃料がかまどの燃焼を維持する時間です。 +Each cookable item requires time to be cooked. This time is specific to the item type and the item must be “on fire” for the whole cooking time to actually yield the result.=調理可能な各アイテムは、調理するために時間を要します。この時間はアイテムの種類によって異なり、実際に結果を得るためには、調理時間全体にわたってアイテムに「火が通って」いなければいけません。 +Hotbar=ホットバー +At the bottom of the screen you see some squares. This is called the “hotbar”. The hotbar allows you to quickly access the first items from your player inventory.=画面の下に、いくつか四角いものが見えます。これは「ホットバー」と呼ばれるものです。ホットバーを使うと、インベントリの初段のアイテムに素早くアクセスできます。 +You can change the selected item with the mouse wheel or the keyboard.=選択した項目は、マウスホイールやキーボードで変更できます。 +• Select previous item in hotbar: [Mouse wheel up] or [B]=・ホットバーの選択項目を前へ:[マウスホイール上] or [B] +• Select next item in hotbar: [Mouse wheel down] or [N]=・ホットバーの選択項目を次へ:[マウスホイール下] or [N] +• Select item in hotbar directly: [1]-[9]=ホットバーの項目を直接選択:[1]-[9] +The selected item is also your wielded item.=選択したアイテムは、手に持ったアイテムでもあります。 +Minimap=ミニマップ +If you have a map item in any of your hotbar slots, you can use the minimap.=ホットバーのいずれかのスロットにマップアイテムがある場合、ミニマップが使えます。 +Press [F9] to make a minimap appear on the top right. The minimap helps you to find your way around the world. Press it again to select different minimap modes and zoom levels. The minimap also shows the positions of other players.=[F9]を押すと、右上にミニマップが表示されます。ミニマップは世界各地での道しるべになります。もう一度押すと、ミニマップモードやズームレベルが切替わります。ミニマップには、他のプレイヤーの位置も表示されます。 +There are 2 minimap modes and 3 zoom levels.=2つのミニマップモードと、3つのズームレベルがあります。 +Surface mode (image 1) is a top-down view of the world, roughly resembling the colors of the blocks this world is made of. It only shows the topmost blocks, everything below is hidden, like a satellite photo. Surface mode is useful if you got lost.=表層モード(画像1)はワールドを見下ろした光景で、このワールドを形作っているブロックの色に似通っています。一番上のブロックだけが表示され、その下は衛星写真のように隠れています。表層モードは、迷子になったときに便利です。 +Radar mode (image 2) is more complicated. It displays the “denseness” of the area around you and changes with your height. Roughly, the more green an area is, the less “dense” it is. Black areas have many blocks. Use the radar to find caverns, hidden areas, walls and more. The rectangular shapes in image 2 clearly expose the position of a dungeon.=レーダーモード(画像2)はもっと複雑です。これはあなたの周りのエリアの「密集度」を表示し、あなたの高度に応じて変化します。大雑把に言うと、緑色の部分が多いほど「密集」していない事になります。黒いエリアはブロックがたくさんあります。レーダーを使って、洞窟や隠し場所、壁などを発見してみましょう。画像2の四角い形は、ダンジョンの位置を明確に表しています。 +There are also two different rotation modes. In “square mode”, the rotation of the minimap is fixed. If you press [Shift]+[F9] to switch to “circle mode”, the minimap will instead rotate with your looking direction, so “up” is always your looking direction.=また、2種類の回転モードがあります。「正方形モード」では、ミニマップの回転は固定されています。[Shift] + [F9]を押して「円形モード」に切り替えると、ミニマップはあなたの視線方向に合わせて回転し、常に「上」があなたの視線方向となります。 +In some games, the minimap may be disabled.=ゲームによっては、ミニマップが無効になっている場合があります。 +• Toggle minimap mode: [F9]=・ミニマップのモードを切替:[F9] +• Toggle minimap rotation mode: [Shift]+[F9]=・ミニマップの回転モードを切替:[Shift] + [F9] +Inventory=インベントリ +Inventories are used to store item stacks. There are other uses, such as crafting. An inventory consists of a rectangular grid of item slots. Each item slot can either be empty or hold one item stack. Item stacks can be moved freely between most slots.=インベントリは、アイテムスタックを収納するために使います。他にもクラフトなどの用途があります。インベントリは、アイテムスロットの四角いグリッドで構成されています。各アイテムスロットは、空の状態か、1つのアイテムスタックを保持できます。アイテムのスタックは、ほとんどのスロット間で自由に移動できます。 +You have your own inventory which is called your “player inventory”, you can open it with the inventory key (default: [I]). The first inventory slots are also used as slots in your hotbar.=「プレイヤーインベントリ」と呼ばれる自分専用のインベントリがあり、インベントリキー(デフォルト:[I])で開けます。インベントリの初段スロットは、ホットバーのスロットとしても機能します。 +Blocks can also have their own inventory, e.g. chests and furnaces.=ブロックは、独自のインベントリを持つこともできます。例えばチェストやかまどです。 +Inventory controls:=インベントリの操作: +Taking: You can take items from an occupied slot if the cursor holds nothing.=取る:カーソルが何も保持していない場合、占有されているスロットからアイテムを取れます。 +• Left click: take entire item stack=・左クリック:アイテムをスタック丸ごと取る +• Right click: take half from the item stack (rounded up)=・右クリック:アイテムをスタックから半分取る(切り上げ) +• Middle click: take 10 items from the item stack=・中クリック:アイテムをスタックから10個取る +• Mouse wheel down: take 1 item from the item stack=・マウスホイール下:アイテムをスタックから1個取る +Putting: You can put items onto a slot if the cursor holds 1 or more items and the slot is either empty or contains an item stack of the same item type.=置く:カーソルに1つ以上のアイテムを保持し、目的のスロットが空か、同種のアイテムがスタックされている場合、そのアイテムを置けます。 +• Left click: put entire item stack=・左クリック:アイテムをスタック丸ごと置く +• Right click: put 1 item of the item stack=・右クリック:アイテムをスタックから1個置く +• Right click or mouse wheel up: put 1 item of the item stack=・右クリック または マウスホイール上:アイテムをスタックから1個置く +• Middle click: put 10 items of the item stack=・中クリック:アイテムをスタックから10個置く +Exchanging: You can exchange items if the cursor holds 1 or more items and the destination slot is occupied by a different item type.=交換する:カーソルに1つ以上のアイテムを保持し、目的のスロットが別種のアイテムで占有されている場合、アイテムを交換できます。 +• Click: exchange item stacks=・クリック:アイテムスタックを交換 +Throwing away: If you hold an item stack and click with it somewhere outside the menu, the item stack gets thrown away into the environment.=捨てる:アイテムスタックを保持し、メニュー外のどこかをクリックすると、アイテムスタックがその辺に投げ捨てられます。 +Quick transfer: You can quickly transfer an item stack to/from the player inventory to/from another item's inventory slot like a furnace, chest, or any other item with an inventory slot when that item's inventory is accessed. The target inventory is generally the most relevant inventory in this context.=直送する:炉やチェストなどのインベントリスロットに対しては、プレイヤーインベントリからアイテムスタックを直送できます。この場合対象となるのは、一般的に最も関連性の高いインベントリスロットです。 +• Sneak+Left click: Automatically transfer item stack=・スニークキー + 左クリック:アイテムスタックの自動転送 +Online help=オンラインヘルプ +You may want to check out these online resources related to MineClone 2.=MineClone 2 に関連するオンライン資料もチェックしてみてください。 +MineClone 2 download and forum discussion: =MineClone 2 のダウンロードと掲示板での意見交換: +Here you find the most recent version of MineClone 2 and can discuss it.=ここでは MineClone 2 の最新バージョンを確認し、意見を交換できます。 +Bug tracker: =バグ追跡: +Report bugs here.=バグの報告はこちら。 +Minetest links:=Minetest リンク: +You may want to check out these online resources related to Minetest:=Minetest に関連するオンライン資料もチェックしてみてください: +Official homepage of Minetest: =Minetest の公式ホームページ: +The main place to find the most recent version of Minetest, the engine used by MineClone 2.=MineClone 2 で使用されているエンジン、Minetest の最新版を入手できるメインサイトです。 +The main place to find the most recent version of Minetest.=Minetest の最新版を入手できるメインサイトです。 +Community wiki: =コミュニティ wiki: +A community-based documentation website for Minetest. Anyone with an account can edit it! It also features a documentation of Minetest Game.=Minetest のための、コミュニティベースの文書サイトです。アカウントがあれば誰でも編集可能です! また、Minetest Game の資料も掲載されています。 +Minetest forums: =Minetest の掲示板: +A web-based discussion platform where you can discuss everything related to Minetest. This is also a place where player-made mods and games are published and discussed. The discussions are mainly in English, but there is also space for discussion in other languages.=Minetest に関連するあらゆることを話し合える、Webベースの議論場です。また、プレイヤーが作成したMODやゲームを公開し、議論する場でもあります。議論は主に英語で行われますが、他言語で議論するスペースもあります。 +Chat: =チャット: +A generic Internet Relay Chat channel for everything related to Minetest where people can meet to discuss in real-time. If you do not understand IRC, see the Community Wiki for help.=Minetest に関連するあらゆることをリアルタイムで議論するために人々が集う、IRC(インターネット・リレー・チャット)の汎用チャンネルです。IRCが分からない場合は、コミュニティWikiを参照してください。 +Groups=グループ +Items, players and objects (animate and inanimate) can be members of any number of groups. Groups serve multiple purposes:=アイテム、プレイヤー、オブジェクト(生物と無生物)は、任意の数のグループに属することができます。グループには、次のようなさまざまな役割があります: +• Crafting recipes: Slots in a crafting recipe may not require a specific item, but instead an item which is a member of a particular group, or multiple groups=・クラフトレシピ:クラフトレシピのスロットには、特定のアイテムである必要がない代わりに、特定のグループまたは複数のグループに属しているアイテムを要する場合がある +• Digging times: Diggable blocks belong to groups which are used to determine digging times. Mining tools are capable of digging blocks belonging to certain groups=・掘削時間:掘削可能なブロックが属するグループで、掘削時間の設定に使われる。採掘道具は、所定のグループに属するブロックが掘れる。 +• Block behavior: Blocks may show a special behaviour and interact with other blocks when they belong to a particular group=・ブロックの挙動:ブロックは特定のグループに属している場合、特別な挙動を示し、他のブロックと相互作用することがある +• Damage and armor: Objects and players have armor groups, weapons have damage groups. These groups determine damage. See also: “Basics > Weapons”=ダメージと防具:オブジェクトとプレイヤーは防具グループ、武器はダメージグループを持つ。これらのグループによってダメージが定まる。次も参考に:“Basics > Weapons” +• Other uses=・その他の用途 +In the item help, many important groups are usually mentioned and explained.=アイテムヘルプでは、通常、多くの重要なグループに言及し、説明されています。 +Glossary=用語集 +This is a list of commonly used terms:=よく使われる用語の一覧: +Controls:=コントロール +• Wielding: Holding an item in hand=・手に持つ:アイテムを手に持っている状態。ホットバーで選択した状態と同義 +• Pointing: Looking with the crosshair at something in range=・ポイントする:十字線で範囲内のものを指すこと +• Dropping: Throwing an item or item stack to the ground=・捨てる:アイテムを一つずつ又はスタックごと放り投げ落とすこと +• Punching: Attacking with left-click, is also used on blocks=・パンチ:左クリックで攻撃や何かを作動させたりすること。ブロックを持っていても使える場合あり +• Sneaking: Walking slowly while (usually) avoiding to fall over edges=・スニーク:(通常は)縁から落ちるのを避けながら、ゆっくりと歩くこと +• Climbing: Moving up or down a climbable block=・よじ登る:よじ登り可能なブロックを上下に移動すること +Blocks:=ブロック: +• Block: Cubes that the worlds are made of=・ブロック:ワールドを構成する立方体(※立方体以外もブロックと呼んでいる場合あり) +• Mining/digging: Using a mining tool to break a block=・採掘/掘削:採掘道具を使ってブロックを壊すこと +• Building/placing: Putting a block somewhere=・構築/配置:ブロックをどこかに置くこと +• Drop: Items you get after mining a block=・ドロップ:ブロックを採掘した際に得られるアイテム +• Using a block: Right-clicking a block to access its special function=・ブロックを使う:右クリックで、そのブロック特有の作用を起こす +Items:=アイテム: +• Item: A single thing that players can possess=・アイテム:プレイヤーが所持できる単一のモノ +• Item stack: A collection of items of the same kind=・アイテムスタック:同種のアイテムの集まり +• Maximum stack size: Maximum amount of items in an item stack=・最大スタックサイズ:アイテムスタックに格納できるアイテムの最大量 +• Slot / inventory slot: Can hold one item stack=・スロット/インベントリースロット:アイテムスタック一つ分を収納可能な枠 +• Inventory: Provides several inventory slots for storage=・インベントリ:保管用に複数のスロットを提供するもの +• Player inventory: The main inventory of a player=・プレイヤーインベントリ:メインとなるプレイヤー用インベントリ +• Tool: An item which you can use to do special things with when wielding=・道具:手に持って使うと、特有なことができるアイテム +• Range: How far away things can be to be pointed by an item=・範囲:アイテムでポイントできる距離 +• Mining tool: A tool which allows to break blocks=・採掘道具:ブロックを壊すことができる道具 +• Craftitem: An item which is (primarily or only) used for crafting=・クラフトアイテム:クラフトに(主に、または唯一)使用されるアイテム +Gameplay:=ゲームプレイ: +• “heart”: A single health symbol, indicates 2 HP=・「ハート」:ヘルス。マーク1つ分で 2 HP を示す +• “bubble”: A single breath symbol, indicates 1 BP=・「泡」:呼吸。マーク1つ分で 1 BP を示す +• HP: Hit point (equals half 1 “heart”)=・HP:ヘルスポイント。「ハート」マーク半分で 1 HP を示す +• BP: Breath point, indicates breath when diving=・BP:ブレスポイント。潜水時の息(酸素量)を示す +• Mob: Computer-controlled enemy=・MOB:コンピュータが操作する敵 +• Crafting: Combining multiple items to create new ones=・クラフト:複数のアイテムを組み合わせて、新しいアイテムを作ること +• Crafting guide: A helper which shows available crafting recipes=・クラフトガイド:利用可能なクラフトのレシピを表示するヘルプ機能 +• Spawning: Appearing in the world=・スポーン:ワールドに出現すること +• Respawning: Appearing again in the world after death=・リスポーン:死後、再びワールドに現れること +• Group: Puts similar things together, often affects gameplay=・グループ:似たようなものを、同類として扱う。しばしばゲームプレイに影響を与える +• noclip: Allows to fly through walls=・壁抜け:壁を通過し飛行を可能にする +Interface=インターフェイス +• Hotbar: Inventory slots at the bottom=・ホットバー:画面底部に配置されたインベントリースロットのこと +• Statbar: Indicator made out of half-symbols, used for health and breath=・ステータスゲージ:分割するマークで作られたメーターのこと。ヘルスや呼吸の表示に使われる +• Minimap: The map or radar at the top right=・ミニマップ:右上に表示させるマップ、またはレーダーのこと +• Crosshair: Seen in the middle, used to point at things=・十字線:画面中央に見える、物をポイントするのに使われる照準。クロスヘアとも言う +Online multiplayer:=オンライン マルチプレイヤー +• PvP: Player vs Player. If active, players can deal damage to each other=・PvP:プレイヤー・バーサス・プレイヤー。有効な場合、プレイヤーはお互いにダメージを与えることができる +• Griefing: Destroying the buildings of other players against their will=・グリーフィング:他のプレイヤーの意思に反して建物を破壊すること(要するに嫌がらせ) +• Protection: Mechanism to own areas of the world, which only allows the owners to modify blocks inside=・保護:ワールドの各エリアを所有する仕組み。エリア内部のブロックは、所有者のみが変更可能となる +Technical terms:=技術的な用語: +• Minetest: This game engine=・Minetest:マインテスト。本ゲームエンジン +• MineClone 2: What you play right now=・MineClone 2:マインクローン2。今、プレイしているもの +• Minetest Game: A game for Minetest by the Minetest developers=・Minetest Game:Minetest 開発者による、Minetest のためのゲーム +• Game: A complete playing experience to be used in Minetest; such as a game or sandbox or similar=・Game:ゲームやサンドボックスなど、Minetest で使用される完全なプレイ体験 +• Mod: A single subsystem which adds or modifies functionality; is the basic building block of games and can be used to further enhance or modify them=・Mod:モッド。機能を追加または変更する1つのサブシステム。ゲームの基本的な構成要素であり、ゲームをさらに強化または変更するために使用できる +• Privilege: Allows a player to do something=・権限:プレイヤーにかかる何らかの制限を解除するための許可 +• Node: Other word for “block”=・ノード:「ブロック」を表す他の語句 +Settings=設定 +There is a large variety of settings to configure Minetest. Pretty much every aspect can be changed that way.=Minetest を構成するために、多種多様な設定があります。ほとんどの局面をその方法で変更できます。 +These are a few of the most important gameplay settings:=これらは、最も重要なゲームプレイの設定の一部です: +• Damage enabled (enable_damage): Enables the health and breath attributes for all players. If disabled, players are immortal=・ダメージを有効化(enable_damage):全プレイヤーのヘルスと呼吸の設定を有効にする。無効の場合、プレイヤーは不死身になる +• Creative Mode (creative_mode): Enables sandbox-style gameplay focusing on creativity rather than a challenging gameplay. The meaning depends on the game; usual changes are: Reduced dig times, easy access to almost all items, tools never wear off, etc.=・クリエイティブモード(creative_mode):挑戦的なゲームプレイではなく、創造性に焦点を当てたサンドボックススタイルのゲームプレイを可能にする。意味はゲームによるが、通常の変更は次の通り:掘る時間が短くなる、ほぼ全てのアイテムが入手しやすくなる、道具が消耗しなくなる、など +• PvP (enable_pvp): Short for “Player vs Player”. If enabled, players can deal damage to each other=・PvP(enable_pvp):“Player vs Player”の略。有効にすると、プレイヤー同士がダメージを与え合うことが可能になる +For a full list of all available settings, use the “All Settings” dialog in the main menu.=利用可能なすべての設定の一覧は、メインメニューの「すべての設定」ダイアログを使用してください。 +Movement modes=移動モード +You can enable some special movement modes that change how you move.=移動方法を変更する、いくつかの特殊な移動モードを有効化できます。 +Pitch movement mode:=ピッチ移動モード: +• Description: If this mode is activated, the movement keys will move you relative to your current view pitch (vertical look angle) when you're in a liquid or in fly mode.=・説明:このモードが有効になっている場合、液中や飛行モードの時に移動キーを使うと、現在のビューピッチ(垂直方向の視線角)に対して相対的に移動します。 +• Default key: [L]=・デフォルトキー:[L] +• No privilege required=・権限は不要 +Fast mode:=高速モード: +• Description: Allows you to move much faster. Hold down the the “Use” key [E] to move faster. In the client configuration, you can further customize fast mode.=・説明:より高速な移動が可能になります。「使う」キー[E]を押しながら移動すると、より速く動けます。クライアント設定にて、高速モードをさらにカスタマイズできます。 +• Default key: [J]=・デフォルトキー:[J] +• Required privilege: fast=・必要な権限:fast +Fly mode:=飛行モード: +• Description: Gravity doesn't affect you and you can move freely in all directions. Use the jump key to rise and the sneak key to sink.=・説明:重力に影響されず、全方向へ自由に動けます。ジャンプキーで上昇し、スニークキーで下降します。 +• Default key: [K]=・デフォルトキー:[K] +• Required privilege: fly=・必要な権限:fly +Noclip mode:=壁抜けモード: +• Description: Allows you to move through walls. Only works when fly mode is enabled, too.=・説明:壁を通過して移動できるようになります。飛行モードも有効な場合のみ機能します。 +• Default key: [H]=・デフォルトキー:[H] +• Required privilege: noclip=・必要な権限:noclip +Console=コンソール +With [F10] you can open and close the console. The main use of the console is to show the chat log and enter chat messages or server commands.=[F10]でコンソールを開いたり閉じたりできます。コンソールの主な用途は、チャットログの表示や、チャットメッセージ及びサーバーコマンドの入力です。 +Using the chat or server command key also opens the console, but it is smaller and will be closed after you sent a message.=チャットやサーバーのコマンドキーを使ってもコンソールを開けますが、サイズが小さく、メッセージ送信後に閉じられることになります。 +Use the chat to communicate with other players. This requires you to have the “shout” privilege.=他のプレイヤーとの連絡には、チャットを利用します。これには、“shout”権限が必要です。 +Just type in the message and hit [Enter]. Public chat messages can not begin with “/”.=メッセージを入力し、[Enter]キーを押すだけです。公開チャットのメッセージは、先頭に“/”をつけることはできません。 +You can send private messages: Say “/msg ” in chat to send “” which can only be seen by .=個人的なメッセージを送信できます:チャットで“/msg ”と言うと、だけが見ることができる“”を送れます。 +There are some special controls for the console:=これらは、コンソール専用の操作方法です: +• [F10] Open/close console=・[F10]:コンソールの開/閉 +• [Enter]: Send message or command=・[Enter]:メッセージ送信 または コマンド +• [Tab]: Try to auto-complete a partially-entered player name=・[Tab]:部分的に入力されたプレイヤー名を、オートコンプリート(自動入力補完)しよう試みる +• [Ctrl]+[Left]: Move cursor to the beginning of the previous word=・[Ctrl]+[Left]:カーソルを、前の単語の先頭に移動する +• [Ctrl]+[Right]: Move cursor to the beginning of the next word=・[Ctrl]+[Right]:カーソルを、次の単語の先頭に移動する +• [Ctrl]+[Backspace]: Delete previous word=・[Ctrl]+[Backspace]:前の単語を削除 +• [Ctrl]+[Delete]: Delete next word=・[Ctrl]+[Delete]:次の単語を削除 +• [Ctrl]+[U]: Delete all text before the cursor=・[Ctrl]+[U]:カーソルより前のテキストをすべて削除 +• [Ctrl]+[K]: Delete all text after the cursor=・[Ctrl]+[K]:カーソルより後のテキストをすべて削除 +• [Page up]: Scroll up=・[Page up]:上にスクロール +• [Page down]: Scroll down=・[Page down]:下にスクロール +There is also an input history. Minetest saves your previous console inputs which you can quickly access later:=また、入力履歴もあります。Minetest は以前のコンソール入力を保存し、後ですぐにアクセスできるようにしています: +• [Up]: Go to previous entry in history=・[Up]:履歴の、前のエントリに移動 +• [Down]: Go to next entry in history=・[Down]:履歴の、次のエントリに移動 +Server commands=サーバーコマンド +Server commands (also called “chat commands”) are little helpers for advanced users. You don't need to use these commands when playing. But they might come in handy to perform some more technical tasks. Server commands work both in multi-player and single-player mode.=サーバーコマンド(「チャットコマンド」とも呼ばれます)は、上級者向けのちょっとした ヘルプ要素です。プレイ中にこれらのコマンドを使う必要はありません。しかし、より技術的なタスクを実行するのに便利かもしれません。サーバーコマンドは、マルチプレイヤーでもシングルプレイヤーでも使えます。 +Server commands can be entered by players using the chat to perform a special server action. There are a few commands which can be issued by everyone, but some commands only work if you have certain privileges granted on the server. There is a small set of basic commands which are always available, other commands can be added by mods.=サーバーコマンドは、プレイヤーがチャットを使って入力することで、特別なサーバーアクションを実行できます。いくつかのコマンドは誰でも出すことができますが、中にはサーバーに与えられた特定の権限を持っている場合にのみ動作するコマンドもあります。基本的なコマンドは常に利用可能で、その他のコマンドはMODによって追加できます。 +To issue a command, simply type it like a chat message or press Minetest's command key (default: [/]). All commands have to begin with “/”, for example “/mods”. The Minetest command key does the same as the chat key, except that the slash is already entered.=コマンドを出すには、単純にチャットメッセージのように入力するか、Minetest のコマンドキー(デフォルト:[/])を押してください。すべてのコマンドは、“/mods”のように“/”で始まる必要があります。Minetest のコマンドキーは、スラッシュがすでに入力されていることを除いて、チャットキーと同じように動作します。 +Commands may or may not give a response in the chat log, but errors will generally be shown in the chat. Try it for yourselves: Close this window and type in the “/mods” command. This will give you the list of available mods on this server.=コマンドは、チャットログで応答したりしなかったりますが、エラーは基本的にチャットで表示されます。自分自身で試してみてください:このウィンドウを閉じて、“/mods”コマンドを入力してください。このサーバーで利用可能なMODのリストが表示されます。 +“/help all” is a very important command: You get a list of all available commands on the server, a short explanation and the allowed parameters. This command is also important because the available commands often differ per server.=“/help all”は非常に重要なコマンドです。サーバ上で利用可能なすべてのコマンドのリスト、簡単な説明、そして許可されたパラメータを得ることができます。利用可能なコマンドはサーバーごとに異なることが多いので、このコマンドも重要です。 +Commands are followed by zero or more parameters.=コマンドの後には、いくつかのパラメータが続くことがあります。 +In the command reference, you see some placeholders which you need to replace with an actual value. Here's an explanation:=コマンドリファレンスには、実際の値に置き換える必要があるプレースホルダーがいくつか表示されています。次に説明します: +• Text in greater-than and lower-than signs (e.g. “”): Placeholder for a parameter=・大なりと小なり記号で挟まれたテキスト(例:“”):パラメータのプレースホルダー +• Anything in square brackets (e.g. “[text]”) is optional and can be omitted=・角括弧内のもの(例:“[text]”):任意であり、省略が可能 +• Pipe or slash (e.g. “text1 | text2 | text3”): Alternation. One of multiple texts must be used (e.g. “text2”)=・パイプまたはスラッシュ(例:“text1|text2|text3”):択一。 区切られたテキストのうちの1つを使用する必要あり(例:"text2") +• Parenthesis: (e.g. “(word1 word2) | word3”): Groups multiple words together, used for alternations=・半角の括弧(例:“(word1 word2) | word3”):複数の単語をグループ化し、交互に使う +• Everything else is to be read as literal text=・それ以外はすべて、文字通りのテキストとして読める +Here are some examples to illustrate the command syntax:=次は、コマンドの構文を説明するための例です: +• /mods: No parameters. Just enter “/mods”=・/mods: パラメータなし。単に“/mods”とだけ入力する +• /me : 1 parameter. You have to enter “/me ” followed by any text, e.g. “/me orders pizza”=・/me :1つのパラメータ。“/me ”の後に、任意のテキストを入力する。例:“/me orders pizza” +• /give : Two parameters. Example: “/give Player default:apple”=・/give :2つのパラメータ。例“/give Player default:apple” +• /help [all|privs|]: Valid inputs are “/help”, “/help all”, “/help privs”, or “/help ” followed by a command name, like “/help time”=・/help [all|privs|]:有効な入力は“/help”,“/help all”,“/help privs”, または“/help time”のように、“/help ”の後にコマンド名を続けたもの +• /spawnentity [,,]: Valid inputs include “/spawnentity boats:boat” and “/spawnentity boats:boat 0,0,0”=・/spawnentity [,,]:有効な入力は“/spawnentity boats:boat”および“/spawnentity boats:boat 0,0,0” +Some final remarks:=最後に一言: +• For /give and /giveme, you need an itemstring. This is an internally used unique item identifier which you may find in the item help if you have the “give” or “debug” privilege=・give と /giveme では、itemstring が必要です。これは内部で使われる固有のアイテム識別子で、“give”または“debug”権限を持っていれば、アイテムのヘルプに記載されているはずです +• For /spawnentity you need an entity name, which is another identifier=・/spawnentity にはエンティティ名が必要で、これは別の識別子です +Privileges=権限 +Each player has a set of privileges, which differs from server to server. Your privileges determine what you can and can't do. Privileges can be granted and revoked from other players by any player who has the privilege called “privs”.=各プレイヤーは、サーバーによって異なる一連の権限を持ちます。権限は、あなたができること、できないことを規定します。“privs”という権限を持っているプレイヤーであれば、権限を他のプレイヤーに付与したり、取り消したりできます。 +On a multiplayer server with the default configuration, new players start with the privileges called “interact” and “shout”. The “interact” privilege is required for the most basic gameplay actions such as building, mining, using, etc. The “shout” privilege allows to chat.=デフォルト設定のマルチプレイヤーサーバーでは、新規プレイヤーは“interact”と“shout”と呼ばれる権限でスタートします。“interact”権限は、建築、採掘、使用など、最も基本的なゲームプレイに必要なものです。“shout”権限は、チャットを行うためのものです。 +There is a small set of core privileges which you'll find on every server, other privileges might be added by mods.=すべてのサーバーで見られる主要な権限の小セットがあり、その他の権限はModによって追加される場合があります。 +To view your own privileges, issue the server command “/privs”.=自分の権限を表示するには、サーバーコマンド“/privs”を実行します。 +Here are a few basic privilege-related commands:=基本的な権限関連のコマンドをいくつか紹介します: +• /privs: Lists your privileges=・/privs:あなたの権限の一覧 +• /privs : Lists the privileges of =・/privs の権限の一覧 +• /help privs: Shows a list and description about all privileges=・/help privs:全権限の一覧と説明を表示 +Players with the “privs” privilege can modify privileges at will:=“privs”権限を持つプレイヤーは、自由に権限を変更可能: +• /grant : Grant to =・/grant を付与 +• /revoke : Revoke from =・/revoke から を取り消す +In single-player mode, you can use “/grantme all” to unlock all abilities.=シングルプレイでは、“/grantme all”ですべての能力が解放されます。 +Light=光 +As the world is entirely block-based, so is the light in the world. Each block has its own brightness. The brightness of a block is expressed in a “light level” which ranges from 0 (total darkness) to 15 (as bright as the sun).=世界がすべてブロックベースである以上、世界の光もまた然りです。各ブロックはそれぞれの明るさを持ちます。ブロックの明るさは“light level”(=明るさ)で表され、0(真っ暗)から15(太陽と同じ明るさ)までの範囲で設定できます。 +There are two types of light: Sunlight and artificial light.=光には2つの種類があります:太陽光と人工光です。 +Artificial light is emitted by luminous blocks. Artificial light has a light level from 1-14.=人工光は発光ブロックから放射されます。人工光は1~14の明るさを持ちます。 +Sunlight is the brightest light and always goes perfectly straight down from the sky at each time of the day. At night, the sunlight will become moonlight instead, which still provides a small amount of light. The light level of sunlight is 15.=太陽光は最も明るい光であり、日中のどの時間帯でも、常に空から完全にまっすぐ降り注いでいます。夜になると、太陽光は代わりに月明かりになりますが、これはまだわずかな光量しか提供しません。太陽光の明るさは15です。 +Blocks have 3 levels of transparency:=ブロックは3段階の透明度を持ちます: +• Transparent: Sunlight goes through limitless, artificial light goes through with losses=・透明:太陽光は無限に通過し、人工光は損失を伴って通過する +• Semi-transparent: Sunlight and artificial light go through with losses=・半透明:太陽光と人工光は損失を伴って通過する +• Opaque: No light passes through=・不透明:光を通さない +Artificial light will lose one level of brightness for each transparent or semi-transparent block it passes through, until only darkness remains (image 1).=人工光は、透明または半透明のブロックを通過するたびに明るさが1段階下がり、やがて暗闇だけが残ります(画像1)。 +Sunlight will preserve its brightness as long it only passes fully transparent blocks. When it passes through a semi-transparent block, it turns to artificial light. Image 2 shows the difference.=太陽光は、完全に透明なブロックだけを通過する限り、その明るさを保てます。半透明のブロックを通過すると、人工光に変化します。画像2 はその違いを示しています。 +Note that “transparency” here only means that the block is able to carry brightness from its neighboring blocks. It is possible for a block to be transparent to light but you can't see trough the other side.=なお、ここでいう「透明度」とは、隣接するブロックの明るさを伝達できるという意味でしかありません。ブロックが光に対して透明でも、あなたは向こう側が見通せないということはあり得ます。 +Coordinates=座標 +The world is a large cube. And because of this, a position in the world can be easily expressed with Cartesian coordinates. That is, for each position in the world, there are 3 values X, Y and Z.=世界は大きな立方体です。そのため、世界における位置は直交座標で簡単に表せます。つまり、世界の各位置には、X、Y、Zの3つの値が存在します。 +Like this: (5, 45, -12)=こんな感じで:(5, 45, -12) +This refers to the position where X@=5, Y@=45 and Z@=-12. The 3 letters are called “axes”: Y is for the height. X and Z are for the horizontal position.=これは、X@=5、Y@=45、Z@=12 の位置を指します。この3文字を“軸”と呼びます:Yは高さ、XとZは水平方向の位置を表します。 +The values for X, Y and Z work like this:=X、Y、Zの値は次のように動きます: +• If you go up, Y increases=・上昇すると、Yが増加 +• If you go down, Y decreases=・下降すると、Yが減少 +• If you follow the sun, X increases=・太陽の進行方向にならうと、Xが増加 +• If you go to the reverse direction, X decreases=・逆方向へ行くと、Xは減少 +• Follow the sun, then go right: Z increases=・太陽に向かって、右に進む:Zが増加 +• Follow the sun, then go left: Z decreases=・太陽に向かって、左に進む:Zが減少 +• The side length of a full cube is 1=・完全な立方体の辺の長さは、1 +You can view your current position in the debug screen (open with [F5]).=デバッグ画面([F5]で開く)にて現在位置を確認できます。 + +# MCL2 extensions +Creative Mode=クリエイティブモード +Enabling Creative Mode in MineClone 2 applies the following changes:=MineClone 2 で Creative Mode を有効にすると、以下の変更が適用されます: +• You keep the things you've placed=・あなたが置いたものを保つ +• Creative inventory is available to obtain most items easily=・ほとんどのアイテムを簡単に入手できるクリエイティブインベントリが利用可能 +• Hand breaks all default blocks instantly=・すべてのデフォルトブロックを手で即座に壊せる +• Greatly increased hand pointing range=・手のポイント範囲の大幅な拡大 +• Mined blocks don't drop items=・採掘されたブロックがアイテムをドロップしない +• Items don't get used up=・アイテムを使い切ることがない +• Tools don't wear off=・道具が消耗しない +• You can eat food whenever you want=・食べたい時にいつでも食べられる +• You can always use the minimap (including radar mode)=・常にミニマップが使える(レーダーモード含む) +Damage is not affected by Creative Mode, it needs to be disabled separately.=ダメージはクリエイティブモードの影響を受けないので、別途無効化する必要があります。 +Mobs=MOB +Mobs are the living beings in the world. This includes animals and monsters.=MOBとは、世界に存在する生き物のことです。動物やモンスターも含まれます。 +Mobs appear randomly throughout the world. This is called “spawning”. Each mob kind appears on particular block types at a given light level. The height also plays a role. Peaceful mobs tend to spawn at daylight while hostile ones prefer darkness. Most mobs can spawn on any solid block but some mobs only spawn on particular blocks (like grass blocks).=MOBは世界各地にランダムに出現します。これを「スポーンする」と言います。各MOBは特定のブロックに、特定の明るさにおいて出現します。また、高さも重要な要素です。平和的なMOBは昼間に出現し、敵対的なMOBは暗闇を好む傾向があります。ほとんどのMOBはどの固体ブロックにもスポーンできますが、特定のブロック(草原のような)にしかスポーンしないMOBもいます。 +Like players, mobs have hit points and sometimes armor points, too (which means you need better weapons to deal any damage at all). Also like players, hostile mobs can attack directly or at a distance. Mobs may drop random items after they die.=プレイヤーと同様に、MOBにもヒットポイントがあり、時にはアーマーポイントもあります(ということは、ダメージを与えるにはより良い武器が必要です)。また、プレイヤーと同様に、敵対するMOBは直接攻撃することも距離を取って攻撃することもできます。MOBは死んだ後、ランダムなアイテムをドロップすることがあります。 +Most animals roam the world aimlessly while most hostile mobs hunt players. Animals can be fed, tamed and bred.=ほとんどの動物があてもなく世界をさまよい、ほとんどの敵対的なMOBがプレイヤーを狩ります。動物には餌を与え、飼いならし、繁殖させることができます。 +Animals=動物 +Animals are peaceful beings which roam the world aimlessly. You can feed, tame and breed them.=動物たちは、世界をあてもなく歩き回る平和な存在です。餌をあげたり、飼いならしたり、繁殖させたりすることができます。 +Feeding:=餌やり: +Each animal has its own taste for food and doesn't just accept any food. To feed, hold an item in your hand and rightclick the animal.=動物にはそれぞれ食べ物の好みがあり、どんな食べ物でもいいというわけではありません。餌を与えるには、アイテムを手に持ち、動物を右クリックします。 +Animals are attraced to the food they like and follow you as long you hold the food item in hand.=動物は好きな食べ物に惹かれ、餌を手にしている間はついてきます。 +Feeding an animal has three uses: Taming, healing and breeding.=動物の給餌には3つの用途があります:飼いならす、癒す、繁殖させる +Feeding heals animals instantly, depending on the quality of the food item.=餌を与えると、餌の質にもよりますが、動物がすぐに回復します。 +Taming:=手懐ける: +A few animals can be tamed. You can generally do more things with tamed animals and use other items on them. For example, tame horses can be saddled and tame wolves fight on your side.=いくつかの動物は手懐けることができます。一般的に、手懐けた動物にはより多くのことができ、他のアイテムも使用できます。例えば、飼いならされた馬には鞍を付けることができ、飼いならされた狼は側で戦ってくれます。 +Breeding:=繁殖 +When you have fed an animal up to its maximum health, then feed it again, you will activate “Love Mode” and many hearts appear around the animal.=動物の体力を最大まで回復させてから、再びエサを与えると「ラブモード」が発動し、動物のまわりにたくさんのハートが現れます。 +Two animals of the same species will start to breed if they are in Love Mode and close to each other. Soon a baby animal will pop up.=同じ種の2匹の動物は、ラブモード状態で近くにいると交配を始めます。すぐに動物の赤ちゃんが飛び出します。 +Baby animals:=動物の仔 +Baby animals are just like their adult couterparts, but they can't be tamed or bred and don't drop anything when they die. They grow to adults after a short time. When fed, they grow to adults faster.=動物の仔は成体と同じですが、飼いならしたり繁殖させたりすることはできず、死んでも何もドロップしません。短期間で成体になります。餌を与えると、より早く成体になります。 +Hunger=満腹度 +Hunger affects your health and your ability to sprint. Hunger is not in effect when damage is disabled.=満腹度はヘルスと走る能力に影響します。ダメージ無効モードでは、満腹度は効果を及ぼしません。 +Core hunger rules:=満腹度の基礎: +• You start with 20/20 hunger points (more points @= less hungry)=・20/20 の満腹度でスタート(ポイントが多い @= 空腹に長く耐えられる) +• Actions like combat, jumping, sprinting, etc. decrease hunger points=・戦闘、ジャンプ、走るなどのアクションは、満腹度が減少 +• Food restores hunger points=・食べ物で満腹度が回復 +• If your hunger bar decreases, you're hungry=・満腹ゲージが減ってきたら、それは既に「空腹」の状態 +• At 18-20 hunger points, you regenerate 1 HP every 4 seconds=・満腹度が18~20のとき、4秒ごとにHPが1回復. +• At 6 hunger points or less, you can't sprint=・満腹度が6以下になると、走ることができなくなる +• At 0 hunger points, you lose 1 HP every 4 seconds (down to 1 HP)=・満腹度が0になると、4秒ごとにHPが1減少(HP1まで) +• Poisonous food decreases your health=・毒のある食べ物は、ヘルスが減少 +Details:=詳細: +You have 0-20 hunger points, indicated by 20 drumstick half-icons above the hotbar. You also have an invisible attribute: Saturation.=あなたは 0〜20 の満腹度を持っており、ホットバーの上にある20個分の骨付き肉(アイコン半分で1個分)がそれを示しています。また、見えない属性も持っています:隠し満腹度 +Hunger points reflect how full you are while saturation points reflect how long it takes until you're hungry again.=満腹度は「空腹に耐えられる時間」と「腹持ちの許容量」を反映し、隠し満腹度は、再び空腹になるまでの「腹持ちする時間」が反映(見えませんが)されています。 +Each food item increases both your hunger level as well your saturation.=食べ物は、満腹度と隠し満腹度の両方を増加させます。 +Food with a high saturation boost has the advantage that it will take longer until you get hungry again.=隠し満腹度増加の高い食品は、再び空腹になるまでの時間が長くなるという利点があります。 +A few food items might induce food poisoning by chance. When you're poisoned, the health and hunger symbols turn sickly green. Food poisoning drains your health by 1 HP per second, down to 1 HP. Food poisoning also drains your saturation. Food poisoning goes away after a while or when you drink milk.=いくつかの食べ物で、偶然にも食中毒を誘発することがあります。食中毒にかかると、ヘルスと満腹ゲージが病的な緑色になります。食中毒になると毎秒1HPずつ消耗しますが、減るのは1HPまでで0にはなりません。また、食中毒は隠し満腹度も消耗します。食中毒はミルクを飲むか、しばらく経つと治ります。 +You start with 5 saturation points. The maximum saturation is equal to your current hunger level. So with 20 hunger points your maximum saturation is 20. What this means is that food items which restore many saturation points are more effective the more hunger points you have. This is because at low hunger levels, a lot of the saturation boost will be lost due to the low saturation cap.=隠し満腹度は5からスタートします。隠し満腹度の最大値は現在の満腹度と同じです。つまり、満腹度が20ある時は、最大隠し満腹度も20となります。このことは、隠し満腹度を多く回復させる食べ物は、満腹度が高い時ほど効果的であることを意味します。例えば、満腹度が低い場合は隠し満腹度の上限も低いため、それを超える量の隠し満腹度回復は損をしていることになります。 +If your saturation reaches 0, you're hungry and start to lose hunger points. Whenever you see the hunger bar decrease, it is a good time to eat.=隠し満腹度が0になると、「空腹」状態となり満腹度が減少しはじめます。満腹ゲージの減少を確認したらいつでも、食事する良いタイミングです。 +Saturation decreases by doing things which exhaust you (highest exhaustion first):=消耗する行動によって、隠し満腹度が低下(一番目が最も消耗する): +• Regenerating 1 HP=・HPが回復する +• Suffering food poisoning=・食中毒を起こす +• Sprint-jumping=・走りながらジャンプする +• Sprinting=・走る +• Attacking=・攻撃する +• Taking damage=・ダメージを受ける +• Swimming=・泳ぐ +• Jumping=・ジャンプする +• Mining a block=・ブロックを採掘する +Other actions, like walking, do not exaust you.=歩くなどの他の行動では、消耗しません。 +If you have a map item in any of your hotbar slots, you can use the minimap.=いずれかのホットバースロットにマップアイテムがあれば、ミニマップが使えます。 diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr b/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr index a66311448..6803e6e40 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr @@ -45,3 +45,4 @@ Mining durability: @1=Durabilité de minage: @1 Block breaking strength: @1=Résistance à la rupture: @1 @1 uses=@1 utilisations Unlimited uses=Utilisations illimitées +Durability: @1=Durabilité \ No newline at end of file diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr b/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr new file mode 100644 index 000000000..5e5cd5e7a --- /dev/null +++ b/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr @@ -0,0 +1,48 @@ +# textdomain: mcl_tt +Head armor=頭具 +Torso armor=胴衣 +Legs armor=脚具 +Feet armor=足具 +Armor points: @1=防具値:@1 +Armor durability: @1=防具耐久度:@1 +Protection: @1%=外傷防護:@1% +Hunger points: +@1=満腹度:+@1 +Saturation points: +@1=隠し満腹度:+@1 +Deals damage when falling=落下時にダメージ発生 +Grows on grass blocks or dirt=草原や土の上に生育 +Grows on grass blocks, podzol, dirt or coarse dirt=草原、ポドゾル、土、粗い土の上に生育 +Flammable=可燃性 +Zombie view range: -50%=ゾンビに見つかる距離:-50% +Skeleton view range: -50%=スケルトンに見つかる距離:-50% +Creeper view range: -50%=クリーパーに見つかる距離:-50% +Damage: @1=ダメージ:@1 +Damage (@1): @2=ダメージ (@1):@2 +Healing: @1=回復:@1 +Healing (@1): @2=回復 (@1):@2 +Full punch interval: @1s=全力攻撃の間隔:@1秒 +Contact damage: @1 per second=接触ダメージ:@1/秒 +Contact healing: @1 per second=接触回復:@1/秒 +Drowning damage: @1=窒息ダメージ:@1 +Bouncy (@1%)=弾力性 (@1%) +Luminance: @1=発光:@1 +Slippery=滑りやすい +Climbable=よじ登れる +Climbable (only downwards)=よじ登れる(下方のみ) +No jumping=ジャンプ不可 +No swimming upwards=上方への水泳不可 +No rising=上昇不可 +Fall damage: @1%=落下ダメージ:@1% +Fall damage: +@1%=落下ダメージ:+@1% +No fall damage=落下ダメージなし +Mining speed: @1=採掘速度:@1 +Very fast=とても速い +Extremely fast=とてつもなく速い +Fast=速い +Slow=遅い +Very slow=とても遅い +Painfully slow=苦痛レベルで遅い +Mining durability: @1=採掘耐久度:@1 +Block breaking strength: @1=ブロック破壊力:@1 +@1 uses=@1 使用 +Unlimited uses=無限に使用可能 +Durability: @1=耐久度:@1 diff --git a/mods/HUD/awards/api.lua b/mods/HUD/awards/api.lua index 49b11a6cf..2bbea3c9b 100644 --- a/mods/HUD/awards/api.lua +++ b/mods/HUD/awards/api.lua @@ -217,7 +217,7 @@ function awards.unlock(name, award) -- Get award minetest.log("action", name.." has gotten award "..award) - minetest.chat_send_all(S("@1 has made the achievement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]"))) + minetest.chat_send_all(S("@1 has made the advancement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]"))) data.unlocked[award] = award awards.save() @@ -257,9 +257,13 @@ function awards.unlock(name, award) local custom_announce = awdef.custom_announce if not custom_announce then if awdef.secret then - custom_announce = S("Secret achievement gotten:") + custom_announce = S("Secret Advancement Made:") + elseif awdef.type == "Goal" then + custom_announce = S("Goal Completed:") + elseif awdef.type == "Challenge" then + custom_announce = S("Challenge Completed:") else - custom_announce = S("Achievement gotten:") + custom_announce = S("Advancement Made:") end end @@ -283,9 +287,13 @@ function awards.unlock(name, award) elseif awards.show_mode == "chat" then local chat_announce if awdef.secret == true then - chat_announce = S("Secret achievement gotten: @1") + chat_announce = S("Secret Advancement Made: @1") + elseif awdef.type == "Goal" then + chat_announce = S("Goal Completed: @1") + elseif awdef.type == "Challenge" then + chat_announce = S("Challenge Completed: @1") else - chat_announce = S("Achievement gotten: @1") + chat_announce = S("Advancement Made: @1") end -- use the chat console to send it minetest.chat_send_player(name, string.format(chat_announce, title)) @@ -306,9 +314,13 @@ function awards.unlock(name, award) }) local hud_announce if awdef.secret == true then - hud_announce = S("Secret achievement gotten!") + hud_announce = S("Secret Advancement Made!") + elseif awdef.type == "Goal" then + hud_announce = S("Goal Completed!") + elseif awdef.type == "Challenge" then + hud_announce = S("Challenge Completed!") else - hud_announce = S("Achievement gotten!") + hud_announce = S("Advancement Made!") end local two = player:hud_add({ hud_elem_type = "text", @@ -389,10 +401,10 @@ function awards.getFormspec(name, to, sid) local def = awards.def[item.name] if def and def.secret and not item.got then - formspec = formspec .. "label[1,2.75;"..minetest.formspec_escape(S("(Secret achievement)")).."]".. + formspec = formspec .. "label[1,2.75;"..minetest.formspec_escape(S("(Secret Advancement)")).."]".. "image[1,0;3,3;awards_unknown.png]" if def and def.description then - formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;"..minetest.formspec_escape(S("Get this achievement to find out what it is."))..";]" + formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;"..minetest.formspec_escape(S("Make this advancement to find out what it is."))..";]" end else local title = item.name @@ -450,7 +462,7 @@ function awards.getFormspec(name, to, sid) first = false if def.secret and not award.got then - formspec = formspec .. "#707070" .. minetest.formspec_escape(S("(Secret Award)")) + formspec = formspec .. "#707070" .. minetest.formspec_escape(S("(Secret Advancement)")) else local title = award.name if def and def.title then @@ -472,7 +484,7 @@ function awards.show_to(name, to, sid, text) name = to end if name == to and awards.player(to).disabled then - minetest.chat_send_player(S("You've disabled awards. Type /awards enable to reenable.")) + minetest.chat_send_player(name,S("You've disabled awards. Type /awards enable to reenable.")) return end if text then diff --git a/mods/HUD/awards/chat_commands.lua b/mods/HUD/awards/chat_commands.lua index 9b990fd0c..04371139f 100644 --- a/mods/HUD/awards/chat_commands.lua +++ b/mods/HUD/awards/chat_commands.lua @@ -18,48 +18,42 @@ local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_chatcommand("awards", { params = S("[c|clear|disable|enable]"), - description = S("Show, clear, disable or enable your achievements"), + description = S("Show, clear, disable or enable your advancements."), func = function(name, param) + if param == "enable" then + awards.enable(name) + minetest.chat_send_player(name, S("You have enabled your advancements.")) + return + end + + if awards.player(name).disabled then + minetest.chat_send_player(name, S("Awards are disabled, enable them first by using /awards enable!")) + return + end + if param == "clear" then - if awards.player(name).disabled ~= nil then - minetest.chat_send_player(name, S("Awards are disabled, enable them first by using /awards enable!")) - else - awards.clear_player(name) - minetest.chat_send_player(name, - S("All your awards and statistics have been cleared. You can now start again.")) - end + awards.clear_player(name) + minetest.chat_send_player(name, + S("All your awards and statistics have been cleared. You can now start again.")) elseif param == "disable" then awards.disable(name) - minetest.chat_send_player(name, S("You have disabled your achievements.")) - elseif param == "enable" then - awards.enable(name) - minetest.chat_send_player(name, S("You have enabled your achievements.")) - elseif param == "c" then - if awards.player(name).disabled ~= nil then - minetest.chat_send_player(name, S("Awards are disabled, enable them first by using /awards enable!")) - else - awards.show_to(name, name, nil, true) - end + minetest.chat_send_player(name, S("You have disabled your advancements.")) else - if awards.player(name).disabled ~= nil then - minetest.chat_send_player(name, S("Awards are disabled, enable them first by using /awards enable!")) - else - awards.show_to(name, name, nil, false) - end + awards.show_to(name, name, nil, false) end end }) -minetest.register_privilege("achievements", { - description = S("Can give achievements to any player"), +minetest.register_privilege("advancements", { + description = S("Can give advancements to any player"), give_to_singleplayer = false, give_to_admin = false, }) -minetest.register_chatcommand("achievement", { - params = S("(grant ( | all)) | list"), - privs = { achievements = true }, - description = S("Give achievement to player or list all achievements"), +minetest.register_chatcommand("advancement", { + params = S("(grant ( | all)) | list"), + privs = { advancements = true }, + description = S("Give advancement to player or list all advancements"), func = function(name, param) if param == "list" then local list = {} @@ -92,7 +86,7 @@ minetest.register_chatcommand("achievement", { awards.unlock(playername, achievement) return true, S("Done.") else - return false, S("Achievement “@1” does not exist.", achievement) + return false, S("Advancement “@1” does not exist.", achievement) end end }) diff --git a/mods/HUD/awards/locale/awards.fr.tr b/mods/HUD/awards/locale/awards.fr.tr index c227a9c07..e69b77281 100644 --- a/mods/HUD/awards/locale/awards.fr.tr +++ b/mods/HUD/awards/locale/awards.fr.tr @@ -1,25 +1,24 @@ # textdomain:awards @1/@2 chat messages=@1/@2 chat messages -@1/@2 crafted=@1/@2 fabrication -@1/@2 deaths=@1/@2 Mort +@1/@2 crafted=@1/@2 fabriqués +@1/@2 deaths=@1/@2 morts @1/@2 dug=@1/@2 creusé @1/@2 game joins=@1/@2 sessions -@1/@2 placed=@1/@2 mis +@1/@2 placed=@1/@2 placé @1 (got)=@1 (obtenu) -@1: @1=@1: @1 +@1: @2=@1 : @2 @1’s awards:=Récompenses de @1: (Secret Award)=(Récompense Secrètte) = = -A Cat in a Pop-Tart?!=A Cat in a Pop-Tart?! Achievement gotten!=Succès obtenu ! Achievement gotten:=Succès obtenu : Achievement gotten: @1=Succès obtenu : @1 Achievement not found.=Succès inconnu All your awards and statistics have been cleared. You can now start again.=Toutes vos récompenses et statistiques ont été effacées. Vous pouvez maintenant recommencer. Awards=Récompenses -Craft: @1×@2=Frabrication: @1×@2 -Craft: @1=Frabrication: @1 +Craft: @1×@2=Fabrication: @1×@2 +Craft: @1=Fabrication: @1 Die @1 times.=Mort @1 fois. Die.=Mort. Get the achievements statistics for the given player or yourself=Obtenez les statistiques de succès pour le joueur donné ou vous-même @@ -28,9 +27,9 @@ Join the game.=Rejoignez le jeu. List awards in chat (deprecated)=Liste des récompenses dans le chat (obsolète) Place a block: @1=Placer un bloc: @1 Place blocks: @1×@2=Placer des blocs: @1×@2 -Secret Achievement gotten!=Succès secret obtenu ! -Secret Achievement gotten:=Succès secret obtenu : -Secret Achievement gotten: @1=Succès secret obtenu : @1 +Secret achievement gotten!=Succès secret obtenu ! +Secret achievement gotten:=Succès secret obtenu : +Secret achievement gotten: @1=Succès secret obtenu : @1 Show details of an achievement=Afficher les détails d'un succès Show, clear, disable or enable your achievements=Affichez, effacez, désactivez ou activez vos succès Get this achievement to find out what it is.=Obtenez ce succès pour découvrir de quoi il s'agit. @@ -59,3 +58,7 @@ Invalid action.=Action invalide. Player is not online.=Le joueur n'est pas en ligne. Done.=Terminé. Achievement “@1” does not exist.=Le succès «@1» n'existe pas. +@1 has made the achievement @2=@1 a obtenu le succès +Mine a block: @1=Miner un bloc : @1 +Mine blocks: @1×@2=Miner des blocs : @1×@2 +Awards are disabled, enable them first by using /awards enable!=Les succès sont désactivés, activez les d'abord en utilisant /awards enable ! diff --git a/mods/HUD/awards/locale/awards.ja.tr b/mods/HUD/awards/locale/awards.ja.tr new file mode 100644 index 000000000..5a3b73174 --- /dev/null +++ b/mods/HUD/awards/locale/awards.ja.tr @@ -0,0 +1,70 @@ +# textdomain:awards +@1/@2 chat messages=@1/@2 チャットメッセージ +@1/@2 crafted=@1/@2 クラフトした +@1/@2 deaths=@1/@2 死亡した +@1/@2 dug=@1/@2 掘った +@1/@2 game joins=@1/@2 ゲームに参加した +@1/@2 placed=@1/@2 置いた +@1 (got)=@1(入手した) +@1: @2=@1: @2 +@1’s awards:=@1 のアワード +(Secret Award)=(シークレットアワード) +=<実績 ID> +=<名前> +Advancement Made!=進捗 更新! +Advancement Made:=進捗 更新: +Advancement: @1=進捗:@1 +Achievement not found.=実績 未検出 +All your awards and statistics have been cleared. You can now start again.=すべてのアワードと統計がクリアされました。これで再スタートが可能です。 +Awards=アワード +Craft: @1×@2=クラフト: @1×@2 +Craft: @1=クラフト: @1 +Die @1 times.=@1回死にました。 +Die.=死にました。 +Get the achievements statistics for the given player or yourself=所定のプレーヤーまたはあなた自身の実績統計を取得します。 +Join the game @1 times.=ゲームに@1回参加しています。 +Join the game.=ゲームに参加しています。 +List awards in chat (deprecated)=チャットにアワードを一覧表示(非推奨) +Place a block: @1=ブロックを配置:@1 +Place blocks: @1×@2=配置ブロック:@1×@2 +Secret Advancement Made!=隠し進捗 更新! +Secret Advancement Made:=隠し進捗 更新: +Secret Advancement Made: @1=隠し進捗:@1 +Show details of an achievement=実績の詳細を表示 +Show, clear, disable or enable your advancements.=進捗の表示、消去、無効化、有効化等。 +Make this advancement to find out what it is.=この進捗を遂げて、それが何であるかを発見してください。 +Write @1 chat messages.=@1チャットメッセージを書いてください。 +Write something in chat.=チャットに何か書いてください。 +You have disabled your advancements.=進捗を無効にしました。 +You have enabled your advancements.=進捗を有効にしました。 +You have not gotten any awards.=アワードの受賞歴はありません。 +You've disabled awards. Type /awards enable to reenable.=アワードが無効になっています。再度有効にするには、 /awards enable と入力してください。 +[c|clear|disable|enable]=[c|クリア|無効化|有効化] +OK=OK +Error: No awards available.=エラー:アワードに該当するものはありません。 +Eat: @1×@2=食す:@1×@2 +Eat: @1=食す:@1×@2 +@1/@2 eaten=@1/@2 食した +Place @1 block(s).=ブロックを@1個 配置します。 +Dig @1 block(s).=ブロックを@1個 掘ります。 +Eat @1 item(s).=アイテムを@1個 食べます。 +Craft @1 item(s).=アイテムを@1個 クラフトします。 +Can give advancements to any player=任意のプレイヤーに進捗を供与可能 +(grant ( | all)) | list=(供与 <プレイヤー> (<進捗> | 全て)) | リスト +Give advancement to player or list all advancements=プレイヤーに進捗を与えるか、すべての進捗をリストアップ +@1 (@2)=@1 (@2) +Invalid syntax.=無効な構文です。 +Invalid action.=無効な動作です。 +Player is not online.=プレーヤーがオンラインになってません。 +Done.=完了です。 +Advancement “@1” does not exist.=進捗“@1”は存在しません。 +@1 has made the advancement @2=@1は進捗@2を更新 +Mine a block: @1=ブロックを採掘:@1 +Mine blocks: @1×@2=採掘ブロック:@1×@2 +Awards are disabled, enable them first by using /awards enable!=アワードは無効になってます、まず /awards enable を使用して有効にしてください! +Goal Completed:=目標達成: +Goal Completed!=目標達成! +Goal Completed: @1=目標達成:@1 +Challenge Completed:=チャレンジ達成: +Challenge Completed!=チャレンジ達成! +Challenge Completed: @1=チャレンジ達成:@1 diff --git a/mods/HUD/awards/locale/template.txt b/mods/HUD/awards/locale/template.txt index fa05b22b3..5312c2ba7 100644 --- a/mods/HUD/awards/locale/template.txt +++ b/mods/HUD/awards/locale/template.txt @@ -11,9 +11,9 @@ (Secret Award)= = = -Achievement gotten!= -Achievement gotten:= -Achievement gotten: @1= +Advancement Made!= +Advancement Made:= +Advancement: @1= Achievement not found.= All your awards and statistics have been cleared. You can now start again.= Awards= @@ -27,16 +27,16 @@ Join the game.= List awards in chat (deprecated)= Place a block: @1= Place blocks: @1×@2= -Secret achievement gotten!= -Secret achievement gotten:= -Secret achievement gotten: @1= +Secret Advancement Made!= +Secret Advancement Made:= +Secret Advancement Made: @1= Show details of an achievement= -Show, clear, disable or enable your achievements= -Get this achievement to find out what it is.= +Show, clear, disable or enable your advancements.= +Make this advancement to find out what it is.= Write @1 chat messages.= Write something in chat.= -You have disabled your achievements.= -You have enabled your achievements.= +You have disabled your advancements.= +You have enabled your advancements.= You have not gotten any awards.= You've disabled awards. Type /awards enable to reenable.= [c|clear|disable|enable]= @@ -49,16 +49,22 @@ Place @1 block(s).= Dig @1 block(s).= Eat @1 item(s).= Craft @1 item(s).= -Can give achievements to any player= -(grant ( | all)) | list= -Give achievement to player or list all achievements= +Can give advancements to any player= +(grant ( | all)) | list= +Give advancement to player or list all advancements= @1 (@2)= Invalid syntax.= Invalid action.= Player is not online.= Done.= -Achievement “@1” does not exist.= -@1 has made the achievement @2= +Advancement “@1” does not exist.= +@1 has made the advancement @2= Mine a block: @1= Mine blocks: @1×@2= Awards are disabled, enable them first by using /awards enable!= +Goal Completed:= +Goal Completed!= +Goal Completed: @1= +Challenge Completed:= +Challenge Completed!= +Challenge Completed: @1= diff --git a/mods/HUD/hudbars/locale/hudbars.ja.tr b/mods/HUD/hudbars/locale/hudbars.ja.tr new file mode 100644 index 000000000..712c915cb --- /dev/null +++ b/mods/HUD/hudbars/locale/hudbars.ja.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=ヘルス +Breath=呼吸 + +# Default format string for progress bar-style HUD bars, e.g. “Health 5/20” +@1: @2/@3=@1:@2/@3 diff --git a/mods/HUD/mcl_achievements/init.lua b/mods/HUD/mcl_achievements/init.lua index c963773d1..ced758948 100644 --- a/mods/HUD/mcl_achievements/init.lua +++ b/mods/HUD/mcl_achievements/init.lua @@ -15,7 +15,9 @@ awards.register_achievement("mcl_buildWorkBench", { type = "craft", item = "mcl_crafting_table:crafting_table", target = 1 - } + }, + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:buildPickaxe", { title = S("Time to Mine!"), @@ -25,7 +27,9 @@ awards.register_achievement("mcl:buildPickaxe", { type = "craft", item = "mcl_tools:pick_wood", target = 1 - } + }, + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:buildFurnace", { title = S("Hot Topic"), @@ -35,7 +39,9 @@ awards.register_achievement("mcl:buildFurnace", { type = "craft", item = "mcl_furnaces:furnace", target = 1 - } + }, + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:buildHoe", { title = S("Time to Farm!"), @@ -45,7 +51,9 @@ awards.register_achievement("mcl:buildHoe", { type = "craft", item = "mcl_farming:hoe_wood", target = 1 - } + }, + type = "Advancement", + group = "Husbandry", }) awards.register_achievement("mcl:makeBread", { title = S("Bake Bread"), @@ -55,7 +63,9 @@ awards.register_achievement("mcl:makeBread", { type = "craft", item = "mcl_farming:bread", target = 1 - } + }, + type = "Advancement", + group = "Husbandry", }) awards.register_achievement("mcl:bakeCake", { @@ -66,7 +76,9 @@ awards.register_achievement("mcl:bakeCake", { type = "craft", item = "mcl_cake:cake", target = 1 - } + }, + type = "Advancement", + group = "Husbandry", }) awards.register_achievement("mcl:buildBetterPickaxe", { title = S("Getting an Upgrade"), @@ -77,7 +89,9 @@ awards.register_achievement("mcl:buildBetterPickaxe", { type = "craft", item = "mcl_tools:pick_stone", target = 1 - } + }, + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:buildSword", { title = S("Time to Strike!"), @@ -87,7 +101,9 @@ awards.register_achievement("mcl:buildSword", { type = "craft", item = "mcl_tools:sword_wood", target = 1 - } + }, + type = "Advancement", + group = "Adventure", }) awards.register_achievement("mcl:bookcase", { @@ -98,7 +114,22 @@ awards.register_achievement("mcl:bookcase", { type = "craft", item = "mcl_books:bookshelf", target = 1 - } + }, + type = "Advancement", + group = "Overworld", +}) + +awards.register_achievement("mcl:buildIronPickaxe", { + title = S("Isn't It Iron Pick"), + description = S("Craft a iron pickaxe using sticks and iron."), + icon = "default_tool_steelpick.png", + trigger = { + type = "craft", + item = "mcl_tools:pick_iron", + target = 1 + }, + type = "Advancement", + group = "Overworld", }) -- Item pickup achievements: These are awarded when picking up a certain item. @@ -107,35 +138,78 @@ awards.register_achievement("mcl:diamonds", { title = S("DIAMONDS!"), description = S("Pick up a diamond from the floor."), icon = "mcl_core_diamond_ore.png", + type = "Advancement", }) awards.register_achievement("mcl:blazeRod", { title = S("Into Fire"), description = S("Pick up a blaze rod from the floor."), icon = "mcl_mobitems_blaze_rod.png", + type = "Advancement", + group = "Nether", }) awards.register_achievement("mcl:killCow", { title = S("Cow Tipper"), description = S("Pick up leather from the floor.\nHint: Cows and some other animals have a chance to drop leather, when killed."), icon = "mcl_mobitems_leather.png", + type = "Advancement", + group = "Adventure", }) awards.register_achievement("mcl:mineWood", { title = S("Getting Wood"), description = S("Pick up a wood item from the ground.\nHint: Punch a tree trunk until it pops out as an item."), icon = "default_tree.png", + type = "Advancement", + group = "Overworld", }) +awards.register_achievement("mcl:whosCuttingOnions", { + title = S("Who is Cutting Onions?"), + description = S("Pick up a crying obsidian from the floor."), + icon = "default_obsidian.png^mcl_core_crying_obsidian.png", + type = "Advancement", + group = "Nether", +}) + +awards.register_achievement("mcl:hiddenInTheDepths", { + title = S("Hidden in the Depths"), + description = S("Pick up an Ancient Debris from the floor."), + icon = "mcl_nether_ancient_debris_side.png", + type = "Advancement", + group = "Nether", +}) + +awards.register_achievement("mcl:PickUpDragonEgg", { + title = S("The Next Generation"), + description = S("Hold the Dragon Egg.\nHint: Pick up the egg from the ground and have it in your inventory."), + icon = "mcl_end_dragon_egg.png", + type = "Goal", + group = "End", +}) + +awards.register_achievement("mcl:skysTheLimit", { + title = S("Sky's the Limit"), + description = S("Find the elytra and prepare to fly above and beyond!"), + icon = "mcl_armor_inv_elytra.png", + type = "Goal", + group = "End", +}) -- TODO: Make also unlock when moved to inventory, not just picking up from ground + -- Smelting achivements: These are awarded when picking up an item from a furnace -- output. They are given in mcl_furnaces. awards.register_achievement("mcl:acquireIron", { title = S("Aquire Hardware"), description = S("Take an iron ingot from a furnace's output slot.\nHint: To smelt an iron ingot, put a fuel (like coal) and iron ore into a furnace."), icon = "default_steel_ingot.png", + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:cookFish", { title = S("Delicious Fish"), description = S("Take a cooked fish from a furnace.\nHint: Use a fishing rod to catch a fish and cook it in a furnace."), icon = "mcl_fishing_fish_cooked.png", + type = "Advancement", + group = "Husbandry", }) -- Other achievements triggered outside of mcl_achievements @@ -145,6 +219,8 @@ awards.register_achievement("mcl:onARail", { title = S("On A Rail"), description = S("Travel by minecart for at least 1000 meters from your starting point in a single ride."), icon = "default_rail.png", + type = "Challenge", + group = "Adventure", }) -- Triggered in mcl_bows @@ -154,13 +230,205 @@ awards.register_achievement("mcl:snipeSkeleton", { -- TODO: The range should be 50, not 20. Nerfed because of reduced bow range description = S("Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters."), icon = "mcl_bows_bow.png", + type = "Challenge", + group = "Adventure", }) -- Triggered in mcl_portals awards.register_achievement("mcl:buildNetherPortal", { - title = S("Into the Nether"), + title = S("We Need to Go Deeper"), description = S("Use obsidian and a fire starter to construct a Nether portal."), - icon = "default_obsidian.png", + icon = "mcl_fire_flint_and_steel.png", + type = "Advancement", + group = "Overworld", +}) + +awards.register_achievement("mcl:enterEndPortal", { + title = S("The End?"), + description = S("Or the beginning?\nHint: Enter an end portal."), + icon = "mcl_end_end_stone.png", + type = "Advancement", + group = "Overworld", +}) + +awards.register_achievement("mcl:theNether", { + title = S("The Nether"), + description = S("Bring summer clothes.\nHint: Enter the Nether."), + icon = "mcl_nether_netherrack.png", + type = "Advancement", + group = "Nether", +}) + +-- Triggered in mcl_totems +awards.register_achievement("mcl:postMortal", { + title = S("Postmortal"), + description = S("Use a Totem of Undying to cheat death."), + icon = "mcl_totems_totem.png", + type = "Goal", + group = "Adventure", +}) + +-- Triggered in mcl_beds +awards.register_achievement("mcl:sweetDreams", { + title = S("Sweet Dreams"), + description = S("Sleep in a bed to change your respawn point."), + icon = "mcl_beds_bed_red_inv.png", + type = "Advancement", + group = "Adventure", +}) + +awards.register_achievement("mcl:notQuiteNineLives", { + title = S('Not Quite "Nine" Lives'), + description = S("Charge a Respawn Anchor to the maximum."), + icon = "respawn_anchor_side4.png", + type = "Advancement", + group = "Nether", +}) + +-- Triggered in mobs_mc +awards.register_achievement("mcl:whatAdeal", { + title = S("What A Deal!"), + description = S("Successfully trade with a Villager."), + icon = "mcl_core_emerald.png", + type = "Advancement", + group = "Adventure", +}) + +awards.register_achievement("mcl:tacticalFishing", { + title = S("Tactical Fishing"), + description = S("Catch a fish... without a fishing rod!"), + icon = "pufferfish_bucket.png", + type = "Advancement", + group = "Husbandry", +}) + +awards.register_achievement("mcl:cutestPredator", { + title = S("The Cutest Predator"), + description = S("Catch an Axolotl with a bucket!"), + icon = "axolotl_bucket.png", + type = "Advancement", + group = "Husbandry", +}) + +awards.register_achievement("mcl:witheringHeights", { + title = S("Withering Heights"), + description = S("Summon the wither from the dead."), + icon = "mcl_mobitems_nether_star.png", + type = "Advancement", + group = "Nether", +}) + +awards.register_achievement("mcl:freeTheEnd", { + title = S("Free the End"), + description = S("Kill the ender dragon. Good Luck!"), + icon = "(spawn_egg.png^[multiply:#252525)^(spawn_egg_overlay.png^[multiply:#b313c9)", -- TODO: Dragon Head Icon + type = "Advancement", + group = "End", +}) + +-- Triggered in mcl_fishing +awards.register_achievement("mcl:fishyBusiness", { + title = S("Fishy Business"), + description = S("Catch a fish.\nHint: Catch a fish, salmon, clownfish, or pufferfish."), + icon = "mcl_fishing_fishing_rod.png", + type = "Advancement", + group = "Husbandry", +}) + +-- Triggered in mcl_compass +awards.register_achievement("mcl:countryLode", { + title = S("Country Lode,\nTake Me Home"), + description = S("Use a compass on a Lodestone."), + icon = "lodestone_side4.png", + type = "Advancement", + group = "Nether", +}) + +-- Triggered in mcl_smithing_table +awards.register_achievement("mcl:seriousDedication", { + title = S("Serious Dedication"), + description = S("Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices."), + icon = "farming_tool_netheritehoe.png", + type = "Challenge", + group = "Husbandry", +}) + +-- Triggered in mcl_brewing +awards.register_achievement("mcl:localBrewery", { + title = S("Local Brewery"), + description = S("Brew a Potion.\nHint: Take a potion or glass bottle out of the brewing stand."), + icon = "mcl_potions_potion_overlay.png^[colorize:#F82423:"..tostring(127).."^mcl_potions_potion_bottle.png", + type = "Advancement", + group = "Nether", +}) + +-- Triggered in mcl_enchanting +awards.register_achievement("mcl:enchanter", { + title = S("Enchanter"), + description = S("Enchant an item using an Enchantment Table."), + icon = "mcl_enchanting_book_enchanted.png", + type = "Advancement", + group = "Overworld", +}) + +--Triggered in mcl_beacons +awards.register_achievement("mcl:beacon", { + title = S("Bring Home the Beacon"), + description = S("Use a beacon."), + icon = "beacon_achievement_icon.png", + type = "Advancement", + group = "Nether", +}) + +awards.register_achievement("mcl:maxed_beacon", { + title = S("Beaconator"), + description = S("Use a fully powered beacon."), + icon = "beacon_achievement_icon.png", + type = "Goal", + group = "Nether", +}) + +-- Triggered in mcl_end +awards.register_achievement("mcl:theEndAgain", { + title = S("The End... Again..."), + description = S("Respawn the Ender Dragon."), + icon = "mcl_end_crystal_item.png", + type = "Goal", + group = "End", +}) + +-- Triggered in mcl_beehives +awards.register_achievement("mcl:bee_our_guest", { + title = S("Bee Our Guest"), + description = S("Use a campfire to collect a bottle of honey from a beehive without aggrivating the bees inside."), + icon = "mcl_honey_honey_bottle.png", + type = "Advancement", + group = "Husbandry", +}) + +awards.register_achievement("mcl:total_beelocation", { + title = S("Total Beelocation"), + description = S("Move a bee nest, with 3 bees inside, using a silk touch enchanted tool."), + icon = "mcl_beehives_bee_nest_front_honey.png", + type = "Advancement", + group = "Husbandry", +}) + +-- Triggered in mcl_copper +awards.register_achievement("mcl:wax_on", { + title = S("Wax On"), + description = S("Apply honeycomb to a copper block to protect it from the elements."), + icon = "mcl_honey_honeycomb.png", + type = "Advancement", + group = "Husbandry", +}) + +awards.register_achievement("mcl:wax_off", { + title = S("Wax Off"), + description = S("Scrape wax off of a copper block."), + icon = "default_tool_stoneaxe.png", + type = "Advancement", + group = "Husbandry", }) -- NON-PC ACHIEVEMENTS (XBox, Pocket Edition, etc.) @@ -244,14 +512,38 @@ awards.register_achievement("mcl:stoneAge", { title = S("Stone Age"), description = S("Mine a stone with new pickaxe."), icon = "default_cobble.png", + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:hotStuff", { title = S("Hot Stuff"), description = S("Put lava in a bucket."), icon = "bucket_lava.png", + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:obsidian", { title = S("Ice Bucket Challenge"), description = S("Obtain an obsidian block."), icon = "default_obsidian.png", + type = "Advancement", + group = "Overworld", +}) + +awards.register_achievement("mcl:hero_of_the_village", { + title = S("Hero of the Village"), + description = S("Successfully defend a village from a raid"), + icon = "mcl_raids_hero_of_the_village_icon.png", + type = "Advancement", + group = "Adventure", + secret = true, +}) + +awards.register_achievement("mcl:voluntary_exile", { + title = S("Voluntary Exile"), + description = S("Kill a raid captain. Maybe consider staying away from the local villages for the time being..."), + icon = "mcl_potions_effect_bad_omen.png", + type = "Advancement", + group = "Adventure", + secret = true, }) diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr index 49c486e48..885bf1d7e 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr @@ -47,3 +47,7 @@ Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Benutz Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Benutzen Sie eine Werkbank, um eine Holzspitzhacke aus Holzplanken und Stöcken zu fertigen. Use obsidian and a fire starter to construct a Nether portal.=Benutzen Sie Obsidian und ein Feuerzeug, um ein Netherportal zu errichten. Use wheat to craft a bread.=Benutzen Sie Weizen, um ein Brot zu machen. +Bring Home the Beacon=Den Nachbarn heimleuchten +Use a beacon.=Benutzen Sie ein Leuchtfeuer. +Beaconator=Leuchtturmwärter +Use a fully powered beacon.=Benutzen Sie ein vollständiges Leuchtfeuer. diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr index ae4941d2e..731d43490 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr @@ -19,7 +19,7 @@ Getting an Upgrade=Obtenir une augmentaton de niveau Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.=Frappez un squelette, wither squelette ou stray à l'arc et à la flèche à une distance d'au moins 20 mètres. Hot Topic=Sujet brûlant Into Fire=Dans le feu -Into the Nether=Dans le Nether +We Need to Go Deeper=Aller au fond des choses Iron Belly=Ventre de fer Librarian=Bibliothécaire Mine emerald ore.=Mine de minerai d'émeraude. @@ -47,3 +47,35 @@ Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Utilis Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Utilisez un établi pour fabriquer une pioche en bois à partir de planches et de bâtons en bois. Use obsidian and a fire starter to construct a Nether portal.=Utilisez de l'obsidienne et un briquet pour construire un portail du Nether. Use wheat to craft a bread.=Utilisez du blé pour fabriquer un pain. +Who is Cutting Onions?=Qui épluche des oignons ? +Pick up a crying obsidian from the floor.=Ramasser une obsidienne pleureuse sur le sol. +Hidden in the Depths=Caché dans les profondeurs +Pick up an Ancient Debris from the floor.=Ramasser un Ancien Débris par terre. +The Nether=Le Nether +Bring summer clothes.@nHint: Enter the Nether.=Apportez des vêtements d'été.@nAstuce : Entrez dans le Nether +Isn't It Iron Pick=Bonne Pioche ! +Craft a iron pickaxe using sticks and iron.=Fabriquer une pioche de fer avec des batons et du fer. +Postmortal=Aux frontières de la mort +Use a Totem of Undying to cheat death.=Utiliser un Totem d'imortalité pour tromper la mort. +Sweet Dreams=Bonne nuit les petits +Sleep in a bed to change your respawn point.=Dormez dans un lit pour changer votre point de réapparition. +Not Quite "Nine" Lives=Presque "neuf" vies +Charge a Respawn Anchor to the maximum.=Charger une Ancre de Réapparition au maximum. +What A Deal!=Adjugé, Vendu ! +Successfully trade with a Villager.=Commercez avec succès avec un villageois. +Withering Heights=Les Witherables +Summon the wither from the dead.=Invoquez le Wither d'entre les morts. +Fishy Business=Merci pour le poisson +Catch a fish.@nHint: Catch a fish, salmon, clownfish, or pufferfish.=Attrapez un poisson. \nAstuce : attrapez un poisson, saumon, poisson-clown, ou poisson-globe. +Country Lode,@nTake Me Home=Petit Poucet +Use a compass on a Lodestone.=utiliser une boussole sur une magnétite. +Serious Dedication=Sérieux dévouement +Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.=Utilisez un lingot de netherite pour améliorez une houe, puis réévaluez complètement vos choix de vie. +Local Brewery=Apprenti chimiste +Brew a Potion.@nHint: Take a potion or glass bottle out of the brewing stand.=Concotez une potion.@nAstuce : Retirez une potion ou bouteille d'eau d'un alambic. +Enchanter=Enchanté ! +Enchant an item using an Enchantment Table.=Enchanter un objet avec la table d'enchantement. +Bring Home the Beacon=Fais ta balise +Use a beacon.=Utilisez une balise. +Beaconator=Phare allumé +Use a fully powered beacon.=Utilisez une balise à pleine puissance. diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.ja.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.ja.tr new file mode 100644 index 000000000..592833cee --- /dev/null +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.ja.tr @@ -0,0 +1,99 @@ +# textdomain:mcl_achievements +Aquire Hardware=金属を入手 +Bake Bread=パンを焼く +Benchmarking=土台作り +Cow Tipper=牛転がし +Craft a bookshelf.=本棚を作ろう。 +Craft a cake using wheat, sugar, milk and an egg.=ケーキを焼こう。 材料:小麦、砂糖、ミルク、タマゴ +Craft a crafting table from 4 wooden planks.=作業台を作ろう。 材料:木材4つ +Craft a stone pickaxe using sticks and cobblestone.=石のツルハシを作ろう。 材料:木の棒、丸石 +Craft a wooden sword using wooden planks and sticks on a crafting table.=作業台で木製の剣を作ろう。 材料:木の棒、木材 +DIAMONDS!=ダイヤモンド! +Delicious Fish=美味しい魚 +Dispense With This=これを省く +Eat a cooked porkchop.=豚肉を焼いて食べよう。 +Eat a cooked rabbit.=ウサギを焼いて食べよう。 +Get really desperate and eat rotten flesh.=やけになって腐肉を喰らおう。 +Getting Wood=木を取得 +Getting an Upgrade=アップグレードを取得 +Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.=20m以上の距離から弓矢を当てよう。 対象:スケルトン、ウィザースケルトン、ストレイ等 +Hot Topic=ホット・トピック +Into Fire=炎の中へ +We Need to Go Deeper=より深く潜る必要がある +Iron Belly=鉄の胃袋 +Librarian=司書 +Mine emerald ore.=エメラルド鉱石を発掘しよう。 +On A Rail=レールの上で +Pick up a blaze rod from the floor.=床からブレイズロッドを拾おう。 +Pick up a diamond from the floor.=床からダイヤモンドを拾おう。 +Pick up a wood item from the ground.@nHint: Punch a tree trunk until it pops out as an item.=地面から木のアイテムを拾おう。@nヒント:アイテムとして飛び出すまで木の幹をパンチします。 +Pick up leather from the floor.@nHint: Cows and some other animals have a chance to drop leather, when killed.=床から革を拾おう。@nヒント:牛や一部の動物は、仕留めると革を落とすことがあります。 +Place a dispenser.=ディスペンサーを置こう。 +Place a flower pot.=植木鉢を置こう。 +Pork Chop=ポークチョップ +Pot Planter=鉢植え家 +Rabbit Season=ウサギの季節 +Sniper Duel=スナイパー対決 +Take a cooked fish from a furnace.@nHint: Use a fishing rod to catch a fish and cook it in a furnace.=かまどから焼き魚を取り出そう。@nヒント:釣り竿を使って魚を獲り、かまどに入れて調理します。 +Take an iron ingot from a furnace's output slot.@nHint: To smelt an iron ingot, put a fuel (like coal) and iron ore into a furnace.=かまどの出力スロットから鉄インゴットを取り出そう。@nヒント:鉄インゴットを製錬するには、かまどに(石炭などの)燃料と鉄の原石を入れます。 +The Haggler=商売人 +The Lie=絵に描いた○○○ +Time to Farm!=いざ農業! +Time to Mine!=いざ採掘! +Time to Strike!=いざ突撃! +Travel by minecart for at least 1000 meters from your starting point in a single ride.=一回のトロッコ乗車で、1000m以上を走り抜けよう。 +Use 8 cobblestones to craft a furnace.=8個の丸石を使って、かまどを作ろう。 +Use a crafting table to craft a wooden hoe from wooden planks and sticks.=作業台を使って、木製のクワを作ろう。 材料:木の棒、木材 +Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=作業台を使って、木製の斧を作ろう。 材料:木の棒、木材 +Use obsidian and a fire starter to construct a Nether portal.=黒曜石と火打ち石を使って、ネザーポータルを構築しよう。 +Use wheat to craft a bread.=小麦を使ってパンを作ろう。 +Who is Cutting Onions?=タマネギ切ってるの誰? +Pick up a crying obsidian from the floor.=床から泣く黒曜石を拾おう。 +Hidden in the Depths=未知なる深海 +Pick up an Ancient Debris from the floor.=床から古代の残骸を拾おう。 +The Nether=ネザー +Bring summer clothes.@nHint: Enter the Nether.=夏服を持っていこう。@nヒント:ネザーにのりこみます。 +Isn't It Iron Pick=鉄のツルハシで決まり +Craft a iron pickaxe using sticks and iron.=鉄のツルハシを作ろう。 材料:木の棒、丸石 +Postmortal=死後 +Use a Totem of Undying to cheat death.=不死のトーテムを使って、死を免れよう。 +Sweet Dreams=よい夢を +Sleep in a bed to change your respawn point.=ベッドで寝て、リスポーン地点を変えよう。 +Not Quite "Nine" Lives=九生とまではいかない +Charge a Respawn Anchor to the maximum.=リスポーンアンカーを最大までチャージしよう。 +What A Deal!=なんて良い取引だ! +Successfully trade with a Villager.=村人との交易を成功させよう。 +Withering Heights=ウィザーリング・ハイツ +Summon the wither from the dead.=死者からウィザーを召喚しよう。 +The Cutest Predator=いちばんカワイイ捕食者 +Catch an Axolotl with a bucket!=バケツでウーパールーパーを捕まえよう! +Fishy Business=フィッシー・ビジネス +Catch a fish.@nHint: Catch a fish, salmon, clownfish, or pufferfish.=魚を獲ろう。@nヒント:タラ、サケ、クマノミ、フグ等を釣ります。 +Country Lode,@nTake Me Home=この道ずっとゆけば@n鉱脈につづいてる +Use a compass on a Lodestone.=ロードストーンにコンパスを使おう。 +Serious Dedication=真摯な取り組み +Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.=ネザライトインゴットでクワをアップグレードしたら、人生設計の完全な見直しを図ろう。 +Local Brewery=地酒処 +Brew a Potion.@nHint: Take a potion or glass bottle out of the brewing stand.=ポーションを醸造しよう。@nヒント:醸造台からポーションかガラス瓶を取り出します。 +Enchanter=エンチャンター +Enchant an item using an Enchantment Table.=エンチャントテーブルを使って、アイテムを一つエンチャントしよう。 +Bring Home the Beacon=ブリング・ホーム・ザ・ビーコン +Use a beacon.=ビーコンを使おう。 +Beaconator=ビーコネーター +Use a fully powered beacon.=フルパワーのビーコンを作ろう。 +The Next Generation=ザ・ネクスト・ジェネレーション +Hold the Dragon Egg.@nHint: Pick up the egg from the ground and have it in your inventory.=ドラゴンの卵を所持しよう。@nヒント:地面から卵を拾って、インベントリにしまいます。 +The End... Again...=おしまい…再び… +Respawn the Ender Dragon.=エンダードラゴンを復活させよう。 +Sky's The Limit=空の境界 +Find the elytra and prepare to fly above and beyond!=エリトラを見つけ、空の彼方へ飛び立つ準備をしよう! +Free the End=エンドの解放 +Kill the ender dragon. Good Luck!=エンダードラゴンを討伐しよう。幸運を祈る! +Bee Our Guest=秘蜜の晩餐会 +Use a campfire to collect a bottle of honey from a beehive without aggrivating the bees inside.=焚き火を使って、ハチの巣の中のハチを怒らせることなく、瓶にハチミツを採ろう。 +Total Beelocation=綿蜜に引越し +Move a bee nest, with 3 bees inside, using a silk touch enchanted tool.=シルクタッチをエンチャントした道具を使って、中に3匹のハチがいるハチの巣を移動させよう。 +Wax On=錆止め +Apply honeycomb to a copper block to protect it from the elements.=銅ブロックにハニカムを塗り、風雨から保護しよう。 +Wax Off=錆止め落とし +Scrape wax off of a copper block.=銅ブロックから錆止めを削り落とそう。 diff --git a/mods/HUD/mcl_achievements/locale/template.txt b/mods/HUD/mcl_achievements/locale/template.txt index ecdba2672..f229b2152 100644 --- a/mods/HUD/mcl_achievements/locale/template.txt +++ b/mods/HUD/mcl_achievements/locale/template.txt @@ -19,7 +19,7 @@ Getting an Upgrade= Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.= Hot Topic= Into Fire= -Into the Nether= +We Need to Go Deeper= Iron Belly= Librarian= Mine emerald ore.= @@ -47,3 +47,53 @@ Use a crafting table to craft a wooden hoe from wooden planks and sticks.= Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.= Use obsidian and a fire starter to construct a Nether portal.= Use wheat to craft a bread.= +Who is Cutting Onions?= +Pick up a crying obsidian from the floor.= +Hidden in the Depths= +Pick up an Ancient Debris from the floor.= +The Nether= +Bring summer clothes.@nHint: Enter the Nether.= +Isn't It Iron Pick= +Craft a iron pickaxe using sticks and iron.= +Postmortal= +Use a Totem of Undying to cheat death.= +Sweet Dreams= +Sleep in a bed to change your respawn point.= +Not Quite "Nine" Lives= +Charge a Respawn Anchor to the maximum.= +What A Deal!= +Successfully trade with a Villager.= +Withering Heights= +Summon the wither from the dead.= +The Cutest Predator= +Catch an Axolotl with a bucket! +Fishy Business= +Catch a fish.@nHint: Catch a fish, salmon, clownfish, or pufferfish.= +Country Lode,@nTake Me Home= +Use a compass on a Lodestone.= +Serious Dedication= +Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.= +Local Brewery= +Brew a Potion.@nHint: Take a potion or glass bottle out of the brewing stand.= +Enchanter= +Enchant an item using an Enchantment Table.= +Bring Home the Beacon= +Use a beacon.= +Beaconator= +Use a fully powered beacon.= +The Next Generation= +Hold the Dragon Egg.@nHint: Pick up the egg from the ground and have it in your inventory.= +The End... Again...= +Respawn the Ender Dragon.= +Sky's The Limit= +Find the elytra and prepare to fly above and beyond!= +Free the End= +Kill the ender dragon. Good Luck!= +Bee Our Guest= +Use a campfire to collect a bottle of honey from a beehive without aggrivating the bees inside.= +Total Beelocation= +Move a bee nest, with 3 bees inside, using a silk touch enchanted tool.= +Wax On= +Apply honeycomb to a copper block to protect it from the elements.= +Wax Off= +Scrape wax off of a copper block.= diff --git a/mods/HUD/mcl_base_textures/textures/crack_anylength.png b/mods/HUD/mcl_base_textures/textures/crack_anylength.png index 7fe8721d9..07e5df8fd 100644 Binary files a/mods/HUD/mcl_base_textures/textures/crack_anylength.png and b/mods/HUD/mcl_base_textures/textures/crack_anylength.png differ diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua index 96b6b4896..1ff981456 100644 --- a/mods/HUD/mcl_bossbars/init.lua +++ b/mods/HUD/mcl_bossbars/init.lua @@ -13,13 +13,13 @@ function mcl_bossbars.recalculate_colors() local frame_count = color_count * 2 for i, color in ipairs(colors) do local idx = i * 2 - 1 - local image = "mcl_bossbars.png" + local image = "(mcl_bossbars.png" .. "^[transformR270" .. "^[verticalframe:" .. frame_count .. ":" .. (idx - 1) .. "^(mcl_bossbars_empty.png" .. "^[lowpart:%d:mcl_bossbars.png" .. "^[transformR270" - .. "^[verticalframe:" .. frame_count .. ":" .. idx .. ")" + .. "^[verticalframe:" .. frame_count .. ":" .. idx .. "))^[resize:1456x40" local _, hex = mcl_util.get_color(color) sorted[color] = { image = image, @@ -162,7 +162,7 @@ minetest.register_globalstep(function(dtime) position = {x = 0.5, y = 0}, alignment = {x = 0, y = 1}, offset = {x = 0, y = i * 40 + 25}, - scale = {x = 3, y = 3}, + scale = {x = 0.375, y = 0.375}, }), } end diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr b/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr new file mode 100644 index 000000000..e7bbbbfc2 --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models=3Dモデル +A faithful Open Source clone of Minecraft=オープンソースによるマインクラフトの忠実なクローン +Contributors=投稿者 +Creator of MineClone=MineClone の創始者 +Creator of MineClone2=MineClone2 の創始者 +Developers=開発者 +Jump to speed up (additionally sprint)=ジャンプでスピードアップ(追加で疾走) +Maintainers=メンテナンス +MineClone5=MineClone5 +Original Mod Authors=オリジナルMODの作者 +Sneak to skip=スニークでスキップ +Textures=テクスチャ +Translations=翻訳 diff --git a/mods/HUD/mcl_credits/people.lua b/mods/HUD/mcl_credits/people.lua index 4658393b6..9c4208ece 100644 --- a/mods/HUD/mcl_credits/people.lua +++ b/mods/HUD/mcl_credits/people.lua @@ -9,12 +9,13 @@ return { "Wuzzy", }}, {S("Maintainers"), 0xFF51D5, { + "AncientMariner", "Nicu", - "cora", }}, {S("Previous Maintainers"), 0xFFFFFF, { "Fleckenstein", "jordan4ibanez", + "cora", }}, {S("Developers"), 0xF84355, { "bzoss", @@ -28,6 +29,14 @@ return { "Code-Sploit", "NO11", "kabou", + "rudzik8", + "chmodsayshello", + "PrairieWind", + "RandomLegoBrick", + "SumianVoice", + "MrRar", + "talamh", + "Faerraven", }}, {S("Contributors"), 0x52FF00, { "Laurent Rocher", @@ -61,7 +70,6 @@ return { "Benjamin Schötz", "Doloment", "Sydney Gems", - "talamh", "Emily2255", "Emojigit", "FinishedFragment", @@ -72,6 +80,22 @@ return { "Sven792", "aldum", "Dieter44", + "Pepebotella", + "MrRar", + "Lazerbeak12345", + "mrminer", + "Thunder1035", + "opfromthestart", + "snowyu", + "FaceDeer", + "Faerraven / Michieal", + "FossFanatic", + "Herbert West", + "GuyLiner", + "3raven", + "anarquimico", + "TheOnlyJoeEnderman", + "Ranko Saotome", }}, {S("MineClone5"), 0xA60014, { "kay27", @@ -79,10 +103,12 @@ return { "epCode", "NO11", "j45", + "chmodsayshello", "3raven", - "PrarieWind", - "Gustavo1", + "PrairieWind", + "Gustavo6046 / wallabra", "CableGuy67", + "MrRar", }}, {S("Mineclonia"), 0xFFFFFF, { "erlehmann", @@ -120,6 +146,7 @@ return { "4Evergreen4", "jordan4ibanez", "paramat", + "cora", }}, {S("3D Models"), 0x0019FF, { "22i", @@ -135,6 +162,10 @@ return { "yutyo", "NO11", "kay27", + "MysticTempest", + "RandomLegoBrick", + "cora", + "Faerraven / Michieal", }}, {S("Translations"), 0x00FF60, { "Wuzzy", @@ -144,6 +175,10 @@ return { "pitchum", "todoporlalibertad", "Marcin Serwin", + "Pepebotella", + "Emojigit", + "snowyu", + "3raven", }}, {S("Funders"), 0xF7FF00, { "40W", @@ -151,6 +186,7 @@ return { {S("Special thanks"), 0x00E9FF, { "celeron55 for creating Minetest", "Jordach for the jukebox music compilation from Big Freaking Dig", + "wsor for working tirelessly in the shadows for the good of all of us, particularly helping with solving contentDB and copyright issues.", "The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game", "Notch and Jeb for being the major forces behind Minecraft", }}, diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index 91e13995b..13ed23668 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -149,6 +149,11 @@ mcl_death_messages = { plain = "@1 went off with a bang", item = "@1 went off with a bang due to a firework fired from @3 by @2", -- order is intentional }, + sweet_berry = { + _translator = S, + plain = "@1 died a sweet death", + assist = "@1 was poked to death by a sweet berry bush whilst trying to escape @2", + }, -- Missing snowballs: The Minecraft wiki mentions them but the MC source code does not. }, } diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr index 05cf99976..6bf704400 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr @@ -1,59 +1,55 @@ # textdomain: mcl_death_messages -@1 was fatally hit by an arrow.=@1 a été mortellement touché par une flèche. -@1 has been killed with an arrow.=@1 a été tué avec une flèche. -@1 was shot by an arrow from @2.=@1 a été abattu par une flèche de @2. -@1 was shot by an arrow from a skeleton.=@1 a été abattu par une flèche d'un squelette. -@1 was shot by an arrow from a stray.=@1 a été abattu par une flèche d'un vagabond. -@1 was shot by an arrow from an illusioner.=@1 a été abattu par une flèche d'un illusionniste. -@1 was shot by an arrow.=@1 a été abattu par une flèche. -@1 forgot to breathe.=@1 a oublié de respirer. -@1 drowned.=@1 s'est noyé. -@1 ran out of oxygen.=@1 a manqué d'oxygène. -@1 was killed by @2.=@1 a été tué par @2. -@1 was killed.=@1 a été tué. -@1 was killed by a mob.=@1 a été tué par un mob. -@1 was burned to death by a blaze's fireball.=@1 a été brûlé vif par la boule de feu d'un blaze. -@1 was killed by a fireball from a blaze.=@1 a été tué par une boule de feu lors d'un blaze. -@1 was burned by a fire charge.=@1 a été brûlé par un incendie. -A ghast scared @1 to death.=Un ghast a éffrayé @1 à mort. -@1 has been fireballed by a ghast.=@1 a été pétrifié par un ghast. -@1 fell from a high cliff.=@1 est tombé d'une haute falaise. -@1 took fatal fall damage.=@1 a succombé à un chute mortelle. -@1 fell victim to gravity.=@1 a été victime de la gravité. -@1 died.=@1 est mort. -@1 was killed by a zombie.=@1 a été tué par un zombie. -@1 was killed by a baby zombie.=@1 a été tué par un bébé zombie. -@1 was killed by a blaze.=@1 a été tué par un blaze. -@1 was killed by a slime.=@1 a été tué par un slime. -@1 was killed by a witch.=@1 a été tué par un sorcier. -@1 was killed by a magma cube.=@1 a été tué par un cube de magma. -@1 was killed by a wolf.=@1 a été tué par un loup. -@1 was killed by a cat.=@1 a été tué par un chat. -@1 was killed by an ocelot.=@1 a été tué par un ocelot. -@1 was killed by an ender dragon.=@1 a été tué par un ender dragon. -@1 was killed by a wither.=@1 a été tué par un wither. -@1 was killed by an enderman.=@1 a été tué par un enderman. -@1 was killed by an endermite.=@1 a été tué par un endermite. -@1 was killed by a ghast.=@1 a été tué par un ghast. -@1 was killed by an elder guardian.=@1 a été tué par un grand gardien. -@1 was killed by a guardian.=@1 a été tué par un gardien. -@1 was killed by an iron golem.=@1 a été tué par un golem de fer. -@1 was killed by a polar_bear.=@1 a été tué par un ours blanc. -@1 was killed by a killer bunny.=@1 a été tué par un lapin tueur. -@1 was killed by a shulker.=@1 a été tué par un shulker. -@1 was killed by a silverfish.=@1 a été tué par un poisson d'argent. -@1 was killed by a skeleton.=@1 a été tué par un squelette. -@1 was killed by a stray.=@1 a été tué par un vagabond. -@1 was killed by a slime.=@1 a été tué par un slime. -@1 was killed by a spider.=@1 a été tué par une araignée. -@1 was killed by a cave spider.=@1 a été tué par une araignée venimeuse. -@1 was killed by a vex.=@1 a été tué par un vex. -@1 was killed by an evoker.=@1 a été tué par un invocateur. -@1 was killed by an illusioner.=@1 a été tué par un illusionniste. -@1 was killed by a vindicator.=@1 a été tué par un vindicateur. -@1 was killed by a zombie villager.=@1 a été tué par un villageois zombie. -@1 was killed by a husk.=@1 a été tué par un zombie momie. -@1 was killed by a baby husk.=@1 a été tué par un bébé zombie momie. -@1 was killed by a zombie pigman.=@1 a été tué par un zombie-couchon. -@1 was killed by a baby zombie pigman.=@1 a été tué par un bébé zombie-couchon -@1 was slain by @2.= +@1 went up in flames=@1 est parti(e) en fumée +@1 walked into fire whilst fighting @2=@1 a marché dans le feu en combattant @2 +@1 was struck by lightning=@1 a été frappé(e) par la foudre +@1 was struck by lightning whilst fighting @2=@1 a été frappé(e) par la foudre en combattant @2 +@1 burned to death=@1 est mort(e) brûlé vif(ve) +@1 was burnt to a crisp whilst fighting @2=@1 a été grillé comme une saucisse en combattant @2 +@1 tried to swim in lava=@1 a essayé de nager dans la lave +@1 tried to swim in lava to escape @2=1 a essayé de nager dans la lave pour échapper à @2 +@1 discovered the floor was lava=@1 a découvert que le sol était en lave +@1 walked into danger zone due to @2=@1 a marché dans une zone de danger à cause de @2 +@1 suffocated in a wall=@1 a étouffé dans un mur +@1 suffocated in a wall whilst fighting @2=@1 a étouffé dans un mur en combattant @2 +@1 drowned=@1 s'est noyé(e) +@1 drowned whilst trying to escape @2=@1 s'est noyé(e) en tentant d'échapper à @2 +@1 starved to death=@1 est mort(e) de faim +@1 starved to death whilst fighting @2=@1 est mort(e) de faim en combattant @2 +@1 was pricked to death=@1 a été piqué(e) à mort +@1 walked into a cactus whilst trying to escape @2=@1 est rentré(e) dans un cactus en tentant d'échapper @2 +@1 hit the ground too hard=@1 a heurté le sol trop fort +@1 hit the ground too hard whilst trying to escape @2=@1 a heurté le sol trop fort en tentant d'échapper à @2 +@1 experienced kinetic energy=@1 a fait l'expérience de l'énergie cinétique +@1 experienced kinetic energy whilst trying to escape @2=@1 a fait l'expérience de l'énergie cinétique en tentant d'échapper à @2 +@1 fell out of the world=@1 est tombé(e) hors du monde +@1 didn't want to live in the same world as @2=@1 ne voulait pas vivre dans le même monde que @2 +@1 died=@1 est mort. +@1 died because of @2=@1 est mort à cause de @2 +@1 was killed by magic=@1 a été tué(e) par magie +@1 was killed by magic whilst trying to escape @2=@1 a été tué(e) par magie en tentant d'échapper à @2 +@1 was killed by @2 using magic=@1 a été tué(e) par @2 en utilisant la magie +@1 was killed by @2 using @3=@1 a été tué(e) par @2 en utilisant @3 +@1 was roasted in dragon breath=@1 a été rôti(e) dans le souffle du dragon +@1 was roasted in dragon breath by @2=@1 a été rôti(e) dans le souffle du dragon par @2 +@1 withered away=@1 s'est flétri(e) +@1 withered away whilst fighting @2=@1 s'est flétri(e) en combattant @2 +@1 was shot by a skull from @2=@1 a été abattu(e) par un crâne lancé par @2 +@1 was squashed by a falling anvil=@1 a été écrasé(e) par la chute d'une enclume +@1 was squashed by a falling anvil whilst fighting @2=@1 a été écrasé(e) par la chute d'une enclume en combattant @2 +@1 was squashed by a falling block=@1 a été écrasé(e) par la chute d'un bloc +@1 was squashed by a falling block whilst fighting @2=@1 a été écrasé(e) par la chute d'un bloc en combattant @2 +@1 was slain by @2=@1 a été occis par @2 +@1 was slain by @2 using @3=@1 a été occis par @2 en utilisant @3 +@1 was shot by @2=@1 a été abattu(e) par @2 +@1 was shot by @2 using @3=@1 a été abattu(e) par @2 en utilisant @3 +@1 was fireballed by @2=@1 a reçu une balle de feu lancée par @2 +@1 was fireballed by @2 using @3=@1 a reçu une balle de feu lancée par @2 en utilisant @3 +@1 was killed trying to hurt @2=@1 a été tué(e) en essayant de blesser @2 +@1 was killed by @3 trying to hurt @2=@1 a été tué(e) par @3 en essayant de blesser @2 +@1 blew up=@1 a explosé +@1 was blown up by @2=@2 a fait exploser @1 +@1 was blown up by @2 using @3=@2 a fait exploser @1 en utilisant @3 +@1 was squished too much=@1 a été pressé(e) un peu trop +@1 was squashed by @2=@1 a été écrasé(e) par @2 +@1 went off with a bang=@1 est parti(e) avec un bang +@1 went off with a bang due to a firework fired from @3 by @2=@1 est parti(e) avec un bang dû à un feu d'artifice tiré depuis @3 par @2 \ No newline at end of file diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ja.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ja.tr new file mode 100644 index 000000000..a725b261f --- /dev/null +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ja.tr @@ -0,0 +1,55 @@ +# textdomain: mcl_death_messages +@1 went up in flames=@1は炎上した +@1 walked into fire whilst fighting @2=@1は@2と戦いながら火中へ踏み入った +@1 was struck by lightning=@1は雷に打たれた +@1 was struck by lightning whilst fighting @2=@1は@2と戦いながら雷に打たれた +@1 burned to death=@1は焼死した +@1 was burnt to a crisp whilst fighting @2=@1は@2と戦いながらカリッと焼けた +@1 tried to swim in lava=@1は溶岩遊泳を試みた +@1 tried to swim in lava to escape @2=@1は@2から逃げるために溶岩遊泳を試みた +@1 discovered the floor was lava=@1は床が溶岩だったと気付いた +@1 walked into danger zone due to @2=@1は@2のせいで危険地帯に踏み入った +@1 suffocated in a wall=@1は壁の中で窒息死した +@1 suffocated in a wall whilst fighting @2=@1は@2と戦いながら壁の中で窒息死した +@1 drowned=@1は溺死した +@1 drowned whilst trying to escape @2=@1は@2から逃れようとして溺死した +@1 starved to death=@1は餓死した +@1 starved to death whilst fighting @2=@1は@2と戦いながら餓死した +@1 was pricked to death=@1は刺されて死んだ +@1 walked into a cactus whilst trying to escape @2=@1は@2から逃れようとしてサボテンに突っ込んだ +@1 hit the ground too hard=@1は地面に激突しすぎた +@1 hit the ground too hard whilst trying to escape @2=@1は@2から逃れようとして地面に激突しすぎた +@1 experienced kinetic energy=@1は運動エネルギーを体験した +@1 experienced kinetic energy whilst trying to escape @2=@1は@2から逃れようとして運動エネルギーを体験した +@1 fell out of the world=@1は奈落の底へ落ちた +@1 didn't want to live in the same world as @2=@1は@2と同じ世界に住みたくなかった +@1 died=@1は死んだ +@1 died because of @2=@1は@2のせいで死んだ +@1 was killed by magic=@1は魔法で殺された +@1 was killed by magic whilst trying to escape @2=@1は@2から逃れようとして魔法で殺された +@1 was killed by @2 using magic=@1は@2の使った魔法で殺された +@1 was killed by @2 using @3=@1は@2の使った@3で殺された +@1 was roasted in dragon breath=@1はドラゴンブレスで炙り焼きにされた +@1 was roasted in dragon breath by @2=@1は@2によりドラゴンブレスで炙り焼きにされた +@1 withered away=@1は干からびた +@1 withered away whilst fighting @2=@1は@2と戦いながら干からびた +@1 was shot by a skull from @2=@1は@2からの頭蓋骨に撃たれた +@1 was squashed by a falling anvil=@1は落下する金床でぺしゃんこにされた +@1 was squashed by a falling anvil whilst fighting @2=@1は@2と戦いながら落下する金床でぺしゃんこにされた +@1 was squashed by a falling block=@1は落下するブロックでぺしゃんこにされた +@1 was squashed by a falling block whilst fighting @2=@1は@2と戦いながら落下するブロックでぺしゃんこにされた +@1 was slain by @2=@1は@2に殺害された +@1 was slain by @2 using @3=@1は@2の使った@3で殺害された +@1 was shot by @2=@1は@2に撃たれた +@1 was shot by @2 using @3=@1は@2の使った@3で撃たれた +@1 was fireballed by @2=@1は@2によって火だるまにされた +@1 was fireballed by @2 using @3=@1は@2の使った@3によって火だるまにされた +@1 was killed trying to hurt @2=@1は@2を傷めつけようとして殺された +@1 was killed by @3 trying to hurt @2=@1は@2を傷めつけようとした@3に殺された +@1 blew up=@1は消し飛んだ +@1 was blown up by @2=@1は@2によって爆破された +@1 was blown up by @2 using @3=@1は@2の使った@3によって爆破された +@1 was squished too much=@1はペラッペラになった +@1 was squashed by @2=@1は@2に潰された +@1 went off with a bang=@1は爆散した +@1 went off with a bang due to a firework fired from @3 by @2=@1は@2が@3から発射した花火により爆散した diff --git a/mods/HUD/mcl_death_messages/locale/template.txt b/mods/HUD/mcl_death_messages/locale/template.txt index 67ba9fd1c..711dfb89b 100644 --- a/mods/HUD/mcl_death_messages/locale/template.txt +++ b/mods/HUD/mcl_death_messages/locale/template.txt @@ -33,7 +33,6 @@ @1 was roasted in dragon breath by @2= @1 withered away= @1 withered away whilst fighting @2= -@1 was killed by magic= @1 was shot by a skull from @2= @1 was squashed by a falling anvil= @1 was squashed by a falling anvil whilst fighting @2= @@ -41,8 +40,6 @@ @1 was squashed by a falling block whilst fighting @2= @1 was slain by @2= @1 was slain by @2 using @3= -@1 was slain by @2= -@1 was slain by @2 using @3= @1 was shot by @2= @1 was shot by @2 using @3= @1 was fireballed by @2= diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index 37250ee2f..359e68918 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -136,7 +136,7 @@ end function mcl_experience.throw_xp(pos, total_xp) local i, j = 0, 0 - + local obs = {} while i < total_xp and j < 100 do local xp = math.min(math.random(1, math.min(32767, total_xp - math.floor(i / 2))), total_xp - i) local obj = minetest.add_entity(pos, "mcl_experience:orb", tostring(xp)) @@ -153,7 +153,9 @@ function mcl_experience.throw_xp(pos, total_xp) i = i + xp j = j + 1 + table.insert(obs,obj) end + return obs end function mcl_experience.remove_hud(player) @@ -179,7 +181,7 @@ function mcl_experience.setup_hud(player) 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}, + scale = {x = 0.35, y = 0.375}, alignment = {x = 1, y = 1}, z_index = 11, }) @@ -204,9 +206,10 @@ function mcl_experience.update(player) if not hud_bars[player] then mcl_experience.setup_hud(player) end - player:hud_change(hud_bars[player], "text", "mcl_experience_bar_background.png^[lowpart:" + + 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" + .. ":mcl_experience_bar.png)^[resize:40x1456^[transformR270" ) if cache.level == 0 then diff --git a/mods/HUD/mcl_experience/locale/mcl_experience.ja.tr b/mods/HUD/mcl_experience/locale/mcl_experience.ja.tr new file mode 100644 index 000000000..07e4234d1 --- /dev/null +++ b/mods/HUD/mcl_experience/locale/mcl_experience.ja.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_experience +[[] ]=[[<プレイヤー>] ] +Gives a player some XP=プレイヤーにXPを付与 +Error: Too many parameters!=エラー:パラメータ過多! +Error: Incorrect value of XP=エラー:XPの値が不適切 +Error: Player not found=エラー:プレイヤー未検出 +Added @1 XP to @2, total: @3, experience level: @4=@2に @1 XPを追加、合計:@3、 XPレベル:@4 diff --git a/mods/HUD/mcl_hbarmor/locale/hbarmor.ja.tr b/mods/HUD/mcl_hbarmor/locale/hbarmor.ja.tr new file mode 100644 index 000000000..2d32381ae --- /dev/null +++ b/mods/HUD/mcl_hbarmor/locale/hbarmor.ja.tr @@ -0,0 +1,2 @@ +# textdomain:hbarmor +Armor=防具 diff --git a/mods/HUD/mcl_info/API.md b/mods/HUD/mcl_info/API.md new file mode 100644 index 000000000..18c901162 --- /dev/null +++ b/mods/HUD/mcl_info/API.md @@ -0,0 +1,18 @@ +## mcl_info +An api to make custom entries in the mcl2 debug hud. + +### mcl_info.register_debug_field(name,defintion) +Debug field defintion example: +{ + level = 3, + --show with debug level 3 and upwards + + func = function(player,pos) return minetest.pos_to_string(pos) end, + -- Function that is run for at each debug + -- sample (default: every .63 seconds) + -- It should output a string and determines + -- the content of the debug field. +} + +### mcl_info.registered_debug_fields +Table the debug definitions are stored in. Do not modify this directly. If you need to overwrite a field just set it again with mcl_info.register_debug_field(). diff --git a/mods/HUD/mcl_info/init.lua b/mods/HUD/mcl_info/init.lua new file mode 100644 index 000000000..b6f69255c --- /dev/null +++ b/mods/HUD/mcl_info/init.lua @@ -0,0 +1,204 @@ +mcl_info = {} +local format, pairs,ipairs,table,vector,minetest,mcl_info,tonumber,tostring = string.format,pairs,ipairs,table,vector,minetest,mcl_info,tonumber,tostring + +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local storage = minetest.get_mod_storage() +local player_dbg = {} + +local refresh_interval = .63 +local huds = {} +local default_debug = 0 + +local function check_setting(s) + return s +end + +--return player setting, set it to 2nd argument if supplied +local function player_setting(p,s) + local name = p:get_player_name() + if check_setting(s) then + p:get_meta():set_string("mcl_info_show",s) + player_dbg[name] = tonumber(s) + end + if not player_dbg[name] then + local r = p:get_meta():get_string("mcl_info_show") + if r == nil or r == "" then r = 0 end + player_dbg[name] = tonumber(r) + end + return player_dbg[name] +end + +mcl_info.registered_debug_fields = {} +local fields_keyset = {} +function mcl_info.register_debug_field(name,def) + table.insert(fields_keyset,name) + mcl_info.registered_debug_fields[name]=def +end + +local function nodeinfo(pos) + local n = minetest.get_node_or_nil(pos) + if not n then return "" end + local l = minetest.get_node_light(pos) + local ld = minetest.get_node_light(pos,0.5) + local r = n.name .. " p1:"..n.param1.." p2:"..n.param2 + if l and ld then + r = r .. " Light: "..l.."/"..ld + end + return r +end + +local function get_text(player, bits) + local pos = vector.offset(player:get_pos(),0,0.5,0) + local bits = bits + if bits == -1 then return "" end + + local r = "" + for _,key in ipairs(fields_keyset) do + local def = mcl_info.registered_debug_fields[key] + if def then + if def.level == nil or def.level <= bits then + r = r ..key..": "..tostring(def.func(player,pos)).."\n" + end + else + r = r ..key..": \n" + end + end + return r +end + +local function info() + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local s = player_setting(player) + local pos = player:get_pos() + local text = get_text(player, s) + local hud = huds[name] + if s and not hud then + local def = { + hud_elem_type = "text", + alignment = {x = 1, y = -1}, + scale = {x = 100, y = 100}, + position = {x = 0.0073, y = 0.889}, + text = text, + style = 5, + ["number"] = 0xcccac0, + z_index = 0, + } + local def_bg = table.copy(def) + def_bg.offset = {x = 2, y = 1} + def_bg["number"] = 0 + def_bg.z_index = -1 + huds[name] = { + player:hud_add(def), + player:hud_add(def_bg), + text, + } + elseif text ~= hud[3] then + hud[3] = text + player:hud_change(huds[name][1], "text", text) + player:hud_change(huds[name][2], "text", text) + end + end + minetest.after(refresh_interval, info) +end +minetest.after(0,info) + +minetest.register_on_leaveplayer(function(p) + local name = p:get_player_name() + huds[name] = nil + player_dbg[name] = nil +end) + +minetest.register_chatcommand("debug",{ + description = S("Set debug bit mask: 0 = disable, 1 = player coords, 2 = coordinates, 3 = biome name, 4 = all"), + params = S(""), + privs = { debug = true }, + func = function(name, params) + local player = minetest.get_player_by_name(name) + if params == "" then return true, "Debug bitmask is "..player_setting(player) end + local dbg = math.floor(tonumber(params) or default_debug) + if dbg < -1 or dbg > 4 then + minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", -1, 4)) + return false,"Current bitmask: "..player_setting(player) + end + return true, "Debug bit mask set to "..player_setting(player,dbg) + end +}) + +-- register normal user access to debug levels 1 and 0. +minetest.register_chatcommand("whereami", { + description = S("Set location bit mask: 0 = disable, 1 = coordinates"), + params = S(""), + -- privs = { }, + func = function(name, params) + local player = minetest.get_player_by_name(name) + if params == "" then + return true, "Location bitmask is " .. player_setting(player) + end + local loc_lev = math.floor(tonumber(params) or default_debug) + if loc_lev < 0 or loc_lev > 4 then + minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", 0, 1)) + return false, "Current bitmask: " .. player_setting(player) + end + return true, "Location bit mask set to " .. player_setting(player, loc_lev) + end +}) + +mcl_info.register_debug_field("Node feet",{ + level = 4, + func = function(pl,pos) + return nodeinfo(pos) + end +}) +mcl_info.register_debug_field("Node below",{ + level = 4, + func = function(pl,pos) + return nodeinfo(vector.offset(pos,0,-1,0)) + end +}) +mcl_info.register_debug_field("Biome",{ + level = 3, + func = function(pl,pos) + local biome_data = minetest.get_biome_data(pos) + local biome = biome_data and minetest.get_biome_name(biome_data.biome) or "No biome" + if biome_data then + return format("%s (%s), Humidity: %.1f, Temperature: %.1f",biome, biome_data.biome, biome_data.humidity, biome_data.heat) + end + return "No biome" + end +}) + +mcl_info.register_debug_field("Coords", { + level = 2, + func = function(pl, pos) + return format("x:%.1f y:%.1f z:%.1f", pos.x, pos.y, pos.z) + end +}) + +mcl_info.register_debug_field("Location", { + level = 1, + func = function(pl, pos) + local report_y = 0 + -- overworld + if (pos.y >= mcl_vars.mg_overworld_min) and (pos.y <= mcl_vars.mg_overworld_max) then + return format("Overworld: x:%.1f y:%.1f z:%.1f", pos.x, pos.y, pos.z) + end + + -- nether + if (pos.y >= mcl_vars.mg_nether_min) and (pos.y <= mcl_vars.mg_nether_max) then + report_y = pos.y - mcl_vars.mg_nether_min + return format("Nether: x:%.1f y:%.1f z:%.1f", pos.x, report_y, pos.z) + end + + -- end + if (pos.y >= mcl_vars.mg_end_min) and (pos.y <= mcl_vars.mg_end_max) then + report_y = pos.y - mcl_vars.mg_end_min + return format("End: x:%.1f y:%.1f z:%.1f", pos.x, report_y, pos.z) + end + + -- outside of scoped bounds. + return format("Void: x:%.1f y:%.1f z:%.1f", pos.x, pos.y, pos.z) + + end +}) diff --git a/mods/HUD/mcl_info/locale/mcl_info.fr.tr b/mods/HUD/mcl_info/locale/mcl_info.fr.tr new file mode 100644 index 000000000..96fb2622e --- /dev/null +++ b/mods/HUD/mcl_info/locale/mcl_info.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Régler le masque de bits pour débuguer : 0 @= pour désactiver, 1 @= nom du biome, 2 @= coordonnées, 3 @= tout= +Error! Possible values are integer numbers from @1 to @2=Erreur ! Les valeurs possibles sont des nombres entiers de @1 à @2 +Debug bit mask set to @1=Masque de bits de débuguage réglé à @1 diff --git a/mods/HUD/mcl_info/locale/mcl_info.ja.tr b/mods/HUD/mcl_info/locale/mcl_info.ja.tr new file mode 100644 index 000000000..3b2f3966b --- /dev/null +++ b/mods/HUD/mcl_info/locale/mcl_info.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=デバッグビットマスク設定:0 @= 無効, 1 @= バイオーム名, 2 @= 座標, 3 @= 全て +Error! Possible values are integer numbers from @1 to @2=エラー! 指定できる値は@1〜@2の整数値です。 +Debug bit mask set to @1=デバッグビットマスクを@1に設定 diff --git a/mods/HUD/mcl_info/locale/mcl_info.ru.tr b/mods/HUD/mcl_info/locale/mcl_info.ru.tr new file mode 100644 index 000000000..7f5b79fe1 --- /dev/null +++ b/mods/HUD/mcl_info/locale/mcl_info.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Установка отладочной битовой маски: 0 @= отключить, 1 @= биом, 2 @= координаты, 3 @= всё +Error! Possible values are integer numbers from @1 to @2=Ошибка! Допустимые значения - целые числа от @1 до @2 +Debug bit mask set to @1=Отладочной битовой маске присвоено значение @1 diff --git a/mods/HUD/mcl_info/locale/template.txt b/mods/HUD/mcl_info/locale/template.txt new file mode 100644 index 000000000..1a0b70ebc --- /dev/null +++ b/mods/HUD/mcl_info/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all= +Error! Possible values are integer numbers from @1 to @2= +Debug bit mask set to @1= diff --git a/mods/HUD/mcl_info/mod.conf b/mods/HUD/mcl_info/mod.conf new file mode 100644 index 000000000..41fdfb0b5 --- /dev/null +++ b/mods/HUD/mcl_info/mod.conf @@ -0,0 +1,3 @@ +name = mcl_info +description = Prints biome name and player position +depends = mcl_init diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 4c2faaef6..a9a1d6dd9 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -117,7 +117,7 @@ local function filter_item(name, description, lang, filter) else desc = string.lower(minetest.get_translated_string(lang, description)) end - return string.find(name, filter) or string.find(desc, filter) + return string.find(name, filter, nil, true) or string.find(desc, filter, nil, true) end local function set_inv_search(filter, player) @@ -362,39 +362,49 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size, local stack_size = get_stack_size(player) -- Survival inventory slots - main_list = "list[current_player;main;0,3.75;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,3.75,9,3).. - -- armor - "list[current_player;armor;2.5,1.3;1,1;1]".. - "list[current_player;armor;2.5,2.75;1,1;2]".. - "list[current_player;armor;5.5,1.3;1,1;3]".. - "list[current_player;armor;5.5,2.75;1,1;4]".. - mcl_formspec.get_itemslot_bg(2.5,1.3,1,1).. - mcl_formspec.get_itemslot_bg(2.5,2.75,1,1).. - mcl_formspec.get_itemslot_bg(5.5,1.3,1,1).. - mcl_formspec.get_itemslot_bg(5.5,2.75,1,1).. - "list[current_player;offhand;1.5,2.025;1,1]".. - mcl_formspec.get_itemslot_bg(1.5,2.025,1,1).. - armor_slot_imgs.. - -- player preview - mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "").. - -- crafting guide button - "image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]".. - "tooltip[__mcl_craftguide;"..F(S("Recipe book")).."]".. - -- help button - "image_button[9,2;1,1;doc_button_icon_lores.png;__mcl_doc;]".. - "tooltip[__mcl_doc;"..F(S("Help")).."]".. - -- 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")).."]" + main_list = "list[current_player;main;0,3.75;9,3;9]" .. + mcl_formspec.get_itemslot_bg(0, 3.75, 9, 3) .. + + -- Armor + "list[current_player;armor;2.5,1.3;1,1;1]" .. + "list[current_player;armor;2.5,2.75;1,1;2]" .. + "list[current_player;armor;5.5,1.3;1,1;3]" .. + "list[current_player;armor;5.5,2.75;1,1;4]" .. + mcl_formspec.get_itemslot_bg(2.5, 1.3, 1, 1) .. + mcl_formspec.get_itemslot_bg(2.5, 2.75, 1, 1) .. + mcl_formspec.get_itemslot_bg(5.5, 1.3, 1, 1) .. + mcl_formspec.get_itemslot_bg(5.5, 2.75, 1, 1) .. + "list[current_player;offhand;1.5,2.025;1,1]" .. + mcl_formspec.get_itemslot_bg(1.5, 2.025, 1, 1) .. + armor_slot_imgs .. + + -- Player preview + mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") .. + + -- Crafting guide button + "image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]" .. + "tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" .. + + -- Help button + "image_button[9,2;1,1;doc_button_icon_lores.png;__mcl_doc;]" .. + "tooltip[__mcl_doc;" .. F(S("Help")) .. "]" .. + + -- Achievements button + "image_button[9,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" .. + --"style_type[image_button;border=;bgimg=;bgimg_pressed=]" .. + "tooltip[__mcl_achievements;"..F(S("Advancements")) .. "]" .. + + -- Switch stack size button + "image_button[9,4;1,1;default_apple.png;__switch_stack;]" .. + "label[9.4,4.4;" .. F(C("#FFFFFF", stack_size ~= 1 and stack_size or "")) .. "]" .. + "tooltip[__switch_stack;" .. F(S("Switch stack size")) .. "]" + + -- Skins button + if minetest.global_exists("mcl_skins") then + main_list = main_list .. + "image_button[9,5;1,1;mcl_skins_button.png;__mcl_skins;]" .. + "tooltip[__mcl_skins;"..F(S("Select player skin")) .. "]" + end -- For shortcuts listrings = listrings .. @@ -689,6 +699,7 @@ minetest.register_on_joinplayer(function(player) players[name].start_i = 0 end init(player) + -- Setup initial creative inventory to the "nix" page. mcl_inventory.set_creative_formspec(player, 0, 1, nil, false, "nix", "") end) diff --git a/mods/HUD/mcl_inventory/init.lua b/mods/HUD/mcl_inventory/init.lua index 1a73e59df..9f54511a0 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -72,50 +72,62 @@ local function set_inventory(player, armor_change_only) armor_slot_imgs = armor_slot_imgs .. "image[3,2;1,1;mcl_inventory_empty_armor_slot_shield.png]" end - local form = "size[9,8.75]".. - "background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]".. - mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "").. - --armor - "list[current_player;armor;0,0;1,1;1]".. - "list[current_player;armor;0,1;1,1;2]".. - "list[current_player;armor;0,2;1,1;3]".. - "list[current_player;armor;0,3;1,1;4]".. - mcl_formspec.get_itemslot_bg(0,0,1,1).. - mcl_formspec.get_itemslot_bg(0,1,1,1).. - mcl_formspec.get_itemslot_bg(0,2,1,1).. - mcl_formspec.get_itemslot_bg(0,3,1,1).. - "list[current_player;offhand;3,2;1,1]".. - mcl_formspec.get_itemslot_bg(3,2,1,1).. - armor_slot_imgs.. - -- craft and inventory - "label[0,4;"..F(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - "list[current_player;main;0,7.74;9,1;]".. - "label[4,0.5;"..F(minetest.colorize("#313131", S("Crafting"))).."]".. - "list[current_player;craft;4,1;2,2]".. - "list[current_player;craftpreview;7,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - mcl_formspec.get_itemslot_bg(4,1,2,2).. - mcl_formspec.get_itemslot_bg(7,1.5,1,1).. - -- crafting guide button - "image_button[4.5,3;1,1;craftguide_book.png;__mcl_craftguide;]".. - "tooltip[__mcl_craftguide;"..F(S("Recipe book")).."]".. - -- help button - "image_button[8,3;1,1;doc_button_icon_lores.png;__mcl_doc;]".. - "tooltip[__mcl_doc;"..F(S("Help")).."]".. - -- skins button - "image_button[3,3;1,1;mcl_skins_button.png;__mcl_skins;]".. - "tooltip[__mcl_skins;"..F(S("Select player skin")).."]".. - -- achievements button - "image_button[7,3;1,1;mcl_achievements_button.png;__mcl_achievements;]".. - "tooltip[__mcl_achievements;"..F(S("Achievements")).."]".. - -- for shortcuts - "listring[current_player;main]".. - "listring[current_player;armor]".. - "listring[current_player;main]" .. - "listring[current_player;craft]" .. - "listring[current_player;main]" + local form = "size[9,8.75]" .. + "background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]" .. + mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "") .. + + -- Armor + "list[current_player;armor;0,0;1,1;1]" .. + "list[current_player;armor;0,1;1,1;2]" .. + "list[current_player;armor;0,2;1,1;3]" .. + "list[current_player;armor;0,3;1,1;4]" .. + mcl_formspec.get_itemslot_bg(0,0,1,1) .. + mcl_formspec.get_itemslot_bg(0,1,1,1) .. + mcl_formspec.get_itemslot_bg(0,2,1,1) .. + mcl_formspec.get_itemslot_bg(0,3,1,1) .. + "list[current_player;offhand;3,2;1,1]" .. + mcl_formspec.get_itemslot_bg(3,2,1,1) .. + armor_slot_imgs .. + + -- Craft and inventory + "label[0,4;"..F(minetest.colorize("#313131", S("Inventory"))) .. "]" .. + "list[current_player;main;0,4.5;9,3;9]" .. + "list[current_player;main;0,7.74;9,1;]" .. + "label[4,0.5;"..F(minetest.colorize("#313131", S("Crafting"))) .. "]" .. + "list[current_player;craft;4,1;2,2]" .. + "list[current_player;craftpreview;7,1.5;1,1;]" .. + mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3) .. + mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) .. + mcl_formspec.get_itemslot_bg(4, 1,2, 2) .. + mcl_formspec.get_itemslot_bg(7, 1.5, 1, 1) .. + + -- Crafting guide button + "image_button[4.5,3;1,1;craftguide_book.png;__mcl_craftguide;]" .. + "tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" .. + + -- Help button + "image_button[8,3;1,1;doc_button_icon_lores.png;__mcl_doc;]" .. + "tooltip[__mcl_doc;" .. F(S("Help")) .. "]" + + -- Skins button + if minetest.global_exists("mcl_skins") then + form = form .. + "image_button[3,3;1,1;mcl_skins_button.png;__mcl_skins;]" .. + "tooltip[__mcl_skins;" .. F(S("Select player skin")) .. "]" + end + + form = form .. + -- Achievements button + "image_button[7,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" .. + "tooltip[__mcl_achievements;" .. F(S("Advancements")) .. "]" .. + + -- For shortcuts + "listring[current_player;main]" .. + "listring[current_player;armor]" .. + "listring[current_player;main]" .. + "listring[current_player;craft]" .. + "listring[current_player;main]" + player:set_inventory_formspec(form) end @@ -157,12 +169,6 @@ minetest.register_on_joinplayer(function(player) player:hud_set_hotbar_image("mcl_inventory_hotbar.png") player:hud_set_hotbar_selected_image("mcl_inventory_hotbar_selected.png") - local old_update_player = mcl_armor.update_player - function mcl_armor.update_player(player, info) - old_update_player(player, info) - set_inventory(player, true) - end - -- In Creative Mode, the initial inventory setup is handled in creative.lua if not minetest.is_creative_enabled(player:get_player_name()) then set_inventory(player) @@ -177,13 +183,15 @@ minetest.register_on_joinplayer(function(player) return_fields(player, "enchanting_lapis") end) - dofile(minetest.get_modpath(minetest.get_current_modname()).."/creative.lua") +mcl_player.register_on_visual_change(mcl_inventory.update_inventory_formspec) + local mt_is_creative_enabled = minetest.is_creative_enabled function minetest.is_creative_enabled(name) if mt_is_creative_enabled(name) then return true end + if not name then return false end local p = minetest.get_player_by_name(name) if p then return p:get_meta():get_string("gamemode") == "creative" @@ -191,6 +199,24 @@ function minetest.is_creative_enabled(name) return false end +--Insta "digging" nodes in gamemode-creative +minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing) + if not puncher or not puncher:is_player() then return end + local name = puncher:get_player_name() + if not minetest.is_creative_enabled(name) then return end + if pointed_thing.type ~= "node" then return end + local def = minetest.registered_nodes[node.name] + if def then + minetest.node_dig(pos,node,puncher) + return true + end +end) + +--Don't subtract from inv when placing in gamemode-creative +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing) + if placer and placer:is_player() and minetest.is_creative_enabled(placer:get_player_name()) then return true end +end) + local function in_table(n,h) for k,v in pairs(h) do if v == n then return true end @@ -221,10 +247,13 @@ minetest.register_chatcommand("gamemode",{ privs = { server = true }, func = function(n,param) -- Full input validation ( just for @erlehmann <3 ) - local p = minetest.get_player_by_name(n) + local p local args = param:split(" ") if args[2] ~= nil then p = minetest.get_player_by_name(args[2]) + n = args[2] + else + p = minetest.get_player_by_name(n) end if not p then return false, S("Player not online") @@ -234,6 +263,7 @@ minetest.register_chatcommand("gamemode",{ elseif args[1] ~= nil then mcl_inventory.player_set_gamemode(p,args[1]) end + --Result message - show effective game mode local gm = p:get_meta():get_string("gamemode") if gm == "" then gm = gamemodes[1] end diff --git a/mods/HUD/mcl_inventory/locale/mcl_inventory.ja.tr b/mods/HUD/mcl_inventory/locale/mcl_inventory.ja.tr new file mode 100644 index 000000000..77c8fe686 --- /dev/null +++ b/mods/HUD/mcl_inventory/locale/mcl_inventory.ja.tr @@ -0,0 +1,21 @@ +# textdomain: mcl_inventory +Recipe book=レシピ本 +Help=ヘルプ +Select player skin=プレイヤースキン選択 +Advancements=進捗 +Building Blocks=建築ブロック +Decoration Blocks=装飾ブロック +Redstone=レッドストーン +Transportation=運送 +Brewing=醸造 +Miscellaneous=その他 +Search Items=アイテム検索 +Foodstuffs=食物 +Tools=道具 +Combat=戦闘 +Mobs=Mob +Materials=素材 +Survival Inventory=サバイバル インベントリ +Crafting=クラフト +Inventory=インベントリ +@1/@2=@1/@2 diff --git a/mods/HUD/mcl_inventory/locale/template.txt b/mods/HUD/mcl_inventory/locale/template.txt index 7f1c9769d..fcbe68580 100644 --- a/mods/HUD/mcl_inventory/locale/template.txt +++ b/mods/HUD/mcl_inventory/locale/template.txt @@ -2,7 +2,7 @@ Recipe book= Help= Select player skin= -Achievements= +Advancements= Building Blocks= Decoration Blocks= Redstone= diff --git a/mods/HUD/mcl_inventory/mod.conf b/mods/HUD/mcl_inventory/mod.conf index 10e669265..e42213d4f 100644 --- a/mods/HUD/mcl_inventory/mod.conf +++ b/mods/HUD/mcl_inventory/mod.conf @@ -1,5 +1,5 @@ name = mcl_inventory author = BlockMen description = Adds the player inventory and creative inventory. -depends = mcl_init, mcl_formspec, mcl_enchanting -optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide, mcl_player +depends = mcl_init, mcl_formspec, mcl_enchanting, mcl_player +optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide diff --git a/mods/HUD/mcl_offhand/init.lua b/mods/HUD/mcl_offhand/init.lua index b0fc223ec..98954b4f5 100644 --- a/mods/HUD/mcl_offhand/init.lua +++ b/mods/HUD/mcl_offhand/init.lua @@ -59,8 +59,9 @@ minetest.register_globalstep(function(dtime) 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 item = minetest.registered_items[offhand_item] + if offhand_item ~= "" and item then + local item_texture = item.inventory_image .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px local position = {x = 0.5, y = 1} local offset = {x = -320, y = -32} @@ -69,8 +70,8 @@ minetest.register_globalstep(function(dtime) hud_elem_type = "image", position = position, offset = offset, - scale = {x = 2.75, y = 2.75}, - text = "mcl_offhand_slot.png", + scale = {x = 0.46875, y = 0.46875}, + text = "mcl_offhand_slot.png" .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px, z_index = 0, }) end @@ -79,7 +80,7 @@ minetest.register_globalstep(function(dtime) hud_elem_type = "image", position = position, offset = offset, - scale = {x = 0.4, y = 0.4}, + scale = {x = 0.375, y = 0.375}, text = item_texture, z_index = 1, }) diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua index 2ea1571c8..2e8397fc1 100644 --- a/mods/HUD/mcl_title/init.lua +++ b/mods/HUD/mcl_title/init.lua @@ -11,8 +11,10 @@ --Note that the table storing timeouts use playername as index insteed of player objects (faster) --This is intended in order to speedup the process of removing HUD elements the the timeout is up +---@type table> local huds_idx = {} +---@type table> local hud_hide_timeouts = {} hud_hide_timeouts.title = {} @@ -24,17 +26,19 @@ huds_idx.subtitle = {} huds_idx.actionbar = {} mcl_title = {} -mcl_title.defaults = {fadein = 10, stay = 70, fadeout = 20} +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} +mcl_title.layout.title = { position = { x = 0.5, y = 0.5 }, alignment = { x = 0, y = -1.3 }, size = 7 } +mcl_title.layout.subtitle = { position = { x = 0.5, y = 0.5 }, alignment = { x = 0, y = 1.7 }, size = 4 } +mcl_title.layout.actionbar = { position = { x = 0.5, y = 1 }, alignment = { x = 0, y = 0 }, size = 1 } local get_color = mcl_util.get_color --local string = string local pairs = pairs +---@param gametick integer +---@return number? local function gametick_to_secondes(gametick) if gametick then return gametick / 20 @@ -44,7 +48,10 @@ local function gametick_to_secondes(gametick) end --https://github.com/minetest/minetest/blob/b3b075ea02034306256b486dd45410aa765f035a/doc/lua_api.txt#L8477 ---[[ + +---@param bold? boolean +---@param italic? boolean +---@return integer local function style_to_bits(bold, italic) if bold then if italic then @@ -60,9 +67,11 @@ local function style_to_bits(bold, italic) end end end -]] ---PARAMS SYSTEM +local no_style = style_to_bits(false, false) + +---PARAMS SYSTEM +---@type table local player_params = {} minetest.register_on_joinplayer(function(player) @@ -75,34 +84,34 @@ minetest.register_on_joinplayer(function(player) 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, + position = mcl_title.layout.title.position, + alignment = mcl_title.layout.title.alignment, + text = "", + style = no_style, + size = { x = mcl_title.layout.title.size }, + number = hex_color, + z_index = 100, }) huds_idx.subtitle[player] = player:hud_add({ hud_elem_type = "text", - position = mcl_title.layout.subtitle.position, - alignment = mcl_title.layout.subtitle.alignment, - text = "", - --style = 0, - size = {x = mcl_title.layout.subtitle.size}, - number = hex_color, - z_index = 100, + position = mcl_title.layout.subtitle.position, + alignment = mcl_title.layout.subtitle.alignment, + text = "", + style = no_style, + size = { x = mcl_title.layout.subtitle.size }, + number = hex_color, + z_index = 100, }) huds_idx.actionbar[player] = player:hud_add({ hud_elem_type = "text", - position = mcl_title.layout.actionbar.position, - offset = {x = 0, y = -210}, - alignment = mcl_title.layout.actionbar.alignment, - --style = 0, - text = "", - size = {x = mcl_title.layout.actionbar.size}, - number = hex_color, - z_index = 100, + position = mcl_title.layout.actionbar.position, + offset = { x = 0, y = -210 }, + alignment = mcl_title.layout.actionbar.alignment, + style = no_style, + text = "", + size = { x = mcl_title.layout.actionbar.size }, + number = hex_color, + z_index = 100, }) end) @@ -123,6 +132,8 @@ minetest.register_on_leaveplayer(function(player) hud_hide_timeouts.actionbar[playername] = nil end) +---@param player ObjectRef +---@param data {stay: integer} function mcl_title.params_set(player, data) player_params[player] = { stay = data.stay or mcl_title.defaults.stay, @@ -131,12 +142,18 @@ function mcl_title.params_set(player, data) } end +---@param player ObjectRef +---@return {stay: integer} function mcl_title.params_get(player) return player_params[player] end --API FUNCTIONS +---@param player ObjectRef +---@param type '"title"'|'"subtitle"'|'"actionbar"' +---@param data {text: string, color: string, stay: integer, bold: boolean, italic: boolean} +---@return boolean function mcl_title.set(player, type, data) if not data.color then data.color = "white" @@ -149,20 +166,25 @@ function mcl_title.set(player, type, data) 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)) + -- 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) - hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or gametick_to_secondes(mcl_title.params_get(player).stay) return true end +---@param player ObjectRef? +---@param type '"title"'|'"subtitle"'|'"actionbar"' function mcl_title.remove(player, type) if player then player:hud_change(huds_idx[type][player], "text", "") - --player:hud_change(huds_idx[type][player], "style", 0) --no styling + player:hud_change(huds_idx[type][player], "style", no_style) end end +---@param player ObjectRef function mcl_title.clear(player) mcl_title.remove(player, "title") mcl_title.remove(player, "subtitle") @@ -179,6 +201,7 @@ minetest.register_globalstep(function(dtime) subtitle = {}, actionbar = {}, } + for element, content in pairs(hud_hide_timeouts) do for name, timeout in pairs(content) do timeout = timeout - dtime @@ -190,47 +213,95 @@ minetest.register_globalstep(function(dtime) end end end + hud_hide_timeouts = new_timeouts end) --DEBUG STUFF!! ---[[ +--TODO:Proper /title command that can send the title to other players. +--These commands are just for debugging right now. +local dbg_msg = "Note that these are just debug commands right now. e.g. the title is only sent to he player issuing the command. Proper /title commands will be added in the future." minetest.register_chatcommand("title", { + privs = { debug = true }, func = function(name, param) local player = minetest.get_player_by_name(name) - mcl_title.set(player, "title", {text=param, color="gold", bold=true, italic=true}) + if player then + mcl_title.set(player, "title", { text = param, color = "gold", bold = true, italic = true }) + return true, dbg_msg + else + return false, dbg_msg + end end, }) minetest.register_chatcommand("subtitle", { + privs = { debug = true }, func = function(name, param) local player = minetest.get_player_by_name(name) - mcl_title.set(player, "subtitle", {text=param, color="gold"}) + if player then + mcl_title.set(player, "subtitle", { text = param, color = "gold" }) + return true, dbg_msg + else + return false, dbg_msg + end end, }) minetest.register_chatcommand("actionbar", { + privs = { debug = true }, func = function(name, param) local player = minetest.get_player_by_name(name) - mcl_title.set(player, "actionbar", {text=param, color="gold"}) + if player then + mcl_title.set(player, "actionbar", { text = param, color = "gold", bold = true, italic = true }) + return true, dbg_msg + else + return false, dbg_msg + end end, }) -minetest.register_chatcommand("timeout", { +minetest.register_chatcommand("title_timeout", { + privs = { debug = true }, func = function(name, param) local player = minetest.get_player_by_name(name) - mcl_title.params_set(player, {stay = 600}) + if player then + mcl_title.params_set(player, { stay = 600 }) + return true, dbg_msg + else + return false, dbg_msg + end end, }) -minetest.register_chatcommand("all", { +minetest.register_chatcommand("title_all", { + privs = { debug = true }, 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"}) + if player then + mcl_title.params_set(player, { stay = 600 }) + mcl_title.set(player, "title", { text = param, color = "gold" }) + mcl_title.set(player, "subtitle", { text = param, color = "gold" }) + mcl_title.set(player, "actionbar", { text = param, color = "gold" }) + return true, dbg_msg + else + return false, dbg_msg + end + end, +}) + +minetest.register_chatcommand("title_all_styles", { + privs = { debug = true }, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player then + mcl_title.params_set(player, { stay = 600 }) + mcl_title.set(player, "title", { text = param, color = "gold" }) + mcl_title.set(player, "subtitle", { text = param, color = "gold", bold = true }) + mcl_title.set(player, "actionbar", { text = param, color = "gold", italic = true }) + return true, dbg_msg + else + return false, dbg_msg + end end, }) -]] \ No newline at end of file diff --git a/mods/HUD/mcl_ver_info/init.lua b/mods/HUD/mcl_ver_info/init.lua new file mode 100644 index 000000000..632847275 --- /dev/null +++ b/mods/HUD/mcl_ver_info/init.lua @@ -0,0 +1,65 @@ +--- +--- Generated by EmmyLua +--- Created by Michieal. +--- DateTime: 11/28/22 4:38 PM +--- +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +local function xpcall_ver (error) + minetest.log("info", "mcl_ver_info:: Gamepath not supported in this version of Minetest.") +end + +local function get_game_info () + local game_info + + if xpcall(minetest.get_game_info, xpcall_ver) then + game_info = minetest.get_game_info() + else + minetest.log( S("Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.")) + return false + end + + return game_info +end + +-- register normal user access to debug levels 1 and 0. +minetest.register_chatcommand("ver", { + description = S("Display Mineclone 2 game version."), + func = function(name, params) + --[[ get_game_info's table data: + { + id = string, + title = string, + author = string, + -- The root directory of the game + path = string, + } + --]] + local game_info = get_game_info () + + if game_info == false then + return true + end + + local conf = Settings(game_info.path .. "/game.conf") + local version = conf:get("version") + + if game_info.title == nil or game_info.title == "" then + game_info.title = "Mineclone 2" + end + -- Notes: "game.conf doesn't support id currently, this is planned in the future" - rubenwardy from the github issue. + -- TODO: Remove workaround after minetest.get_game_info().id is implemented. + if version == nil or version == "" then -- workaround for id = not being implemented yet. + if game_info.id == nil or game_info.id == "" then + game_info.id = " Please upgrade your version to the newest version for the /ver command to work." + end + else + game_info.id = version + end + + minetest.chat_send_player(name, string.format("Version: %s - %s", game_info.title, game_info.id)) + return true + end +}) + diff --git a/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ja.tr b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ja.tr new file mode 100644 index 000000000..e306d9373 --- /dev/null +++ b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ja.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_ver_info +Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.=すみませんが、お使いの Minetest のバージョンは、最新のAPIをサポートしていません。minetest を更新してみて下さい。 \ No newline at end of file diff --git a/mods/HUD/mcl_ver_info/locale/template.txt b/mods/HUD/mcl_ver_info/locale/template.txt new file mode 100644 index 000000000..75febe815 --- /dev/null +++ b/mods/HUD/mcl_ver_info/locale/template.txt @@ -0,0 +1,2 @@ +# textdomain: mcl_ver_info +Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.= \ No newline at end of file diff --git a/mods/HUD/mcl_ver_info/mod.conf b/mods/HUD/mcl_ver_info/mod.conf new file mode 100644 index 000000000..b6f6dca98 --- /dev/null +++ b/mods/HUD/mcl_ver_info/mod.conf @@ -0,0 +1,4 @@ +name = mcl_ver_info +description = Prints game version information; /ver command. +depends = mcl_init +author = Michieal diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ja.tr b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ja.tr new file mode 100644 index 000000000..f836d8239 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ja.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_comparators +Redstone comparators are multi-purpose redstone components.=レッドストーンコンパレータは、多目的なレッドストーン部品です。 +They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.=レッドストーン信号の送信、ブロックにアイテムが含まれているかどうかの検出、複数の信号の比較などが可能です。 +A redstone comparator has 1 main input, 2 side inputs and 1 output. The output is in arrow direction, the main input is in the opposite direction. The other 2 sides are the side inputs.=レッドストーンコンパレータは、1つのメイン入力、2つのサイド入力、1つの出力を持ちます。出力は矢印方向で、メイン入力はその反対方向です。残りの2辺はサイド入力です。 +The main input can powered in 2 ways: First, it can be powered directly by redstone power like any other component. Second, it is powered if, and only if a container (like a chest) is placed in front of it and the container contains at least one item.=メイン入力には、2つの方法で動力を供給できます。1つ目は、他の機器と同様にレッドストーン動力によって直接動力を得られます。2つ目は、コンテナ(チェストのようなもの)が前に置かれ、そのコンテナに少なくとも1つのアイテムが入っている場合にのみ、動力が得られます。 +The side inputs are only powered by normal redstone power. The redstone comparator can operate in two modes: Transmission mode and subtraction mode. It starts in transmission mode and the mode can be changed by using the block.=サイド入力には、通常のレッドストーン動力のみが供給されます。レッドストーンコンパレータは、2つのモードで動作できます。送信モードと減算モードです。送信モードで起動し、ブロックによりモードを変更できます。 +Transmission mode:@nThe front torch is unlit and lowered. The output is powered if, and only if the main input is powered. The two side inputs are ignored.=送信モード:@n前面のトーチは非点灯で降りています。出力が動力を供給するのは、メイン入力に動力が来ている場合のみです。2つのサイド入力は無視されます。 +Subtraction mode:@nThe front torch is lit. The output is powered if, and only if the main input is powered and none of the side inputs is powered.=減算モード:@n前面のトーチは点灯しています。出力が動力を供給するのは、メイン入力に動力が来ており、且つサイド入力のいずれにも動力が来ていない場合のみです。 +Redstone Comparator=レッドストーンコンパレータ +Redstone Comparator (Subtract)=レッドストーンコンパレータ(減算) +Redstone Comparator (Powered)=レッドストーンコンパレータ(稼動) +Redstone Comparator (Subtract, Powered)=レッドストーンコンパレータ(減算・稼動) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index aa20fc813..dce69f26a 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -252,7 +252,16 @@ local dispenserdef = { elseif inv:room_for_item("main", od_ret) then inv:add_item("main", od_ret) else - minetest.add_item(droppos, dropitem) + local pos_variation = 100 + droppos = { + x = droppos.x + math.random(-pos_variation, pos_variation) / 1000, + y = droppos.y + math.random(-pos_variation, pos_variation) / 1000, + z = droppos.z + math.random(-pos_variation, pos_variation) / 1000, + } + local item_entity = minetest.add_item(droppos, dropitem) + local drop_vel = vector.subtract(droppos, pos) + local speed = 3 + item_entity:set_velocity(vector.multiply(drop_vel,speed)) end else stack:take_item() @@ -260,7 +269,16 @@ local dispenserdef = { end else -- Drop item otherwise - minetest.add_item(droppos, dropitem) + local pos_variation = 100 + droppos = { + x = droppos.x + math.random(-pos_variation, pos_variation) / 1000, + y = droppos.y + math.random(-pos_variation, pos_variation) / 1000, + z = droppos.z + math.random(-pos_variation, pos_variation) / 1000, + } + local item_entity = minetest.add_item(droppos, dropitem) + local drop_vel = vector.subtract(droppos, pos) + local speed = 3 + item_entity:set_velocity(vector.multiply(drop_vel,speed)) stack:take_item() inv:set_stack("main", stack_id, stack) end diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ja.tr b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ja.tr new file mode 100644 index 000000000..33d1caddf --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ja.tr @@ -0,0 +1,25 @@ +# textdomain: mcl_dispensers +Dispenser=ディスペンサー +A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=ディスペンサーはレッドストーン部品として機能するブロックで、レッドストーン動力によってアイテムを放出します。9つのインベントリスロットを備えたコンテナを有しています。 +Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=ディスペンサーを、限りある6方向のいずれかに設置します。「穴」は、アイテムがディスペンサーから飛び出す場所です。ディスペンサーを使用して、インベントリにアクセスします。放出したいアイテムを入れてください。レッドストーンエネルギーを供給すると、ランダムなアイテムが放出されます。 +The dispenser will do different things, depending on the dispensed item:=ディスペンサーは、放出されるアイテムによって振る舞いが異なる: +• Arrows: Are launched=矢:発射 +• Eggs and snowballs: Are thrown=卵、雪玉:投擲 +• Fire charges: Are fired in a straight line=発火弾:一直線に射撃 +• Armor: Will be equipped to players and armor stands=鎧:プレイヤーや防具立てに装備予定 +• Boats: Are placed on water or are dropped=ボート:水上に浮かべるか、ドロップ +• Minecart: Are placed on rails or are dropped=トロッコ:レールに乗せるか、ドロップ +• Bone meal: Is applied on the block it is facing=骨粉:向き合っているブロックに適用 +• Empty buckets: Are used to collect a liquid source=空のバケツ:液体の源泉を回収するために使用 +• Filled buckets: Are used to place a liquid source=充填済みのバケツ:液体の源泉を配置するために使用 +• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=頭、カボチャ:プレイヤーや防具立てに装備、またはブロックとして配置 +• Shulker boxes: Are placed as a block=シュルカーボックス:ブロックとして配置 +• TNT: Is placed and ignited=TNT:着火したTNTを設置 +• Flint and steel: Is used to ignite a fire in air and to ignite TNT=火打ち石と打ち金:空気とTNTに着火するために使用 +• Spawn eggs: Will summon the mob they contain=スポーンエッグ:各種mobを召喚 +• Other items: Are simply dropped=その他のアイテム:単純にドロップ +Downwards-Facing Dispenser=下向きディスペンサー +Upwards-Facing Dispenser=上向きディスペンサー +Inventory=インベントリ +9 inventory slots=9つのインベントリスロット +Launches item when powered by redstone power=レッドストーン動力が来ているとアイテムを発射 diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index abb351091..b9c46d6b8 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua @@ -134,7 +134,16 @@ local dropperdef = { -- No container? if not dropped and not dropnodedef.groups.container then -- Drop item normally - minetest.add_item(droppos, dropitem) + local pos_variation = 100 + droppos = { + x = droppos.x + math.random(-pos_variation, pos_variation) / 1000, + y = droppos.y + math.random(-pos_variation, pos_variation) / 1000, + z = droppos.z + math.random(-pos_variation, pos_variation) / 1000, + } + local item_entity = minetest.add_item(droppos, dropitem) + local drop_vel = vector.subtract(droppos, pos) + local speed = 3 + item_entity:set_velocity(vector.multiply(drop_vel,speed)) stack:take_item() inv:set_stack("main", stack_id, stack) end diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ja.tr b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ja.tr new file mode 100644 index 000000000..53f800ba4 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ja.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_droppers +Dropper=ドロッパー +A dropper is a redstone component and a container with 9 inventory slots which, when supplied with redstone power, drops an item or puts it into a container in front of it.=ドロッパーは、9つのインベントリスロットを持つコンテナのレッドストーン部品で、レッドストーン動力を供給されると、アイテムをドロップしたり手前のコンテナに入れたりします。 +Droppers can be placed in 6 possible directions, items will be dropped out of the hole. Use the dropper to access its inventory. Supply it with redstone energy once to make the dropper drop or transfer a random item.=ドロッパーは任意の6方向に設置することができ、穴からアイテムをドロップしようとします。ドロッパーを使用し、そのインベントリにアクセスします。ドロッパーにレッドストーンエネルギーを供給すると、ランダムなアイテムがドロップまたは転送されます。 +Downwards-Facing Dropper=下向きドロッパー +Upwards-Facing Dropper=上向きドロッパー +Inventory=インベントリ +9 inventory slots=9つのインベントリスロット +Drops item when powered by redstone power=レッドストーン動力が来るとアイテムをドロップ diff --git a/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ja.tr b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ja.tr new file mode 100644 index 000000000..b8acdf1e6 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_observers +Observer=オブザーバー +An observer is a redstone component which observes the block in front of it and sends a very short redstone pulse whenever this block changes.=オブザーバーはレッドストーン部品で、目前のブロックを観察し、このブロックが変更されるたびに非常に短いレッドストーンパルスを送信します。 +Place the observer directly in front of the block you want to observe with the “face” looking at the block. The arrow points to the side of the output, which is at the opposite side of the “face”. You can place your redstone dust or any other component here.=観察したいブロックの真正面に、オブザーバーの「顔」がブロックを見るように置いてください。矢印は出力側を指しており、「顔」の反対側にあたります。ここにはレッドストーンダスト等の部品が置けます。 +Emits redstone pulse when block in front changes=前方のブロックが変更されると、レッドストーンパルスを送信 diff --git a/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ja.tr b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ja.tr new file mode 100644 index 000000000..53109f675 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_target +Target=的 +A target is a block that provides a temporary redstone charge when hit by a projectile.=的は、飛び道具が当たると一時的にレッドストーンチャージを提供するブロックです。 +Throw a projectile on the target to activate it.=的に投射物を投げ当て、それを作動させます。 \ No newline at end of file diff --git a/mods/ITEMS/REDSTONE/mesecons_button/init.lua b/mods/ITEMS/REDSTONE/mesecons_button/init.lua index 2812b2758..fd765eded 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_button/init.lua @@ -112,7 +112,7 @@ function mesecon.register_button(basename, description, texture, recipeitem, sou if push_by_arrow then tt = tt .. "\n" .. S("Pushable by arrow") end - minetest.register_node("mesecons_button:button_"..basename.."_off", { + minetest.register_node(":mesecons_button:button_"..basename.."_off", { drawtype = "nodebox", tiles = {texture}, wield_image = "mesecons_button_wield_mask.png^"..texture.."^mesecons_button_wield_mask.png^[makealpha:255,126,126", @@ -147,7 +147,7 @@ function mesecon.register_button(basename, description, texture, recipeitem, sou _mcl_hardness = 0.5, }) - minetest.register_node("mesecons_button:button_"..basename.."_on", { + minetest.register_node(":mesecons_button:button_"..basename.."_on", { drawtype = "nodebox", tiles = {texture}, wield_image = "mesecons_button_wield_mask.png^"..texture.."^mesecons_button_wield_mask.png^[makealpha:255,126,126", @@ -223,6 +223,10 @@ local woods = { { "darkwood", "mcl_core:darkwood", "mcl_core_planks_big_oak.png", S("Dark Oak Button") }, { "sprucewood", "mcl_core:sprucewood", "mcl_core_planks_spruce.png", S("Spruce Button") }, { "junglewood", "mcl_core:junglewood", "default_junglewood.png", S("Jungle Button") }, + + { "mangrove_wood", "mcl_mangrove:mangrove_wood", "mcl_mangrove_planks.png", S("Mangrove Button") }, + { "crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", "crimson_hyphae_wood.png", S("Crimson Button") }, + { "warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", "warped_hyphae_wood.png", S("Warped Button") }, } for w=1, #woods do diff --git a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ja.tr b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ja.tr new file mode 100644 index 000000000..036568fad --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ja.tr @@ -0,0 +1,14 @@ +# textdomain: mesecons_button +Use the button to push it.=ボタンを押して使用します。 +Stone Button=石のボタン +A stone button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=石のボタンは石でできたレッドストーン部品で、押すことでレッドストーン動力を提供できます。押すと、隣接するレッドストーン部品を 1秒間 動作させます。 +Oak Button=オークのボタン +Acacia Button=アカシアのボタン +Birch Button=シラカバのボタン +Dark Oak Button=ダークオークのボタン +Spruce Button=トウヒのボタン +Jungle Button=ジャングルのボタン +A wooden button is a redstone component made out of wood which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1.5 seconds. Wooden buttons may also be pushed by arrows.=木製のボタンは木でできたレッドストーン部品で、押すことでレッドストーン動力を提供できます。押すと、隣接するレッドストーン部品を 1.5秒間 動作させます。木製のボタンは、矢でも押せます。 +Provides redstone power when pushed=押すとレッドストーン動力を提供 +Push duration: @1s=押下持続時間: @1秒 +Pushable by arrow=矢で押下可能 diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ja.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ja.tr new file mode 100644 index 000000000..1b46a6c7a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ja.tr @@ -0,0 +1,30 @@ +# textdomain: mesecons_commandblock +Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands.=エラー:コマンド「@1」は存在しません:コマンドブロックは変更されていません。使用可能なコマンドのリストについては、チャットコマンドの "help" を使用してください。 +Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands. Hint: Try to remove the leading slash.=エラー:コマンド「@1」は存在しません:コマンドブロックは変更されていません。使用可能なコマンドのリストについては、チャットコマンドの "help" を使用してください。 ヒント:先頭のスラッシュを削除してみてください。 +Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.=エラー:コマンド "@1" を使用するには権限不足です!(足りない権限: @2) コマンドブロックは変更されていません。 +Error: No commander! Block must be replaced.=エラー:コマンダーがいません! ブロックは交換しなければなりません。 +Commander: @1=コマンダー: @1 +Submit=提出 +No commands.=コマンドはありません。 +Commands:=コマンド: +Help=ヘルプ +Placement denied. You need the “maphack” privilege to place command blocks.=配置が拒否されました。コマンドブロックを配置するには "maphack" 権限が必要です。 +Command Block=コマンドブロック +Command blocks are mighty redstone components which are able to alter reality itself. In other words, they cause the server to execute server commands when they are supplied with redstone power.=コマンドブロックは、現実そのものを変換できる、強大なレッドストーン部品です。言い換えると、レッドストーン動力が供給されたときに、サーバーにサーバーコマンドを実行させるもの、です。 +Everyone can activate a command block and look at its commands, but not everyone can edit and place them.=コマンドブロックは誰でも起動でき、そのコマンドを見れますが、編集や配置は誰にでも出来るわけではありません。 +To view the commands in a command block, use it. To activate the command block, just supply it with redstone power. This will execute the commands once. To execute the commands again, turn the redstone power off and on again.=コマンドブロックのコマンドを表示するには、コマンドブロックを使用します。コマンドブロックを起動するには、レッドストーン動力を供給するだけです。これにより、コマンドが一回実行されます。コマンドを再度実行するには、レッドストーン動力を一旦オフにし、再度オンにしてください。 +To be able to place a command block and change the commands, you need to be in Creative Mode and must have the “maphack” privilege. A new command block does not have any commands and does nothing. Use the command block (in Creative Mode!) to edit its commands. Read the help entry “Advanced usage > Server Commands” to understand how commands work. Each line contains a single command. You enter them like you would in the console, but without the leading slash. The commands will be executed from top to bottom.=コマンドブロックを配置してコマンドを変更するには、クリエイティブモード且つ「maphack」権限が必要です。新しいコマンドブロックはコマンドを持たず、何もしません。コマンドブロックを使って(クリエイティブモードで!)そのコマンドを編集してください。コマンドの動作について知るには、ヘルプの "Advanced usage > Server Commands" をお読みください。各行は単一のコマンドを含んでいます。コンソールと同じように入力しますが、先頭のスラッシュを除きます。コマンドは上から順に実行されます。 +All commands will be executed on behalf of the player who placed the command block, as if the player typed in the commands. This player is said to be the “commander” of the block.=すべてのコマンドは、コマンドブロックを配置したプレイヤーに代わって、あたかもそのプレイヤーがコマンドを入力したかのように実行されます。このプレイヤーを、そのブロックの「コマンダー」と呼びます。 +Command blocks support placeholders, insert one of these placeholders and they will be replaced by some other text:=コマンドブロックはプレースホルダーをサポートしており、いずれかのプレースホルダーを挿入すると、他のテキストに置き換わります: +• “@@c”: commander of this command block=• "@@c":このコマンドブロックのコマンダー +• “@@n” or “@@p”: nearest player from the command block=• "@@n" か "@@p":コマンドブロックから最も近いプレイヤー +• “@@f” farthest player from the command block=• "@@f":ブロックから最も遠いプレイヤー +• “@@r”: random player currently in the world=• "@@r":いまワールドにいるランダムプレイヤー +• “@@@@”: literal “@@” sign=• "@@@@":文字通りの「@@」記号 +Example 1:@n time 12000@nSets the game clock to 12:00=例1:@n time 12000@nゲームクロックを12:00に設定 +Example 2:@n give @@n mcl_core:apple 5@nGives the nearest player 5 apples=例2:@n give @@n mcl_core:apple 5@n最も近いプレイヤーにリンゴを5個与える +Access denied. You need the “maphack” privilege to edit command blocks.=アクセスが拒否されました。コマンドブロックの編集には "maphack" 権限が必要です。 +Editing the command block has failed! You can only change the command block in Creative Mode!=コマンドブロックの編集に失敗しました! コマンドブロックの変更ができるのは、クリエイティブモードでのみ!です。 +Editing the command block has failed! The command block is gone.=コマンドブロックの編集に失敗しました! コマンドブロックがどこかいきました。 +Executes server commands when powered by redstone power=レッドストーン動力が来るとサーバーコマンドを実行 +Command blocks are not enabled on this server=このサーバーではコマンドブロックが有効になっていない diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ja.tr b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ja.tr new file mode 100644 index 000000000..74e8d644d --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ja.tr @@ -0,0 +1,13 @@ +# textdomain: mesecons_delayer +Redstone repeaters are versatile redstone components with multiple purposes: 1. They only allow signals to travel in one direction. 2. They delay the signal. 3. Optionally, they can lock their output in one state.=レッドストーンリピーターは多目的に使えるレッドストーン部品:1、信号は一方通行のみ。 2、信号が遅延する。 3、任意で,出力を1つの状態にロック可能。 +To power a redstone repeater, send a signal in “arrow” direction (the input). The signal goes out on the opposite side (the output) with a delay. To change the delay, use the redstone repeater. The delay is between 0.1 and 0.4 seconds long and can be changed in steps of 0.1 seconds. It is indicated by the position of the moving redstone torch.=レッドストーンリピーターを動かすには、「矢印」方向に信号を送ります(入力)。信号は遅延を伴って反対側(出力)に出ていきます。遅延時間を変更するには、レッドストーンリピーターを使用します。遅延は0.1~0.4秒の間で、0.1秒刻みで変更できます。それを示すのは、移動するレッドストーントーチの位置です。 +To lock a repeater, send a signal from an adjacent repeater into one of its sides. While locked, the moving redstone torch disappears, the output doesn't change and the input signal is ignored.=リピーターをロックするには、その側面にリピーターを隣接し信号を送ります。ロック中は、移動するレッドストーントーチが消え、出力は変化せず、入力信号も無視されます。 +Redstone Repeater=レッドストーンリピーター +Redstone Repeater (Powered)=レッドストーンリピーター(稼動) +Redstone Repeater (Locked)=レッドストーンリピーター(ロック済) +Redstone Repeater (Locked, Powered)=レッドストーンリピーター(ロック済・稼動) +Redstone Repeater (Delay @1)=レッドストーンリピーター(遅延 @1) +Redstone Repeater (Delay @1, Powered)=レッドストーンリピーター(遅延 @1・稼動) +Transmits redstone power only in one direction=レッドストーン動力の送信は一方向に限定 +Delays signal=信号の遅延 +Output locks when getting active redstone repeater signal from the side=側面からアクティブなレッドストーンリピーターの信号を受けると、出力をロック diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ja.tr b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ja.tr new file mode 100644 index 000000000..d3224f581 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mesecons_lightstone +Redstone Lamp=レッドストーンランプ +Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.=レッドストーンランプは、レッドストーン動力によって明るく灯る(明るさ @1)シンプルなレッドストーン部品です。 +Glows when powered by redstone power=レッドストーン動力が来ると点灯 diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua index 6e4616299..b2ff0916e 100644 --- a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua @@ -1,3 +1,4 @@ +local GRAVITY = tonumber(minetest.settings:get("movement_gravity")) local table = table --register stoppers for movestones/pistons @@ -328,17 +329,17 @@ function mesecon.mvps_move_objects(pos, dir, nodestack) -- Move object at tip of stack, pushpos is position at tip of stack local pushpos = vector.add(pos, vector.multiply(dir, #nodestack)) - local objects = minetest.get_objects_inside_radius(pushpos, 1) + local objects = minetest.get_objects_inside_radius(pushpos, 1.15) for _, obj in ipairs(objects) do table.insert(objects_to_move, obj) end -- Move objects lying/standing on the stack (before it was pushed - oldstack) - if tonumber(minetest.settings:get("movement_gravity")) > 0 and dir.y == 0 then + if GRAVITY > 0 then -- If gravity positive and dir horizontal, push players standing on the stack for _, n in ipairs(nodestack) do local p_above = vector.add(n.pos, {x=0, y=1, z=0}) - local objects = minetest.get_objects_inside_radius(p_above, 1) + local objects = minetest.get_objects_inside_radius(p_above, 1.15) for _, obj in ipairs(objects) do table.insert(objects_to_move, obj) end @@ -347,7 +348,10 @@ function mesecon.mvps_move_objects(pos, dir, nodestack) for _, obj in ipairs(objects_to_move) do local entity = obj:get_luaentity() - if not entity or not mesecon.is_mvps_unmov(entity.name) then + local player = obj:is_player() + + + if not entity or not player and not mesecon.is_mvps_unmov(entity.name) then local np = vector.add(obj:get_pos(), dir) --move only if destination is not solid @@ -355,6 +359,30 @@ function mesecon.mvps_move_objects(pos, dir, nodestack) if not ((not minetest.registered_nodes[nn.name]) or minetest.registered_nodes[nn.name].walkable) then obj:set_pos(np) + -- Launch Player, TNT & mobs like in Minecraft + -- Only doing so if slimeblock is attached. + for _, r in ipairs(mesecon.rules.alldirs) do + local adjpos = vector.add(np, r) + local adjnode = minetest.get_node(adjpos) + if minetest.registered_nodes[adjnode.name] and minetest.registered_nodes[adjnode.name].mvps_sticky and adjnode.name == "mcl_core:slimeblock" then + local np = vector.add(obj:get_pos(), dir) + + -- Reset acceleration of all objects before launching. + -- Fixes eggs, & snowballs thrown by dispensers + obj:set_acceleration({x=dir.x, y=-GRAVITY, z=dir.z}) + + --Need to set velocities differently for players, items & mobs/tnt, and falling anvils. + if player then + obj:add_velocity({x = dir.x * 10, y = dir.y * 13, z = dir.z * 10}) + elseif entity.name == "__builtin:item" then + obj:add_velocity({x = dir.x * 9, y = dir.y * 11, z = dir.z * 9}) + elseif entity.name == "__builtin:falling_node" then + obj:add_velocity({x = dir.x * 43, y = dir.y * 72, z = dir.z * 43}) + else + obj:add_velocity({x = dir.x * 6, y = dir.y * 9, z = dir.z * 6}) + end + end + end end end end diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ja.tr b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ja.tr new file mode 100644 index 000000000..0591b6b92 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ja.tr @@ -0,0 +1,22 @@ +# textdomain: mesecons_noteblock +Note Block=音符ブロック +A note block is a musical block which plays one of many musical notes and different intruments when it is punched or supplied with redstone power.=音符ブロックは、パンチしたりレッドストーン動力を供給することで、多くの音符やさまざまな楽器のうちの1つを演奏する音楽ブロックです。 +Use the note block to choose the next musical note (there are 25 semitones, or 2 octaves). The intrument played depends on the material of the block below the note block:=音符ブロックを使って、次の音符を選択(25半音、つまり2オクターブ分あり)。演奏される楽器は、音符ブロックの下にあるブロックの素材に依存: +• Glass: Sticks=ガラス:スティック +• Wood: Bass guitar=木:ベースギター +• Stone: Bass drum=石:バスドラム +• Sand or gravel: Snare drum=砂・砂利:スネアドラム +• Anything else: Piano=その他:ピアノ +• Block of Gold: Bell=金ブロック:ベル +• Clay: Flute=粘土:フルート +• Packed Ice: Chime=氷塊:チャイム +• Wool: Guitar=羊毛:ギター +• Bone Block: Xylophne=骨ブロック:木琴 +• Block of Iron: Iron xylophne=鉄ブロック:鉄琴 +• Soul Sand: Cow bell=ソウルサンド:カウベル +• Pumpkin: Didgeridoo=カボチャ:ディジュリドゥ +• Block of Emerald: Square wave=エメラルドブロック:矩形波 +• Hay Bale: Banjo=干し草の俵:バンジョー +• Glowstone: Electric piano=グローストーン:電子ピアノ +The note block will only play a note when it is below air, otherwise, it stays silent.=音符ブロックは、空気の下でのみ音を鳴らし、それ以外では無音のままです。 +Plays a musical note when powered by redstone power=レッドストーン動力が来ると音符を演奏 diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ja.tr b/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ja.tr new file mode 100644 index 000000000..949de6805 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mesecons_pistons +This block can have one of 6 possible orientations.=このブロックは6つの可能な方向からひとつ選べます。 +Piston=ピストン +A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=ピストンとは、押出機を備えたレッドストーン部品のことで、レッドストーン動力が供給されると、その前方の1つないしは複数のブロックを押します。ただし、すべてのブロックが押せるわけではありません。 +Sticky Piston=粘着ピストン +A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=粘着ピストンは、粘着付押出機が伸縮できるレッドストーン部品です。レッドストーン動力が供給されると伸びます。押出機が伸びると、その前方の1つないしは複数のブロックを押します。押出機が縮むと、手前にある1つのブロックを引き戻します。なお、すべてのブロックが伸縮できるわけではありません。 +Pushes block when powered by redstone power=レッドストーン動力が来るとブロックを押す +Pushes or pulls block when powered by redstone power=レッドストーン動力が来るとブロックを押すか引く diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua b/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua index 495fbd048..9248e693e 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua @@ -12,6 +12,16 @@ local pp_box_on = { fixed = { -7/16, -8/16, -7/16, 7/16, -7.5/16, 7/16 }, } +local function pp_on_rightclick(pos, node) + local basename = minetest.registered_nodes[node.name].pressureplate_basename + if node.name == basename .. "_off" then + minetest.set_node(pos, { name = basename .. "_on" }) + mesecon.receptor_on(pos, mesecon.rules.pplate) + else + minetest.get_meta(pos):set_string("deact_time", "") + end +end + local function pp_on_timer(pos, elapsed) local node = minetest.get_node(pos) local basename = minetest.registered_nodes[node.name].pressureplate_basename @@ -37,34 +47,80 @@ local function pp_on_timer(pos, elapsed) end end - local objs = minetest.get_objects_inside_radius(pos, 1) + local function obj_touching_plate_pos(obj_ref, plate_pos) + local obj_pos = obj_ref:get_pos() + local props = obj_ref:get_properties() + local parent = obj_ref:get_attach() + if props and obj_pos and not parent then + local collisionbox = props.collisionbox + local physical = props.physical + local is_player = obj_ref:is_player() + local luaentity = obj_ref:get_luaentity() + local is_item = luaentity and luaentity.name == "__builtin:item" + if collisionbox and physical or is_player or is_item then + local plate_x_min = plate_pos.x - 7 / 16 + local plate_x_max = plate_pos.x + 7 / 16 + local plate_z_min = plate_pos.z - 7 / 16 + local plate_z_max = plate_pos.z + 7 / 16 + local plate_y_max = plate_pos.y - 7 / 16 - if node.name == basename .. "_on" then - local disable - if #objs == 0 then - disable = true - elseif not activated_by.any then - disable = true - for k, obj in pairs(objs) do - if obj_does_activate(obj, activated_by) then - disable = false - break + local obj_x_min = obj_pos.x + collisionbox[1] + local obj_x_max = obj_pos.x + collisionbox[4] + local obj_z_min = obj_pos.z + collisionbox[3] + local obj_z_max = obj_pos.z + collisionbox[6] + local obj_y_min = obj_pos.y + collisionbox[2] + + if + obj_y_min <= plate_y_max and + not (obj_x_min >= plate_x_max) and + not (obj_x_max <= plate_x_min) and + not (obj_z_min >= plate_z_max) and + not (obj_z_max <= plate_z_min) + then + return true end end end + return false + end + + local objs = minetest.get_objects_inside_radius(pos, 1) + + if node.name == basename .. "_on" then + local disable = true + for k, obj in pairs(objs) do + if + obj_does_activate(obj, activated_by) and + obj_touching_plate_pos(obj, pos) + then + disable = false + minetest.get_meta(pos):set_string("deact_time", "") + break + end + end if disable then - minetest.set_node(pos, {name = basename .. "_off"}) - mesecon.receptor_off(pos, mesecon.rules.pplate) + local meta = minetest.get_meta(pos) + local deact_time = meta:get_float("deact_time") + local current_time = minetest.get_us_time() + if deact_time == 0 then + deact_time = current_time + 1 * 1000 * 1000 + meta:set_float("deact_time", deact_time) + end + if deact_time <= current_time then + minetest.set_node(pos, { name = basename .. "_off" }) + mesecon.receptor_off(pos, mesecon.rules.pplate) + meta:set_string("deact_time", "") + end end elseif node.name == basename .. "_off" then for k, obj in pairs(objs) do - local objpos = obj:get_pos() - if obj_does_activate(obj, activated_by) then - if objpos.y > pos.y-1 and objpos.y < pos.y then - minetest.set_node(pos, {name = basename .. "_on"}) - mesecon.receptor_on(pos, mesecon.rules.pplate) - break - end + if + obj_does_activate(obj, activated_by) and + obj_touching_plate_pos(obj, pos) + then + minetest.set_node(pos, { name = basename .. "_on" }) + mesecon.receptor_on(pos, mesecon.rules.pplate) + break end end end @@ -118,6 +174,7 @@ function mesecon.register_pressure_plate(basename, description, textures_off, te walkable = false, description = description, on_timer = pp_on_timer, + on_rightclick = pp_on_rightclick, on_construct = function(pos) minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL) end, @@ -164,6 +221,10 @@ local woods = { { "darkwood", "mcl_core:darkwood", "mcl_core_planks_big_oak.png", S("Dark Oak Pressure Plate" )}, { "sprucewood", "mcl_core:sprucewood", "mcl_core_planks_spruce.png", S("Spruce Pressure Plate") }, { "junglewood", "mcl_core:junglewood", "default_junglewood.png", S("Jungle Pressure Plate") }, + + { "mangrove_wood", "mcl_mangrove:mangrove_wood", "mcl_mangrove_planks.png", S("Mangrove Pressure Plate") }, + { "crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", "crimson_hyphae_wood.png", S("Crimson Pressure Plate") }, + { "warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", "warped_hyphae_wood.png", S("Warped Pressure Plate") }, } for w=1, #woods do diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ja.tr b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ja.tr new file mode 100644 index 000000000..f1e926e31 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ja.tr @@ -0,0 +1,16 @@ +# textdomain: mesecons_pressureplates +A pressure plate is a redstone component which supplies its surrounding blocks with redstone power while someone or something rests on top of it.=感圧板はレッドストーン部品で、誰かや何かがその上に乗っている間、周囲のブロックにレッドストーン動力を供給します。 +Oak Pressure Plate=オークの感圧板 +Acacia Pressure Plate=アカシアの感圧板 +Birch Pressure Plate=シラカバの感圧板 +Dark Oak Pressure Plate=ダークオークの感圧板 +Spruce Pressure Plate=トウヒの感圧板 +Jungle Pressure Plate=ジャングルの感圧板 +A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=木製の感圧板はレッドストーン部品で、ドロップアイテムやプレイヤー、モブを含む移動可能なオブジェクトがその上に乗っている間、周囲のブロックにレッドストーン動力を供給します。 +Stone Pressure Plate=石の感圧板 +A stone pressure plate is a redstone component which supplies its surrounding blocks with redstone power while a player or mob stands on top of it. It is not triggered by anything else.=石の感圧板はレッドストーン部品で、プレイヤーやモブがその上に立っている間、周囲のブロックにレッドストーン動力を供給します。他の何かがトリガーになることはありません。 +Provides redstone power when pushed=押すとレッドストーン動力を供給 +Pushable by players, mobs and objects=押せるのはプレイヤー、モブ、オブジェクト +Pushable by players and mobs=押せるのはプレイヤーかモブ +Pushable by players=押せるのはプレイヤー +Pushable by mobs=押せるのはモブ diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ja.tr b/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ja.tr new file mode 100644 index 000000000..5ba7a13ec --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mesecons_solarpanel +Daylight Sensor=日照センサー +Daylight sensors are redstone components which provide redstone power when they are in sunlight and no power otherwise. They can also be inverted.=日照センサーはレッドストーン機器で、日光の下にいるときにレッドストーン動力を供給し、それ以外のときは出力しません。また、反転させることもできます。 +Use the daylight sensor to toggle its state.=日照センサーを使用して、その状態を切り替えます。 +Inverted Daylight Sensor=反転した日照センサー +In inverted state, they provide redstone power when they are not in sunlight and no power otherwise.=反転状態では、日光が当たっていないときにレッドストーン動力を供給し、それ以外のときは出力しません。 +Provides redstone power when in sunlight=日光の下でレッドストーン動力を供給 +Can be inverted=反転可能 diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ja.tr b/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ja.tr new file mode 100644 index 000000000..05bfa2574 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ja.tr @@ -0,0 +1,10 @@ +# textdomain: mesecons_torch +Redstone Torch=レッドストーントーチ +Redstone Torch (off)=レッドストーントーチ(オフ) +Redstone Torch (overheated)=レッドストーントーチ(熱過多状態) +A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything.=レッドストーントーチはレッドストーン部品で、レッドストーン信号を反転させるのに使えます。それは、それが取り付けられているブロックを除いて、その周囲のブロックにレッドストーン動力を供給します。レッドストーントーチは通常点灯していますが、接続されているブロックに動力を供給することで消灯も可能です。消灯中のレッドストーントーチは、何の動力源にもなりません。 +Redstone torches can be placed at the side and on the top of full solid opaque blocks.=レッドストーントーチは、全固体の不透明ブロックの側面と上部に配置できます。 +Block of Redstone= +A block of redstone permanently supplies redstone power to its surrounding blocks.=レッドストーンブロックは、その周囲のブロックに、レッドストーン動力を永続的に供給します。 +Provides redstone power when it's not powered itself=自身が動力を得ていない時にレッドストーン動力を提供 +Provides redstone power=レッドストーン動力を提供 diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_off.png b/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_off.png index cecdaf8fa..fff9a53a9 100644 Binary files a/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_off.png and b/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_off.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_on.png b/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_on.png index 24d0a94d9..705f3db94 100644 Binary files a/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_on.png and b/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_on.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.de.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.de.tr index 27a3bb55f..880219396 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.de.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.de.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever=Hebel A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=Ein Hebel ist eine Redstonekomponente, die ein- und ausgeschaltet werden kann. Er versorgt seine benachbarten Blöcke mit Redstoneenergie, solange er sich im eingeschalteten Zustand befindet. Use the lever to flip it on or off.=Benutzen Sie den Hebel, um ihn ein- oder auszuschalten. diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.es.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.es.tr index e0e55298e..9b83bf6db 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.es.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.es.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever=Palanca A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=EUna palanca es un componente de redstone que se puede activar y desactivar. Suministra energía redstone a bloques adyacentes mientras está en el estado "encendido". Use the lever to flip it on or off.=Use la palanca para encenderlo o apagarlo. diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.fr.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.fr.tr index 3d5d23c81..c3dc63aa9 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.fr.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.fr.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever=Levier A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=Un levier est un composant de redstone qui peut être activé et désactivé. Il fournit de l'énergie redstone aux blocs adjacents pendant qu'il est à l'état "activé". Use the lever to flip it on or off.=Utilisez le levier pour l'activer ou le désactiver. diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ja.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ja.tr new file mode 100644 index 000000000..d751d9d15 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mesecons_walllever +Lever=レバー +A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=レバーは、オンとオフを切り替えられるレッドストーン部品です。「オン」の状態の間は、隣接するブロックにレッドストーン動力を供給します。 +Use the lever to flip it on or off.=レバーでON/OFFを切り替えます。 +Provides redstone power while it's turned on=電源オン時にレッドストーン動力を提供 diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr index 924fe3dd0..9bfed99db 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever=Dźwignia A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=Dźwignia jest czerwienitowym elementem, który można przełączać między stanem włączonym i wyłączonym. Wysyła ona czerwienitową energię gdy jest w stanie włączonym. Use the lever to flip it on or off.=Użyj dźwigni by przełączyć ją między stanami. diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr index 6ed05b387..00a3e84f1 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever=Рычаг A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=Рычаг это компонент редстоуна, который можно включать и выключать. Он подаёт энергию редстоуна на соседние блоки, пока он находится во «включённом» состоянии. Use the lever to flip it on or off.=[Используйте] рычаг, чтобы перещёлкнуть его во включённое или выключенное положение . diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/template.txt index 0187e6d28..198ad9f9a 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/template.txt +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/template.txt @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever= A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.= Use the lever to flip it on or off.= diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ja.tr b/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ja.tr new file mode 100644 index 000000000..33da44f9c --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ja.tr @@ -0,0 +1,11 @@ +# textdomain: mesecons_wires +Redstone is a versatile conductive mineral which transmits redstone power. It can be placed on the ground as a trail.=レッドストーンは、レッドストーン動力を伝達する多用途の導電性鉱物です。地面に導線を敷設できます。 +A redstone trail can be in two states: Powered or not powered. A powered redstone trail will power (and thus activate) adjacent redstone components.=レッドストーン導線は、稼動と非稼動の2つの状態がとれます。稼動中のレッドストーン導線は、隣接するレッドストーン部品に動力を与えます(つまり作動します)。 +Redstone power can be received from various redstone components, such as a block of redstone or a button. Redstone power is used to activate numerous mechanisms, such as redstone lamps or pistons.=レッドストーン動力は、レッドストーンのブロックやボタンなど、さまざまなレッドストーン部品から受け取れます。レッドストーン動力は、レッドストーンランプやピストンなど、数々なメカニズムを作動させるために使われます。 +Place redstone on the ground to build a redstone trail. The trails will connect to each other automatically and it can also go over hills. An easy way to power a redstone trail is by placing a redstone torch.=レッドストーンを地面に置くと、レッドストーン導線ができます。導線は自動的に相互接続され、丘を越えることもできます。レッドストーン導線に動力を伝える簡単な方法は、レッドストーントーチを置くことです。 +Read the help entries on the other redstone components to learn how redstone components interact.=レッドストーン部品がどのように相互作用するかについては、他のレッドストーン部品のヘルプエントリーをお読みください。 +Redstone=レッドストーン +Powered Redstone Spot (@1)=稼動中のレッドストーンスポット (@1) +Redstone Trail (@1)=レッドストーン導線 (@1) +Powered Redstone Trail (@1)=稼動中のレッドストーン導線 (@1) +Transmits redstone power, powers mechanisms=レッドストーン動力の伝達、メカニズム類の起動 diff --git a/mods/ITEMS/mcl_amethyst/init.lua b/mods/ITEMS/mcl_amethyst/init.lua index 0ee78de41..e43223a41 100644 --- a/mods/ITEMS/mcl_amethyst/init.lua +++ b/mods/ITEMS/mcl_amethyst/init.lua @@ -117,7 +117,6 @@ for _, def in pairs(bud_def) do walkable = false, light_source = def.light_source, groups = { - dig_by_water = 1, destroy_by_lava_flow = 1, dig_by_piston = 1, pickaxey = 1, @@ -162,7 +161,6 @@ minetest.register_node("mcl_amethyst:amethyst_cluster",{ walkable = false, light_source = 7, groups = { - dig_by_water = 1, destroy_by_lava_flow = 1, dig_by_piston = 1, pickaxey = 1, diff --git a/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ja.tr b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ja.tr new file mode 100644 index 000000000..4535580e9 --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ja.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_amethyst +Amethyst Cluster=アメジストの集塊 +Amethyst Cluster is the final growth of amethyst bud.=アメジストの集塊は、アメジストの芽の成長最終段階です。 +Amethyst Shard=アメジストの欠片 +An amethyst shard is a crystalline mineral.=アメジストの欠片は、結晶性の鉱物です。 +Block of Amethyst=アメジストブロック +Budding Amethyst=芽生えたアメジスト +Calcite=方解石 +Calcite can be found as part of amethyst geodes.=方解石は、アメジストジオードの一部として見つけることができます。 +Large Amethyst Bud=大きなアメジストの芽 +Large Amethyst Bud is the third growth of amethyst bud.=大きなアメジストの芽は、アメジストの芽の成長三段階目です。 +Medium Amethyst Bud=中くらいのアメジストの芽 +Medium Amethyst Bud is the second growth of amethyst bud.=中くらいのアメジストの芽は、アメジストの芽の成長二段階目です。 +Small Amethyst Bud=小さなアメジストの芽 +Small Amethyst Bud is the first growth of amethyst bud.=小さなアメジストの芽は、アメジストの芽の成長一段階目です。 +The Block of Amethyst is a decoration block crafted from amethyst shards.=アメジストブロックは、アメジストの欠片を加工した装飾ブロックです。 +The Budding Amethyst can grow amethyst=芽生えたアメジストは、アメジストを育成可能 +Tinted Glass=遮光ガラス +Tinted Glass is a type of glass which blocks lights while it is visually transparent.=遮光ガラスは、視覚的には透明でありながら光を遮断するタイプのガラスです。 diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index d3b32b844..a56299cd9 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -84,6 +84,19 @@ local function distinguish_tool_and_material(input1, input2) end end +-- Helper function to make sure update_anvil_slots NEVER overstacks the output slot +local function fix_stack_size(stack) + if not stack or stack == "" then return "" end + local count = stack:get_count() + local max_count = stack:get_stack_max() + + if count > max_count then + stack:set_count(max_count) + count = max_count + end + return count +end + -- Update the inventory slots of an anvil node. -- meta: Metadata of anvil node local function update_anvil_slots(meta) @@ -213,6 +226,7 @@ local function update_anvil_slots(meta) -- Set the new output slot if new_output then + fix_stack_size(new_output) inv:set_stack("output", 1, new_output) end end diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ja.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ja.tr new file mode 100644 index 000000000..881ea5460 --- /dev/null +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ja.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_anvils +Set Name=名称を設定 +Repair and Name=修理・銘 +Inventory=インベントリ +Anvil=金床 +The anvil allows you to repair tools and armor, and to give names to items. It has a limited durability, however. Don't let it fall on your head, it could be quite painful!=金床は、道具や防具を修理したり、アイテムに名前を付けたりできます。ただし耐久性には限度があります。頭に落ちると痛すぎるので注意しましょう! +To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.=金床を使用するには、右クリックです。金床には、2つの入力スロット(左側)と1つの出力スロットがあります。 +To rename items, put an item stack in one of the item slots while keeping the other input slot empty. Type in a name, hit enter or “Set Name”, then take the renamed item from the output slot.=アイテムを改名するには、入力スロットの片方にアイテムを入れ、もう一方は空のままにしておきます。名前を入力し、エンターキーか「名称を設定」を押したら、出力スロットから改名したアイテムを取り出します。 +There are two possibilities to repair tools (and armor):=道具(と防具)の修理方法には、可能性が次の2通りある: +• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.=・ 道具 + 道具:同種の道具を2つ、入力スロットに置きます。修理された道具の「耐久度」は、入力した両方の道具の「耐久度」合計に、ボーナスで12%を加算させたものになります。 +• Tool + Material: Some tools can also be repaired by combining them with an item that it's made of. For example, iron pickaxes can be repaired with iron ingots. This repairs the tool by 25%.=・ 道具 + 素材:道具の中には、その素材となっているアイテムと組み合わせることで修理できるものもあります。例えば、鉄のツルハシは鉄インゴットで修理可能です。この場合、道具は25%修復されます。 +Armor counts as a tool. It is possible to repair and rename a tool in a single step.=防具は、道具としてカウントされます。道具の修理と改名を一括して行えます。 +The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed.=金床は耐久性に限度があります(3段階の損傷レベル:無傷、やや損傷、かなり損傷)。何かを修理したり改名するたび、確率12%で金床が傷みます。また、金床は1ブロック以上落下した時にも傷む可能性があります。かなり損傷した金床に更なる傷が入った場合、壊れます。 +Slightly Damaged Anvil=やや損傷した金床 +Very Damaged Anvil=かなり損傷した金床 +Repair and rename items=アイテムの修理と改名 diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua index 6ec1b377b..1b9aa4f73 100644 --- a/mods/ITEMS/mcl_armor/api.lua +++ b/mods/ITEMS/mcl_armor/api.lua @@ -114,6 +114,10 @@ function mcl_armor.register_set(def) for k, v in pairs(element_groups) do groups[k] = v end + local upgrade_item = nil + if def._mcl_upgradable and def._mcl_upgrade_item_material then + upgrade_item = itemstring:gsub("_[%l%d]*$",def._mcl_upgrade_item_material) + end minetest.register_tool(itemstring, { description = S(def.description .. " " .. (descriptions[name] or element.description)), @@ -133,6 +137,8 @@ function mcl_armor.register_set(def) _on_break = on_break_callbacks[name] or def.on_break, _mcl_armor_element = name, _mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png", + _mcl_upgradable = def._mcl_upgradable, + _mcl_upgrade_item = upgrade_item }) if def.craft_material then diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua index ed616397d..2606f8263 100644 --- a/mods/ITEMS/mcl_armor/damage.lua +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -33,7 +33,7 @@ mcl_damage.register_modifier(function(obj, damage, reason) local itemname = itemstack:get_name() local enchantments = mcl_enchanting.get_enchantments(itemstack) - if not flags.bypasses_armor then + if not flags.bypasses_armor and minetest.get_item_group(itemname, "non_combat_armor") == 0 then points = points + minetest.get_item_group(itemname, "mcl_armor_points") toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness") @@ -90,6 +90,8 @@ mcl_damage.register_modifier(function(obj, damage, reason) if thorns_damage > 0 and reason.type ~= "thorns" and reason.source ~= obj then mcl_util.deal_damage(reason.source, thorns_damage, {type = "thorns", direct = obj}) + -- mcl_util.deal_damage may remove object immediately + if not reason.source:get_pos() then return end local thorns_item = thorns_pieces[math.random(#thorns_pieces)] diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr index 6f55a73fe..19c24c73d 100644 --- a/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr @@ -6,18 +6,45 @@ Iron Helmet=Casque de Fer Golden Helmet=Casque d'Or Diamond Helmet=Casque de Diamant Chain Helmet=Casque de Mailles +Netherite Helmet=Casque de Netherite Leather Tunic=Tunique en Cuir Iron Chestplate=Plastron de Fer Golden Chestplate=Plastron d'Or Diamond Chestplate=Plastron de Diamant Chain Chestplate=Cotte de Mailles +Netherite Chestplate=Plastron de Netherite Leather Pants=Pantalon de Cuir Iron Leggings=Jambières de Fer Golden Leggings=Jambières d'Or Diamond Leggings=Jambières de Diamant Chain Leggings=Jambières de Mailles +Netherite Leggings=Jambières de Netherite Leather Boots=Bottes de Cuir Iron Boots=Bottes de Fer Golden Boots=Bottes d'Or Diamond Boots=Bottes de Diamant Chain Boots=Bottes de Mailles +Netherite Boots=Bottes de Netherite +Elytra=Élytres + +#Translations of enchantements +Increases underwater mining speed.=Augmente la vitesse de minage sous-marine. +Blast Protection=Protection contre les explosions +Reduces explosion damage and knockback.=Réduit les dégâts d'explosion et de recul. +Curse of Binding=Malédiction du lien éternel +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=L'objet ne peut pas être retiré des emplacements d'armure sauf en cas de mort, de rupture ou en mode créatif. +Feather Falling=Chute amortie +Reduces fall damage.=Réduit les dégats de chute. +Fire Protection=Protection contre le feu +Reduces fire damage.=Reduit les dégats de feu. +Shooting consumes no regular arrows.=Le tir ne consomme pas de flèches standard. +Shoot 3 arrows at the cost of one.=Tirez sur 3 flèches au prix d'une. +Projectile Protection=Protection contre les projectiles +Reduces projectile damage.=Réduit les dommages causés par les projectiles. +Protection=Protection +Reduces most types of damage by 4% for each level.=Réduit la plupart des types de dégâts de 4% pour chaque niveau. +Thorns=Épines +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflète une partie des dégâts subis lors de la frappe, au prix d'une réduction de la durabilité à chaque déclenchement. +Aqua Affinity=Affinité aquatique + + diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.ja.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.ja.tr new file mode 100644 index 000000000..fc1f0f02b --- /dev/null +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.ja.tr @@ -0,0 +1,48 @@ +# textdomain: mcl_armor +This is a piece of equippable armor which reduces the amount of damage you receive.=被ダメージを軽減する、装備可能な防具です。 +To equip it, put it on the corresponding armor slot in your inventory menu.=装備するには、インベントリメニュー中の対応する防具スロットに置いてください。 +Leather Cap=革のキャップ +Iron Helmet=鉄のヘルメット +Golden Helmet=金のヘルメット +Diamond Helmet=ダイヤモンドのヘルメット +Chain Helmet=鎖のヘルメット +Netherite Helmet=ネザライトのヘルメット +Leather Tunic=革のチュニック +Iron Chestplate=鉄のチェストプレート +Golden Chestplate=金のチェストプレート +Diamond Chestplate=ダイヤモンドのチェストプレート +Chain Chestplate=鎖のチェストプレート +Netherite Chestplate=ネザライトのチェストプレート +Leather Pants=革のズボン +Iron Leggings=鉄のレギンス +Golden Leggings=金のレギンス +Diamond Leggings=ダイヤモンドのレギンス +Chain Leggings=鎖のレギンス +Netherite Leggings=ネザライトのレギンス +Leather Boots=革のブーツ +Iron Boots=鉄のブーツ +Golden Boots=金のブーツ +Diamond Boots=ダイヤモンドのブーツ +Chain Boots=鎖のブーツ +Netherite Boots=ネザライトのブーツ +Elytra=エリトラ + +#Translations of enchantements +Increases underwater mining speed.=水中でも採掘速度が低下しません。 +Blast Protection=爆風耐性 +Reduces explosion damage and knockback.=爆発ダメージとノックバックを軽減します。 +Curse of Binding=束縛の呪い +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=次の場合を除き、防具スロットからアイテムを外せません;アイテムが破損/自身が死亡/クリエイティブモード中 +Feather Falling=落下耐性 +Reduces fall damage.=落下ダメージを軽減します。 +Fire Protection=炎上耐性 +Reduces fire damage.=火炎ダメージを軽減します(溶岩は対象外)。 +Shooting consumes no regular arrows.=普通の矢なら放っても消費しません。 +Shoot 3 arrows at the cost of one.=1本分のコストで3本の矢を放ちます。 +Projectile Protection=飛来物耐性 +Reduces projectile damage.=飛来物ダメージを軽減します。 +Protection=外傷耐性 +Reduces most types of damage by 4% for each level.=体の外からのダメージ全般を軽減します(レベル毎に+4%)。 +Thorns=イバラ +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=受けたダメージの一部を与え返せますが、その代わり耐久度が余計に削られます。 +Aqua Affinity=水中採掘 \ No newline at end of file diff --git a/mods/ITEMS/mcl_armor/locale/template.txt b/mods/ITEMS/mcl_armor/locale/template.txt index 8a95fca02..4b4ad8385 100644 --- a/mods/ITEMS/mcl_armor/locale/template.txt +++ b/mods/ITEMS/mcl_armor/locale/template.txt @@ -6,18 +6,43 @@ Iron Helmet= Golden Helmet= Diamond Helmet= Chain Helmet= +Netherite Helmet= Leather Tunic= Iron Chestplate= Golden Chestplate= Diamond Chestplate= Chain Chestplate= +Netherite Chestplate= Leather Pants= Iron Leggings= Golden Leggings= Diamond Leggings= Chain Leggings= +Netherite Leggings= Leather Boots= Iron Boots= Golden Boots= Diamond Boots= Chain Boots= +Netherite Boots= +Elytra= + +#Translations of enchantements +Increases underwater mining speed.= +Blast Protection= +Reduces explosion damage and knockback.= +Curse of Binding=Malédiction du lien éternel +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.= +Feather Falling= +Reduces fall damage.= +Fire Protection= +Reduces fire damage.= +Shooting consumes no regular arrows.= +Shoot 3 arrows at the cost of one.= +Projectile Protection= +Reduces projectile damage.= +Protection= +Reduces most types of damage by 4% for each level.= +Thorns= +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.= +Aqua Affinity= \ No newline at end of file diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d index b3a943f46..9c1b290a6 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d and b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend b/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend index a613eef89..b41b3c575 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend and b/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d index 4e17ee341..15a131e94 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 b0494efbf..8c16536b2 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/register.lua b/mods/ITEMS/mcl_armor/register.lua index 1f9ce7b02..89ff5ca9f 100644 --- a/mods/ITEMS/mcl_armor/register.lua +++ b/mods/ITEMS/mcl_armor/register.lua @@ -49,6 +49,8 @@ mcl_armor.register_set({ }, repair_material = "mcl_core:iron_ingot", cook_material = "mcl_core:iron_nugget", + sound_equip = "mcl_armor_equip_iron", + sound_unequip = "mcl_armor_unequip_iron", }) mcl_armor.register_set({ @@ -64,6 +66,8 @@ mcl_armor.register_set({ }, craft_material = "mcl_core:iron_ingot", cook_material = "mcl_core:iron_nugget", + sound_equip = "mcl_armor_equip_iron", + sound_unequip = "mcl_armor_unequip_iron", }) mcl_armor.register_set({ @@ -79,6 +83,28 @@ mcl_armor.register_set({ }, toughness = 2, craft_material = "mcl_core:diamond", + sound_equip = "mcl_armor_equip_diamond", + sound_unequip = "mcl_armor_unequip_diamond", + _mcl_upgradable = true, + _mcl_upgrade_item_material = "_netherite", +}) + +mcl_armor.register_set({ + name = "netherite", + description = "Netherite", + durability = 555, + enchantability = 10, + points = { + head = 3, + torso = 8, + legs = 6, + feet = 3, + }, + groups = { fire_immune=1 }, + toughness = 2, + craft_material = "mcl_nether:netherite_ingot", + sound_equip = "mcl_armor_equip_diamond", + sound_unequip = "mcl_armor_unequip_diamond", }) mcl_armor.register_protection_enchantment({ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_netherite.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_netherite.png new file mode 100644 index 000000000..39f84afb1 Binary files /dev/null and b/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_netherite.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_netherite.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_netherite.png new file mode 100644 index 000000000..8e3a38366 Binary files /dev/null and b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_netherite.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_netherite.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_netherite.png new file mode 100644 index 000000000..c35f11247 Binary files /dev/null and b/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_netherite.png differ diff --git a/mods/ITEMS/mcl_amethyst/textures/mcl_amethyst_amethyst_cluster_block.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_netherite.png similarity index 56% rename from mods/ITEMS/mcl_amethyst/textures/mcl_amethyst_amethyst_cluster_block.png rename to mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_netherite.png index 7ea932bf8..a73c1b2fd 100644 Binary files a/mods/ITEMS/mcl_amethyst/textures/mcl_amethyst_amethyst_cluster_block.png and b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_netherite.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_netherite.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_netherite.png new file mode 100644 index 000000000..32fabb10f Binary files /dev/null and b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_netherite.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_netherite.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_netherite.png new file mode 100644 index 000000000..b906e2098 Binary files /dev/null and b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_netherite.png differ diff --git a/mods/ITEMS/mcl_beds/textures/portal.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_netherite.png similarity index 50% rename from mods/ITEMS/mcl_beds/textures/portal.png rename to mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_netherite.png index 160ad95f3..3ac1b844a 100644 Binary files a/mods/ITEMS/mcl_beds/textures/portal.png and b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_netherite.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_netherite.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_netherite.png new file mode 100644 index 000000000..7411e0a70 Binary files /dev/null and b/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_netherite.png differ diff --git a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ja.tr b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ja.tr new file mode 100644 index 000000000..4f2892d2c --- /dev/null +++ b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_armor_stand +Armor Stand=アーマースタンド +An armor stand is a decorative object which can display different pieces of armor. Anything which players can wear as armor can also be put on an armor stand.=アーマースタンドは、様々な防具類を展示できる装飾品です。プレイヤーが防具として身につけられるものであれば、何でも置けます。 +Just place an armor item on the armor stand. To take the top piece of armor from the armor stand, select your hand and use the place key on the armor stand.=アーマースタンドに防具アイテムを置くだけです。アーマースタンドから一番上の防具を取るには、素手になって配置キーです。 +Displays pieces of armor=防具を個々に展示 diff --git a/mods/ITEMS/mcl_bamboo/README.md b/mods/ITEMS/mcl_bamboo/README.md new file mode 100644 index 000000000..e330cf202 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/README.md @@ -0,0 +1,19 @@ +mcl_bamboo +========= + +This mod adds simple bamboo nodes to your Mineclone 2 world. + +Code redo for Mineclone 2: Michieal. Original bamboo code by: Krock. + +License for code: GPL3; images / textures: CC-BY-SA. +Images Created by Michieal, except for: +Inventory / wield image: created by RandomLegoBrick#8692 and is CC0. + +Dependencies: mcl_core, mcl_sounds, mcl_tools + +Optional Dependencies = mcl_flowerpots, mclx_stairs, mcl_doors, mcl_signs, mesecons_pressureplates, mcl_fences, mesecons_button + +Special thanks to Nicu for help with the nodebox stalk design. + +Original code's forum topic: +Forum topic: https://forum.minetest.net/viewtopic.php?id=8289 \ No newline at end of file diff --git a/mods/ITEMS/mcl_bamboo/init.lua b/mods/ITEMS/mcl_bamboo/init.lua new file mode 100644 index 000000000..3c7cb58a7 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/init.lua @@ -0,0 +1,841 @@ +-- [bamboo] mod by Krock, modified by SmallJoker, Made for MineClone 2 by Michieal (as mcl_bamboo). +-- Parts of mcl_scaffolding were used. Mcl_scaffolding originally created by Cora; modified for mcl_bamboo by Michieal. +-- Creation date: 12-01-2022 (Dec 1st, 2022) +-- License for everything: GPL3 +-- Bamboo max height: 12-16 + +-- LOCALS +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local bamboo = "mcl_bamboo:bamboo" +local adj_nodes = { + vector.new(0, 0, 1), + vector.new(0, 0, -1), + vector.new(1, 0, 0), + vector.new(-1, 0, 0), +} +local node_sound = mcl_sounds.node_sound_wood_defaults() + +-- CONSTS +local SIDE_SCAFFOLDING = false +local MAKE_STAIRS = true +local DEBUG = false +local USE_END_CAPS = false + +-- Due to door fix #2736, doors are displayed backwards. When this is fixed, set this variable to false. +local BROKEN_DOORS = true + +-- LOCAL FUNCTIONS + +-- Add Groups function, courtesy of Warr1024. +function addgroups(name, ...) + local def = minetest.registered_items[name] or error(name .. " not found") + local groups = {} + for k, v in pairs(def.groups) do + groups[k] = v + end + local function addall(x, ...) + if not x then + return + end + groups[x] = 1 + return addall(...) + end + addall(...) + return minetest.override_item(name, {groups = groups}) +end + +local function create_nodes() + + local bamboo_def = { + description = "Bamboo", + tiles = {"mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo.png"}, + drawtype = "nodebox", + paramtype = "light", + groups = {handy = 1, axey = 1, choppy = 1, flammable = 3}, + sounds = node_sound, + drops = "mcl_bamboo:bamboo", + inventory_image = "mcl_bamboo_bamboo_shoot.png", + wield_image = "mcl_bamboo_bamboo_shoot.png", + _mcl_blast_resistance = 1, + _mcl_hardness = 2, + node_box = { + type = "fixed", + fixed = { + -- {0.1875, -0.5, -0.125, 0.4125, 0.5, 0.0625}, + -- {-0.125, -0.5, 0.125, -0.3125, 0.5, 0.3125}, + -- {-0.25, -0.5, -0.3125, 0, 0.5, -0.125}, + {-0.175, -0.5, -0.195, 0.05, 0.5, 0.030}, + } + }, + + --[[ + Node Box definitions for alternative styles. + {-0.05, -0.5, 0.285, -0.275, 0.5, 0.06}, + {0.25, -0.5, 0.325, 0.025, 0.5, 0.100}, + {-0.125, -0.5, 0.125, -0.3125, 0.5, 0.3125}, + --]] + + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + local node = minetest.get_node(pointed_thing.under) + local pos = pointed_thing.under + if DEBUG then + minetest.log("mcl_bamboo::Node placement data:") + minetest.log(dump(pointed_thing)) + minetest.log(dump(node)) + end + + if DEBUG then + minetest.log("mcl_bamboo::Checking for protected placement of bamboo.") + end + local pname = placer:get_player_name() + if minetest.is_protected(pos, pname) then + minetest.record_protection_violation(pos, pname) + return + end + if DEBUG then + minetest.log("mcl_bamboo::placement of bamboo is not protected.") + end + + -- Use pointed node's on_rightclick function first, if present + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + if DEBUG then + minetest.log("mcl_bamboo::attempting placement of bamboo via targeted node's on_rightclick.") + end + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + + if node.name ~= "mcl_bamboo:bamboo" then + if node.name ~= "mcl_flowerpots:flower_pot" then + if minetest.get_item_group(node.name, "dirt") == 0 then + return itemstack + end + end + end + + if DEBUG then + minetest.log("mcl_bamboo::placing bamboo directly.") + end + return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under))) + + end, + + on_destruct = function(pos) + -- Node destructor; called before removing node. + local new_pos = vector.offset(pos, 0, 1, 0) + local node_above = minetest.get_node(new_pos) + if node_above and node_above.name == "mcl_bamboo:bamboo" then + local sound_params = { + pos = new_pos, + gain = 1.0, -- default + max_hear_distance = 10, -- default, uses a Euclidean metric + } + + minetest.remove_node(new_pos) + minetest.sound_play(node_sound.dug, sound_params, true) + local istack = ItemStack("mcl_bamboo:bamboo") + minetest.add_item(new_pos, istack) + end + end, + } + minetest.register_node("mcl_bamboo:bamboo", bamboo_def) + local bamboo_top = table.copy(bamboo_def) + bamboo_top.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, flammable = 3} + + bamboo_top.on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + local node = minetest.get_node(pointed_thing.under) + local pos = pointed_thing.under + if DEBUG then + minetest.log("mcl_bamboo::Node placement data:") + minetest.log(dump(pointed_thing)) + minetest.log(dump(node)) + end + + if DEBUG then + minetest.log("mcl_bamboo::Checking for protected placement of bamboo.") + end + local pname = placer:get_player_name() + if pname then + if minetest.is_protected(pos, pname) then + minetest.record_protection_violation(pos, pname) + return + end + --not for player use. + if minetest.is_creative_enabled(pname) == false then + itemstack:set_count(0) + return itemstack + end + end + if DEBUG then + minetest.log("mcl_bamboo::placement of bamboo is not protected.") + end + + if node.name ~= "mcl_bamboo:bamboo" then + return itemstack + end + + if DEBUG then + minetest.log("mcl_bamboo::placing bamboo directly.") + end + return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under))) + end, + + minetest.register_node("mcl_bamboo:bamboo_top", bamboo_top) + + local bamboo_block_def = { + description = "Bamboo Block", + tiles = {"mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_block.png"}, + groups = {handy = 1, building_block = 1, axey = 1, flammable = 2, material_wood = 1, bamboo_block = 1, fire_encouragement = 5, fire_flammability = 5}, + sounds = node_sound, + paramtype2 = "facedir", + drops = "mcl_bamboo:bamboo_block", + _mcl_blast_resistance = 3, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_bamboo:bamboo_block_stripped", -- this allows us to use the built in Axe's strip block. + on_place = function(itemstack, placer, pointed_thing) + + local pos = pointed_thing.under + + local pname = placer:get_player_name() + if minetest.is_protected(pos, pname) then + minetest.record_protection_violation(pos, pname) + return + end + + -- Use pointed node's on_rightclick function first, if present + local node = minetest.get_node(pointed_thing.under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + + return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under))) + end, + + } + + -- basic bamboo nodes. + minetest.register_node("mcl_bamboo:bamboo_block", bamboo_block_def) + local bamboo_stripped_block = table.copy(bamboo_block_def) + bamboo_stripped_block.on_rightclick = nil + bamboo_stripped_block.description = S("Stripped Bamboo Block") + bamboo_stripped_block.tiles = {"mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_block_stripped.png"} + minetest.register_node("mcl_bamboo:bamboo_block_stripped", bamboo_stripped_block) + minetest.register_node("mcl_bamboo:bamboo_plank", { + description = S("Bamboo Plank"), + _doc_items_longdesc = S("Bamboo Plank"), + _doc_items_hidden = false, + tiles = {"mcl_bamboo_bamboo_plank.png"}, + stack_max = 64, + is_ground_content = false, + groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 2, + }) + + -- specific bamboo nodes... + if minetest.get_modpath("mcl_flowerpots") then + if DEBUG then + minetest.log("mcl_bamboo::FlowerPot Section Entrance. Modpath exists.") + end + if mcl_flowerpots ~= nil then + -- Flower-potted Bamboo... + local flwr_name = "mcl_bamboo:bamboo" + local flwr_def = {name = "bamboo_plant", + desc = S("Bamboo"), + image = "mcl_bamboo_bamboo_fpm.png", -- use with "register_potted_cube" + -- "mcl_bamboo_flower_pot.png", -- use with "register_potted_flower" + } + + mcl_flowerpots.register_potted_cube(flwr_name, flwr_def) + -- mcl_flowerpots.register_potted_flower(flwr_name, flwr_def) + minetest.register_alias("bamboo_flower_pot", "mcl_flowerpots:flower_pot_bamboo_plant") + end + end + + if minetest.get_modpath("mcl_doors") then + if mcl_doors then + local top_door_tiles = {} + local bot_door_tiles = {} + + if BROKEN_DOORS then + top_door_tiles = {"mcl_bamboo_door_top_alt.png", "mcl_bamboo_door_top.png"} + bot_door_tiles = {"mcl_bamboo_door_bottom_alt.png", "mcl_bamboo_door_bottom.png"} + else + top_door_tiles = {"mcl_bamboo_door_top.png", "mcl_bamboo_door_top.png"} + bot_door_tiles = {"mcl_bamboo_door_bottom.png", "mcl_bamboo_door_bottom.png"} + end + + local name = "mcl_bamboo:bamboo_door" + local def = { + description = S("Bamboo Door."), + inventory_image = "mcl_bamboo_door_wield.png", + wield_image = "mcl_bamboo_door_wield.png", + groups = {handy = 1, axey = 1, material_wood = 1, flammable = -1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = bot_door_tiles, + tiles_top = top_door_tiles, + sounds = mcl_sounds.node_sound_wood_defaults(), + } + + --[[ Registers a door + -- name: The name of the door + -- def: a table with the folowing fields: + -- description + -- inventory_image + -- groups + -- tiles_bottom: the tiles of the bottom part of the door {front, side} + -- tiles_top: the tiles of the bottom part of the door {front, side} + -- If the following fields are not defined the default values are used + -- node_box_bottom + -- node_box_top + -- selection_box_bottom + -- selection_box_top + -- only_placer_can_open: if true only the player who placed the door can + -- open it + -- only_redstone_can_open: if true, the door can only be opened by redstone, + -- not by rightclicking it + --]] + + mcl_doors:register_door(name, def) + + name = "mcl_bamboo:bamboo_trapdoor" + local trap_def = { + description = S("Bamboo Trapdoor."), + inventory_image = "mcl_bamboo_door_complete.png", + groups = {}, + tile_front = "mcl_bamboo_trapdoor_top.png", + tile_side = "mcl_bamboo_trapdoor_side.png", + _doc_items_longdesc = S("Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder."), + _doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."), + wield_image = "mcl_bamboo_trapdoor_wield.png", + inventory_image = "mcl_bamboo_trapdoor_wield.png", + groups = {handy = 1, axey = 1, mesecon_effector_on = 1, material_wood = 1, flammable = -1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), + } + + mcl_doors:register_trapdoor(name, trap_def) + + minetest.register_alias("bamboo_door", "mcl_bamboo:bamboo_door") + minetest.register_alias("bamboo_trapdoor", "mcl_bamboo:bamboo_trapdoor") + end + end + + if MAKE_STAIRS then + if minetest.get_modpath("mcl_stairs") then + if mcl_stairs ~= nil then + mcl_stairs.register_stair_and_slab_simple( + "bamboo_block", + "mcl_bamboo:bamboo_block", + S("Bamboo Stair"), + S("Bamboo Slab"), + S("Double Bamboo Slab") + ) + mcl_stairs.register_stair_and_slab_simple( + "bamboo_stripped", + "mcl_bamboo:bamboo_block_stripped", + S("Stripped Bamboo Stair"), + S("Stripped Bamboo Slab"), + S("Double Stripped Bamboo Slab") + ) + mcl_stairs.register_stair_and_slab_simple( + "bamboo_plank", + "mcl_bamboo:bamboo_plank", + S("Bamboo Plank Stair"), + S("Bamboo Plank Slab"), + S("Double Bamboo Plank Slab") + ) + + -- let's add plank slabs to the wood_slab group. + local bamboo_plank_slab = "mcl_stairs:slab_bamboo_plank" + local node_groups = { + wood_slab = 1, + building_block = 1, + slab = 1, + axey = 1, + handy = 1, + stair = 1, + flammable = 1, + fire_encouragement = 5, + fire_flammability = 20 + } + + minetest.override_item(bamboo_plank_slab, {groups = node_groups}) + end + end + end + + if minetest.get_modpath("mesecons_pressureplates") then + + if mesecon ~= nil and mesecon.register_pressure_plate ~= nil then + -- make sure that pressure plates are installed. + + -- Bamboo Pressure Plate... + + -- Register a Pressure Plate (api command doc.) + -- basename: base name of the pressure plate + -- description: description displayed in the player's inventory + -- textures_off:textures of the pressure plate when inactive + -- textures_on: textures of the pressure plate when active + -- image_w: wield image of the pressure plate + -- image_i: inventory image of the pressure plate + -- recipe: crafting recipe of the pressure plate + -- sounds: sound table (like in minetest.register_node) + -- plusgroups: group memberships (attached_node=1 and not_in_creative_inventory=1 are already used) + -- activated_by: optimal table with elements denoting by which entities this pressure plate is triggered + -- Possible table fields: + -- * player=true: Player + -- * mob=true: Mob + -- By default, is triggered by all entities + -- longdesc: Customized long description for the in-game help (if omitted, a dummy text is used) + + mesecon.register_pressure_plate( + "mcl_bamboo:pressure_plate_bamboo_wood", + S("Bamboo Pressure Plate"), + {"mcl_bamboo_bamboo_plank.png"}, + {"mcl_bamboo_bamboo_plank.png"}, + "mcl_bamboo_bamboo_plank.png", + nil, + {{"mcl_bamboo:bamboo_plank", "mcl_bamboo:bamboo_plank"}}, + mcl_sounds.node_sound_wood_defaults(), + {axey = 1, material_wood = 1}, + nil, + S("A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.")) + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_bamboo:pressure_plate_bamboo_wood_off", + burntime = 15 + }) + minetest.register_alias("bamboo_pressure_plate", "mcl_bamboo:pressure_plate_bamboo_wood") + + end + end + + if minetest.get_modpath("mcl_signs") then + if DEBUG then + minetest.log("mcl_bamboo::Signs Section Entrance. Modpath exists.") + end + if mcl_signs ~= nil then + -- Bamboo Signs... + mcl_signs.register_sign_custom("mcl_bamboo", "_bamboo", "mcl_signs_sign_greyscale.png", + "#f6dc91", "default_sign_greyscale.png", "default_sign_greyscale.png", + "Bamboo Sign") + mcl_signs.register_sign_craft("mcl_bamboo", "mcl_bamboo:bamboo_plank", "_bamboo") + minetest.register_alias("bamboo_sign", "mcl_signs:wall_sign_bamboo") + end + end + + if minetest.get_modpath("mcl_fences") then + if DEBUG then + minetest.log("mcl_bamboo::Fences Section Entrance. Modpath exists.") + end + local id = "bamboo_fence" + local id_gate = "bamboo_fence_gate" + local wood_groups = {handy = 1, axey = 1, flammable = 2, fence_wood = 1, fire_encouragement = 5, fire_flammability = 20} + local wood_connect = {"group:fence_wood"} + + local fence_id = mcl_fences.register_fence(id, S("Bamboo Fence"), "mcl_bamboo_fence_bamboo.png", wood_groups, + 2, 15, wood_connect, node_sound) + local gate_id = mcl_fences.register_fence_gate(id, S("Bamboo Fence Gate"), "mcl_bamboo_fence_gate_bamboo.png", + wood_groups, 2, 15, node_sound) -- note: about missing params.. will use defaults. + + if DEBUG then + minetest.log(dump(fence_id)) + minetest.log(dump(gate_id)) + end + + local craft_wood = "mcl_bamboo:bamboo_plank" + minetest.register_craft({ + output = "mcl_bamboo:" .. id .. " 3", + recipe = { + {craft_wood, "mcl_core:stick", craft_wood}, + {craft_wood, "mcl_core:stick", craft_wood}, + } + }) + minetest.register_craft({ + output = "mcl_bamboo:" .. id_gate, + recipe = { + {"mcl_core:stick", craft_wood, "mcl_core:stick"}, + {"mcl_core:stick", craft_wood, "mcl_core:stick"}, + } + }) + -- 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_alias("bamboo_fence", "mcl_fences:" .. id) + minetest.register_alias("bamboo_fence_gate", "mcl_fences:" .. id_gate) + end + + if minetest.get_modpath("mesecons_button") then + if mesecon ~= nil then + mesecon.register_button( + "bamboo", + S("Bamboo Button"), + "mcl_bamboo_bamboo_plank.png", + "mcl_bamboo:bamboo_plank", + node_sound, + {material_wood = 1, handy = 1, pickaxey = 1, flammable = 3, fire_flammability = 20, fire_encouragement = 5, }, + 1, + false, + S("A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second."), + "mesecons_button_push") + end + end + + minetest.register_node("mcl_bamboo:scaffolding", { + description = S("Scaffolding"), + doc_items_longdesc = S("Scaffolding block used to climb up or out across areas."), + doc_items_hidden = false, + tiles = {"mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_bottom.png"}, + drawtype = "nodebox", + paramtype = "light", + use_texture_alpha = "clip", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.375, -0.5, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, -0.375, 0.5, -0.375}, + {0.375, -0.5, -0.5, 0.5, 0.5, -0.375}, + {0.375, -0.5, 0.375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, 0.375, -0.375, 0.5, 0.5}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + }, + buildable_to = false, + is_ground_content = false, + walkable = false, + climbable = true, + physical = true, + node_placement_prediction = "", + groups = {handy = 1, axey = 1, flammable = 3, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, falling_node = 1, stack_falling = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + on_place = function(itemstack, placer, ptd) + if SIDE_SCAFFOLDING then + -- count param2 up when placing to the sides. Fall when > 6 + local ctrl = placer:get_player_control() + if ctrl and ctrl.sneak then + local pp2 = minetest.get_node(ptd.under).param2 + local np2 = pp2 + 1 + if minetest.get_node(vector.offset(ptd.above, 0, -1, 0)).name == "air" then + minetest.set_node(ptd.above, {name = "mcl_bamboo:scaffolding_horizontal", param2 = np2}) + itemstack:take_item(1) + end + if np2 > 6 then + minetest.check_single_for_falling(ptd.above) + end + return itemstack + end + end + + --place on solid nodes + local node = minetest.get_node(ptd.under) + if itemstack:get_name() ~= node.name then + minetest.set_node(ptd.above, {name = "mcl_bamboo:scaffolding", param2 = 0}) + itemstack:take_item(1) + return itemstack + end + + --build up when placing on existing scaffold + local h = 0 + local pos = ptd.under + repeat + pos.y = pos.y + 1 + h = h + 1 + local cn = minetest.get_node(pos) + if cn.name == "air" then + minetest.set_node(pos, node) + itemstack:take_item(1) + placer:set_wielded_item(itemstack) + return itemstack + end + until cn.name ~= node.name or h >= 32 + end, + on_destruct = function(pos) + -- Node destructor; called before removing node. + local new_pos = vector.offset(pos, 0, 1, 0) + local node_above = minetest.get_node(new_pos) + if node_above and node_above.name == "mcl_bamboo:scaffolding" then + local sound_params = { + pos = new_pos, + gain = 1.0, -- default + max_hear_distance = 10, -- default, uses a Euclidean metric + } + + minetest.remove_node(new_pos) + minetest.sound_play(node_sound.dug, sound_params, true) + local istack = ItemStack("mcl_bamboo:scaffolding") + minetest.add_item(new_pos, istack) + end + end, + + }) + + if SIDE_SCAFFOLDING then + --currently, disabled. + minetest.register_node("mcl_bamboo:scaffolding_horizontal", { + description = S("Scaffolding (horizontal)"), + doc_items_longdesc = S("Scaffolding block used to climb up or out across areas."), + doc_items_hidden = false, + tiles = {"mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_bottom.png"}, + drawtype = "nodebox", + paramtype = "light", + use_texture_alpha = "clip", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.375, -0.5, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, -0.375, 0.5, -0.375}, + {0.375, -0.5, -0.5, 0.5, 0.5, -0.375}, + {0.375, -0.5, 0.375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, 0.375, -0.375, 0.5, 0.5}, + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + }, + groups = {handy = 1, axey = 1, flammable = 3, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, not_in_creative_inventory = 1, falling_node = 1}, + _mcl_after_falling = function(pos) + if minetest.get_node(pos).name == "mcl_bamboo:scaffolding_horizontal" then + if minetest.get_node(vector.offset(pos, 0, 0, 0)).name ~= "mcl_bamboo:scaffolding" then + minetest.remove_node(pos) + minetest.add_item(pos, "mcl_bamboo:scaffolding") + else + minetest.set_node(vector.offset(pos, 0, 1, 0), {name = "mcl_bamboo:scaffolding"}) + end + end + end + }) + end +end + +local function register_craftings() + -- Craftings + + minetest.register_craft({ + output = bamboo .. "_block", + recipe = { + {bamboo, bamboo, bamboo}, + {bamboo, bamboo, bamboo}, + {bamboo, bamboo, bamboo}, + } + }) + + minetest.register_craft({ + output = bamboo .. "_plank 2", + recipe = { + {bamboo .. "_block"}, + } + }) + + minetest.register_craft({ + output = bamboo .. "_plank 2", + recipe = { + {bamboo .. "_block_stripped"}, + } + }) + + minetest.register_craft({ + output = "mcl_core:stick", + recipe = { + {bamboo}, + {bamboo}, + } + }) + + minetest.register_craft({ + output = "mcl_bamboo:scaffolding 6", + recipe = {{bamboo, "mcl_mobitems:string", bamboo}, + {bamboo, "", bamboo}, + {bamboo, "", bamboo}} + }) + + minetest.register_craft({ + output = "mcl_bamboo:bamboo_door 3", + recipe = { + {bamboo .. "_plank", bamboo .. "_plank"}, + {bamboo .. "_plank", bamboo .. "_plank"}, + {bamboo .. "_plank", bamboo .. "_plank"} + } + }) + + minetest.register_craft({ + output = "mcl_bamboo:bamboo_trapdoor 2", + recipe = { + {bamboo .. "_plank", bamboo .. "_plank", bamboo .. "_plank"}, + {bamboo .. "_plank", bamboo .. "_plank", bamboo .. "_plank"}, + } + }) + + -- Fuels + minetest.register_craft({ + type = "fuel", + recipe = "mcl_bamboo:bamboo_door", + burntime = 10, + }) + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_bamboo:bamboo_trapdoor", + burntime = 15, + }) + + minetest.register_craft({ + type = "fuel", + recipe = bamboo, + burntime = 2.5, -- supposed to be 1/2 that of a stick, per minecraft wiki as of JE 1.19.3 + }) + + minetest.register_craft({ + type = "fuel", + recipe = bamboo .. "_block", + burntime = 15, + }) + + minetest.register_craft({ + type = "fuel", + recipe = bamboo .. "_block_stripped", + burntime = 15, + }) + + minetest.register_craft({ + type = "fuel", + recipe = bamboo .. "_plank", + burntime = 7.5, + }) + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_bamboo:scaffolding", + burntime = 20 + }) + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:slab_bamboo_plank", + burntime = 7.5, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:slab_bamboo_block", + burntime = 7.5, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:slab_bamboo_stripped", + burntime = 7.5, + }) + + minetest.register_craft({ + type = "fuel", + recipe = "mesecons_button:button_bamboo_off", + burntime = 5, + }) + +end + +create_nodes() +register_craftings() + +-- MAPGEN +dofile(minetest.get_modpath(modname) .. "/mapgen.lua") + +local BAMBOO_MAX_HEIGHT_CHECK = -16 + +--ABMs +minetest.register_abm({ + nodenames = {"mcl_bamboo:bamboo"}, + interval = 40, + chance = 40, + action = function(pos, node) + local soil_pos = nil + if minetest.get_node_light(pos) < 8 then + return + end + local found_soil = false + for py = -1, BAMBOO_MAX_HEIGHT_CHECK, -1 do + local chk_pos = vector.offset(pos, 0, py, 0) + local name = minetest.get_node(chk_pos).name + if minetest.get_item_group(name, "soil") ~= 0 then + found_soil = true + soil_pos = chk_pos + break + elseif name ~= "mcl_bamboo:bamboo" then + break + end + end + if not found_soil then + return + end + for py = 1, 14 do + local npos = vector.offset(pos, 0, py, 0) + local name = minetest.get_node(npos).name + if vector.distance(soil_pos, npos) >= 15 then + -- stop growing check. + if USE_END_CAPS then + if name == "air" then + minetest.set_node(npos, {name = "mcl_bamboo:bamboo_top"}) + end + end + break + end + if name == "air" then + minetest.set_node(npos, {name = "mcl_bamboo:bamboo"}) + break + elseif name ~= "mcl_bamboo:bamboo" then + break + end + end + end, +}) + +-- Base Aliases. +minetest.register_alias("bamboo_block", "mcl_bamboo:bamboo_block") +minetest.register_alias("bamboo_strippedblock", "mcl_bamboo:bamboo_block_stripped") +minetest.register_alias("bamboo", "mcl_bamboo:bamboo") +minetest.register_alias("bamboo_plank", "mcl_bamboo:bamboo_plank") + +minetest.register_alias("mcl_stairs:stair_bamboo", "mcl_stairs:stair_bamboo_block") +minetest.register_alias("bamboo:bamboo", "mcl_bamboo:bamboo") + +--[[ +todo -- make scaffolds do side scaffold blocks, so that they jut out. +todo -- Also, make those blocks collapse (break) when a nearby connected scaffold breaks. +todo -- add in alternative bamboo styles to simulate random placement. (see commented out nde box definitions. +todo -- make endcap node for bamboo, so that they can be 12-16 nodes high and stop growing. +todo -- mash all of that together so that it drops as one item, and chooses what version to be, in on_place. +todo -- Raft +todo -- Raft with Chest. +todo -- Add in Extras. +todo: Added a new "Mosaic" plank variant that is unique to Bamboo called Bamboo Mosaic + It can be crafted with 1x2 Bamboo Slabs in a vertical strip + You can craft Stair and Slab variants of Bamboo Mosaic + Bamboo Mosaic blocks cannot be used as a crafting ingredient where other wooden blocks are used, but they can be + used as fuel. + +todo -- add in fuel recipes for: + [-] bamboo slab + stripped bamboo slab + [-] bamboo stair + stripped bamboo stair + bamboo plank stair +--]] diff --git a/mods/ITEMS/mcl_bamboo/locale/template.txt b/mods/ITEMS/mcl_bamboo/locale/template.txt new file mode 100644 index 000000000..1701a4a05 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/locale/template.txt @@ -0,0 +1,36 @@ +# textdomain: mcl_bamboo + + +### init.lua ### + +A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.= + +A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.= + +Bamboo= +Bamboo Button= +Bamboo Door.= +Bamboo Fence= +Bamboo Fence Gate= +Bamboo Plank= +Bamboo Plank Slab= +Bamboo Plank Stair= +Bamboo Pressure Plate= +Bamboo Sign= +Bamboo Slab= +Bamboo Stair= +Bamboo Trapdoor.= +Double Bamboo Plank Slab= +Double Bamboo Slab= +Double Stripped Bamboo Slab= +Nether Brick Fence= +Scaffolding= +Scaffolding (horizontal)= +Scaffolding block used to climb up or out across areas.= +Stripped Bamboo Slab= +Stripped Bamboo Stair= + +To open or close the trapdoor, rightclick it or send a redstone signal to it.= + +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.= + diff --git a/mods/ITEMS/mcl_bamboo/mapgen.lua b/mods/ITEMS/mcl_bamboo/mapgen.lua new file mode 100644 index 000000000..8fa61ca54 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/mapgen.lua @@ -0,0 +1,60 @@ +local item_water, item_dirt, item_grass + +item_water = "mcl_core:water_source" +item_dirt = "mcl_core:dirt" +item_grass = "mcl_core:dirt_with_grass" +local function make_bamboo(pos, size) + for y = 0, size - 1 do + local p = {x = pos.x, y = pos.y + y, z = pos.z} + if minetest.get_node(p).name ~= "air" then + return + end + minetest.set_node(p, {name = "mcl_bamboo:bamboo"}) + end +end + +minetest.register_on_generated(function(minp, maxp, seed) + if maxp.y < 2 and minp.y > 0 then + return + end + + local c_grass = minetest.get_content_id(item_grass) + local n_bamboo = minetest.get_perlin(8234, 3, 0.6, 100) + + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local area = VoxelArea:new {MinEdge = emin, MaxEdge = emax} + local data = vm:get_data() + + local rand = PseudoRandom(seed % 8000) + for z = minp.z + 2, maxp.z - 2, 4 do + for x = minp.x + 2, maxp.x - 2, 4 do + local bamboo_amount = math.floor(n_bamboo:get_2d({x = x, y = z}) * 7 - 3) + for i = 1, bamboo_amount do + local p_pos = { + x = rand:next(x - 2, x + 2), + y = 0, + z = rand:next(z - 2, z + 2) + } + + local found = false + local node = -1 + for y = 4, 0, -1 do + p_pos.y = y + node = data[area:index(p_pos.x, p_pos.y, p_pos.z)] + if node == c_grass then + found = true + break + end + end + + if found and + minetest.find_node_near(p_pos, 5, {"group:water", item_water}) then + p_pos.y = p_pos.y + 1 + make_bamboo(p_pos, rand:next(4, 12)) + end + end + end + end +end +) diff --git a/mods/ITEMS/mcl_bamboo/mod.conf b/mods/ITEMS/mcl_bamboo/mod.conf new file mode 100644 index 000000000..d4b93a7d9 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/mod.conf @@ -0,0 +1,4 @@ +name = mcl_bamboo +depends = mcl_core, mcl_sounds, mcl_tools +optional_depends = mcl_flowerpots, mclx_stairs, mcl_doors, mcl_signs, mesecons_pressureplates, mcl_fences, mesecons_button +author = Michieal \ No newline at end of file diff --git a/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_bottom.png b/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_bottom.png new file mode 100644 index 000000000..286cdd381 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_bottom.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_top.png b/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_top.png new file mode 100644 index 000000000..8aba3c825 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_top.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_wield.png b/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_wield.png new file mode 100644 index 000000000..4c666cc6a Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/backup/mcl_bamboo_door_wield.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo.png new file mode 100644 index 000000000..8fd0a8131 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_block.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_block.png new file mode 100644 index 000000000..0bbbd9041 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_block.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_block_stripped.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_block_stripped.png new file mode 100644 index 000000000..b9418a27b Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_block_stripped.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_bottom.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_bottom.png new file mode 100644 index 000000000..96f7c7974 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_bottom.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_fpm.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_fpm.png new file mode 100644 index 000000000..7c3f2b40d Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_fpm.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_plank.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_plank.png new file mode 100644 index 000000000..cd19288f9 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_plank.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_shoot.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_shoot.png new file mode 100644 index 000000000..0d1226cb3 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_bamboo_shoot.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_bottom.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_bottom.png new file mode 100644 index 000000000..286cdd381 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_bottom.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_bottom_alt.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_bottom_alt.png new file mode 100644 index 000000000..00bd07b0b Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_bottom_alt.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_top.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_top.png new file mode 100644 index 000000000..8aba3c825 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_top.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_top_alt.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_top_alt.png new file mode 100644 index 000000000..6aa951c26 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_top_alt.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_wield.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_wield.png new file mode 100644 index 000000000..6d61e8fcf Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_door_wield.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_fence_bamboo.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_fence_bamboo.png new file mode 100644 index 000000000..1193b6b2f Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_fence_bamboo.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_fence_gate_bamboo.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_fence_gate_bamboo.png new file mode 100644 index 000000000..bd51d0683 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_fence_gate_bamboo.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_flower_pot.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_flower_pot.png new file mode 100644 index 000000000..599c17037 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_flower_pot.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_scaffolding_bottom.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_scaffolding_bottom.png new file mode 100644 index 000000000..46cddd712 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_scaffolding_bottom.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_scaffolding_top.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_scaffolding_top.png new file mode 100644 index 000000000..4fb912a4a Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_scaffolding_top.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_side.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_side.png new file mode 100644 index 000000000..444c54bdd Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_side.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_top.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_top.png new file mode 100644 index 000000000..4ea65d465 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_top.png differ diff --git a/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_wield.png b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_wield.png new file mode 100644 index 000000000..1b30fc4c5 Binary files /dev/null and b/mods/ITEMS/mcl_bamboo/textures/mcl_bamboo_trapdoor_wield.png differ diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.ja.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.ja.tr new file mode 100644 index 000000000..7d2fd5b9e --- /dev/null +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.ja.tr @@ -0,0 +1,77 @@ +# textdomain: mcl_banners +White Banner=白色の旗 +White=白色 +Grey Banner=灰色の旗 +Grey=灰色 +Light Grey Banner=薄灰色の旗 +Light Grey=薄灰色 +Black Banner=黒色の旗 +Black=黒色 +Red Banner=赤色の旗 +Red=赤色 +Yellow Banner=黄色の旗 +Yellow=黄色 +Green Banner=緑色の旗 +Green=緑色 +Cyan Banner=青緑色の旗 +Cyan=青緑色 +Blue Banner=青色の旗 +Blue=青色 +Magenta Banner=赤紫色の旗 +Magenta=赤紫色 +Orange Banner=橙色の旗 +Orange=橙色 +Purple Banner=紫色の旗 +Violet=紫色 +Brown Banner=茶色の旗 +Brown=茶色 +Pink Banner=桃色の旗 +Pink=桃色 +Lime Banner=黄緑色の旗 +Lime=黄緑色 +Light Blue Banner=空色の旗 +Light Blue=空色 +Banners are tall colorful decorative blocks. They can be placed on the floor and at walls. Banners can be emblazoned with a variety of patterns using a lot of dye in crafting.=旗は、背の高いカラフルな装飾ブロックです。床や壁に配置できます。クラフトで染料を多用すると、さまざまな模様のエンブレムが作れます。 +Use crafting to draw a pattern on top of the banner. Emblazoned banners can be emblazoned again to combine various patterns. You can draw up to 12 layers on a banner that way. If the banner includes a gradient, only 3 layers are possible.=クラフトによって、旗の面に模様を描きます。エンブレム入りの旗を再度エンブレム化することで、様々なパターンを組み合わせられます。この方法では、旗に最大12枚のレイヤー(重ねられる層)が描けます。グラデーションを含む場合は、3レイヤーまでとなります。 +You can copy the pattern of a banner by placing two banners of the same color in the crafting grid—one needs to be emblazoned, the other one must be clean. Finally, you can use a banner on a cauldron with water to wash off its top-most layer.=同じ色の旗を2枚並べて、旗の模様を写せます。1枚はエンブレム入りで、もう1枚はまっさらな状態であることが必要です。最後に、旗を大釜の上に置いて使うことで、その一番上のレイヤーを水で洗い流す事もできます。 +@1 Bordure=@1 縁取り +@1 Bricks=@1 レンガ模様 +@1 Roundel=@1 円形 +@1 Creeper Charge=@1 クリーパー模様 +@1 Saltire=@1 ✕字 +@1 Bordure Indented=@1 波形の縁取り +@1 Per Bend Inverted=@1 \分割 左下塗り +@1 Per Bend Sinister Inverted=@1 /分割 右下塗り +@1 Per Bend=@1 \分割 右上塗り +@1 Per Bend Sinister=@1 /分割 左上塗り +@1 Flower Charge=@1 花模様 +@1 Gradient=@1 グラデーション 上から塗り +@1 Base Gradient=@1 グラデーション 下から塗り +@1 Per Fess Inverted=@1 上下分割 下塗り +@1 Per Fess=@1 上下分割 上塗り +@1 Per Pale=@1 左右分割 左塗り +@1 Per Pale Inverted=@1 左右分割 右塗り +@1 Thing Charge=@1 何かの模様 +@1 Lozenge=@1 菱形 +@1 Skull Charge=@1 骸骨模様 +@1 Paly=@1 縦縞 +@1 Base Dexter Canton=@1 矩形 左下塗り +@1 Base Sinister Canton=@1 矩形 右下塗り +@1 Chief Dexter Canton=@1 矩形 左上塗り +@1 Chief Sinister Canton=@1 矩形 右上塗り +@1 Cross=@1 十字 +@1 Base=@1 横帯 下端塗り +@1 Pale=@1 縦帯 中央塗り +@1 Bend Sinister=@1 /帯 +@1 Bend=@1 \帯 +@1 Pale Dexter=@1 縦帯 左端塗り +@1 Fess=@1 横帯 中央塗り +@1 Pale Sinister=@1 縦帯 右端塗り +@1 Chief=@1 横帯 上端塗り +@1 Chevron=@1 下に三角形 +@1 Chevron Inverted=@1 上に逆三角形 +@1 Base Indented=@1 下に波形 +@1 Chief Indented=@1 上に波形 +And one additional layer=さらにレイヤーを1枚追加 +And @1 additional layers=さらにレイヤーを@1枚追加 +Paintable decoration=塗装可能な装飾 diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ja.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ja.tr new file mode 100644 index 000000000..3715310c0 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_barrels +Barrel=樽 +Barrels are containers which provide 27 inventory slots.=樽は、27個のインベントリースロットを持つ容器です。 +To access its inventory, rightclick it. When broken, the items will drop out.=インベントリにアクセスするには、右クリックします。壊れると、アイテムがドロップアウトします。 +27 inventory slots=27個のインベントリースロット \ No newline at end of file diff --git a/mods/ITEMS/mcl_beacons/init.lua b/mods/ITEMS/mcl_beacons/init.lua new file mode 100644 index 000000000..4614d5ce1 --- /dev/null +++ b/mods/ITEMS/mcl_beacons/init.lua @@ -0,0 +1,402 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +--[[ +there are strings in meta, which are being used to see which effect will be given to the player(s) +Valid strings: + swiftness + leaping + strenght + regeneration +]]-- + +mcl_beacons = { + blocks ={"mcl_core:diamondblock","mcl_core:ironblock","mcl_core:goldblock","mcl_core:emeraldblock","mcl_nether:netheriteblock"}, + fuel = {"mcl_core:diamond","mcl_core:emerald","mcl_core:iron_ingot","mcl_core:gold_ingot","mcl_nether:netherite_ingot"} +} +local beacon_blocklist = mcl_beacons.blocks +local beacon_fuellist = mcl_beacons.fuel + +local pallete_order = { + glass_cyan = 1, + pane_cyan_flat = 1, + pane_cyan = 1, + + glass_white = 2, + pane_white_flat = 2, + pane_white = 2, + + glass_brown = 3, + pane_brown_flat = 3, + pane_brown = 3, + + glass_blue = 4, + pane_blue_flat = 4, + pane_blue = 4, + + glass_light_blue = 5, + pane_light_blue_flat = 5, + pane_light_blue = 5, + + glass_pink = 6, + pane_pink_flat = 6, + pane_pink = 6, + + glass_purple = 7, + pane_purple_flat = 7, + pane_purple = 7, + + glass_red = 8, + pane_red_flat = 8, + pane_red = 8, + + glass_silver = 9, + pane_silver_flat = 9, + pane_silver = 9, + + glass_gray = 10, + pane_gray_flat = 10, + pane_gray = 10, + + glass_lime = 11, + pane_lime_flat = 11, + pane_lime = 11, + + glass_green = 12, + pane_green_flat = 12, + pane_green = 12, + + glass_orange = 13, + pane_orange_flat = 13, + pane_orange = 13, + + glass_yellow = 14, + pane_yellow_flat = 14, + pane_yellow = 14, + + glass_black = 15, + pane_black_flat = 15, + pane_black = 15, + + glass_magenta = 16, + pane_magenta_flat = 16, + pane_magenta = 16 +} + +local function get_beacon_beam(glass_nodename) + if glass_nodename == "air" then return 0 end + local glass_string = glass_nodename:split(':')[2] + if not pallete_order[glass_string] then return 0 end + return pallete_order[glass_string] +end + +minetest.register_node("mcl_beacons:beacon_beam", { + tiles = {"^[colorize:#b8bab9"}, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.1250, -0.5000, -0.1250, 0.1250, 0.5000, 0.1250} + } + }, + pointable= false, + light_source = 14, + walkable = false, + groups = {not_in_creative_inventory=1}, + _mcl_blast_resistance = 1200, + paramtype2 = "color", + palette = "beacon_beam_palette.png", + palette_index = 0, + buildable_to = true, +}) + +mesecon.register_mvps_stopper("mcl_beacons:beacon_beam") + +local formspec_string= + "size[11,14]".. + + "label[4.5,0.5;"..minetest.formspec_escape(S("Beacon:")).."]".. + "label[0.5,1;"..minetest.formspec_escape(S("Primary Power:")).."]".. + "label[0.5,8.25;"..minetest.formspec_escape( S("Inventory:")).."]".. + + "image[1,1.5;1,1;custom_beacom_symbol_4.png]".. + "image[1,3;1,1;custom_beacom_symbol_3.png]".. + "image[1,4.5;1,1;custom_beacom_symbol_2.png]".. + "image[1,6;1,1;custom_beacom_symbol_1.png]".. + + "image_button[5.2,1.5;1,1;mcl_potions_effect_swift.png;swiftness;]".. + "image_button[5.2,3;1,1;mcl_potions_effect_leaping.png;leaping;]".. + "image_button[5.2,4.5;1,1;mcl_potions_effect_strong.png;strenght;]".. + "image_button[5.2,6;1,1;mcl_potions_effect_regenerating.png;regeneration;]".. + + "item_image[1,7;1,1;mcl_core:diamond]".. + "item_image[2.2,7;1,1;mcl_core:emerald]".. + "item_image[3.4,7;1,1;mcl_core:iron_ingot]".. + "item_image[4.6,7;1,1;mcl_core:gold_ingot]".. + "item_image[5.8,7;1,1;mcl_nether:netherite_ingot]".. + + mcl_formspec.get_itemslot_bg(7.2,7,1,1).. + "list[context;input;7.2,7;1,1;]".. + mcl_formspec.get_itemslot_bg(1,9,9,3).. + "list[current_player;main;1,9;9,3;9]".. + mcl_formspec.get_itemslot_bg(1,12.5,9,1).. + "list[current_player;main;1,12.5;9,1;]" + +local function remove_beacon_beam(pos) + for y=pos.y, pos.y+301 do + local node = minetest.get_node({x=pos.x,y=y,z=pos.z}) + if node.name ~= "air" and node.name ~= "mcl_core:bedrock" and node.name ~= "mcl_core:void" then + if node.name == "ignore" then + minetest.get_voxel_manip():read_from_map({x=pos.x,y=y,z=pos.z}, {x=pos.x,y=y,z=pos.z}) + node = minetest.get_node({x=pos.x,y=y,z=pos.z}) + end + + if node.name == "mcl_beacons:beacon_beam" then + minetest.remove_node({x=pos.x,y=y,z=pos.z}) + end + end + end +end + +local function beacon_blockcheck(pos) + for y_offset = 1,4 do + local block_y = pos.y - y_offset + for block_x = (pos.x-y_offset),(pos.x+y_offset) do + for block_z = (pos.z-y_offset),(pos.z+y_offset) do + local valid_block = false --boolean which stores if block is valid or not + for _, beacon_block in pairs(beacon_blocklist) do + if beacon_block == minetest.get_node({x=block_x,y=block_y,z=block_z}).name and not valid_block then --is the block in the pyramid a valid beacon block + valid_block =true + end + end + if not valid_block then + return y_offset -1 --the last layer is complete, this one is missing or incomplete + end + end + end + if y_offset == 4 then --all checks are done, beacon is maxed + return y_offset + end + end +end + +local function effect_player(effect,pos,power_level, effect_level,player) + local distance = vector.distance(player:get_pos(), pos) + if distance > (power_level+1)*10 then return end + if effect == "swiftness" then + mcl_potions.swiftness_func(player,effect_level,16) + elseif effect == "leaping" then + mcl_potions.leaping_func(player, effect_level, 16) + elseif effect == "strenght" then + mcl_potions.strength_func(player, effect_level, 16) + elseif effect == "regeneration" then + mcl_potions.regeneration_func(player, effect_level, 16) + end +end + +local function globalstep_function(pos,player) + local meta = minetest.get_meta(pos) + local power_level = beacon_blockcheck(pos) + local effect_string = meta:get_string("effect") + if meta:get_int("effect_level") == 2 and power_level < 4 then + return + else + local obstructed = false + for y=pos.y+1, pos.y+100 do + + local nodename = minetest.get_node({x=pos.x,y=y, z = pos.z}).name + if nodename ~= "mcl_core:bedrock" and nodename ~= "air" and nodename ~= "mcl_core:void" and nodename ~= "ignore" then --ignore means not loaded, let's just assume that's air + if nodename ~="mcl_beacons:beacon_beam" then + if minetest.get_item_group(nodename,"glass") == 0 and minetest.get_item_group(nodename,"material_glass") == 0 then + obstructed = true + remove_beacon_beam(pos) + return + end + end + end + end + if obstructed then + return + end + effect_player(effect_string,pos,power_level,meta:get_int("effect_level"),player) + end +end + +minetest.register_node("mcl_beacons:beacon", { + description = S"Beacon", + drawtype = "mesh", + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + mesh = "mcl_beacon.b3d", + tiles = {"beacon_UV.png"}, + use_texture_alpha = "clip", + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("input", 1) + local form = formspec_string + meta:set_string("formspec", form) + end, + on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local input = meta:get_inventory():get_stack("input",1) + if not input:is_empty() then + local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} --from mcl_anvils + minetest.add_item(p, input) + end + remove_beacon_beam(pos) + end, + on_receive_fields = function(pos, formname, fields, sender) + if fields.swiftness or fields.regeneration or fields.leaping or fields.strenght then + local sender_name = sender:get_player_name() + local power_level = beacon_blockcheck(pos) + if minetest.is_protected(pos, sender_name) then + minetest.record_protection_violation(pos, sender_name) + return + elseif power_level == 0 then + return + end + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local input = inv:get_stack("input",1) + + if input:is_empty() then + return + end + + local valid_item = false + + for _, item in ipairs(beacon_fuellist) do + if input:get_name() == item then + valid_item = true + end + end + + if not valid_item then + return + end + + local successful = false + if fields.swiftness then + if power_level == 4 then + minetest.get_meta(pos):set_int("effect_level",2) + else + minetest.get_meta(pos):set_int("effect_level",1) + end + minetest.get_meta(pos):set_string("effect","swiftness") + successful = true + elseif fields.leaping and power_level >= 2 then + if power_level == 4 then + minetest.get_meta(pos):set_int("effect_level",2) + else + minetest.get_meta(pos):set_int("effect_level",1) + end + minetest.get_meta(pos):set_string("effect","leaping") + successful = true + elseif fields.strenght and power_level >= 3 then + if power_level == 4 then + minetest.get_meta(pos):set_int("effect_level",2) + else + minetest.get_meta(pos):set_int("effect_level",1) + end + minetest.get_meta(pos):set_string("effect","strenght") + successful = true + elseif fields.regeneration and power_level == 4 then + minetest.get_meta(pos):set_int("effect_level",2) + minetest.get_meta(pos):set_string("effect","regeneration") + successful = true + end + if successful then + if power_level == 4 then + awards.unlock(sender:get_player_name(),"mcl:maxed_beacon") + end + awards.unlock(sender:get_player_name(),"mcl:beacon") + input:take_item() + inv:set_stack("input",1,input) + + local beam_palette_index = 0 + remove_beacon_beam(pos) + for y = pos.y +1, pos.y + 201 do + local node = minetest.get_node({x=pos.x,y=y,z=pos.z}) + if node.name == ignore then + minetest.get_voxel_manip():read_from_map({x=pos.x,y=y,z=pos.z}, {x=pos.x,y=y,z=pos.z}) + node = minetest.get_node({x=pos.x,y=y,z=pos.z}) + end + + + if minetest.get_item_group(node.name, "glass") ~= 0 or minetest.get_item_group(node.name,"material_glass") ~= 0 then + beam_palette_index = get_beacon_beam(node.name) + end + + if node.name == "air" then + minetest.set_node({x=pos.x,y=y,z=pos.z},{name="mcl_beacons:beacon_beam",param2=beam_palette_index}) + end + end + globalstep_function(pos,sender)--call it once outside the globalstep so the player gets the effect right after selecting it + end + end + end, + light_source = 14, + groups = {handy=1}, + drop = "mcl_beacons:beacon", + sounds = mcl_sounds.node_sound_glass_defaults(), + _mcl_hardness = 3, +}) + +mesecon.register_mvps_stopper("mcl_beacons:beacon") +mcl_wip.register_wip_item("mcl_beacons:beacon") + +function register_beaconblock (itemstring)--API function for other mods + table.insert(beacon_blocklist, itemstring) +end + +function register_beaconfuel(itemstring) + table.insert(beacon_fuellist, itemstring) +end + +local timer = 0 + +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer >= 3 then + for _, player in ipairs(minetest.get_connected_players()) do + local player_pos = player:get_pos() + local pos_list = minetest.find_nodes_in_area({x=player_pos.x-50, y=player_pos.y-50, z=player_pos.z-50}, {x=player_pos.x+50, y=player_pos.y+50, z=player_pos.z+50},"mcl_beacons:beacon") + for _, pos in ipairs(pos_list) do + globalstep_function(pos,player) + end + end + timer = 0 + end +end) + + +minetest.register_abm{ + label="update beacon beam", + nodenames = {"mcl_beacons:beacon_beam"}, + interval = 1, + chance = 1, + action = function(pos) + local node_below = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + local node_above = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + local node_current = minetest.get_node(pos) + + if node_below.name == "air" then + if minetest.get_node({x=pos.x,y=pos.y-2,z=pos.z}).name == "mcl_beacons:beacon" then + minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z},{name="mcl_beacons:beacon_beam",param2=0}) + end + remove_beacon_beam(pos) + elseif node_above.name == "air" or (node_above.name == "mcl_beacons:beacon_beam" and node_above.param2 ~= node_current.param2) then + minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z},{name="mcl_beacons:beacon_beam",param2=node_current.param2}) + elseif minetest.get_item_group(node_above.name, "glass") ~= 0 or minetest.get_item_group(node_above.name,"material_glass") ~= 0 then + minetest.set_node({x=pos.x,y=pos.y+2,z=pos.z},{name="mcl_beacons:beacon_beam",param2=get_beacon_beam(node_above.name)}) + end + end, +} + +minetest.register_craft({ + output = "mcl_beacons:beacon", + recipe = { + {"mcl_core:glass", "mcl_core:glass", "mcl_core:glass"}, + {"mcl_core:glass", "mcl_mobitems:nether_star", "mcl_core:glass"}, + {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"} + } +}) diff --git a/mods/ITEMS/mcl_beacons/locale/mcl_beacons.de.tr b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.de.tr new file mode 100644 index 000000000..d6f194a6c --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.de.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_beacons +Beacon=Leuchtfeuer +Beacon:=Leuchtfeuer: +Primary Power:=Primäre Kraft: +Inventory:=Inventar: diff --git a/mods/ITEMS/mcl_beacons/locale/mcl_beacons.fr.tr b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.fr.tr new file mode 100644 index 000000000..f6290b800 --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.fr.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_beacons +Beacon=Balise +Beacon:=Balise : +Primary Power:=Pouvoir Primaire : +Inventory:=Inventaire : diff --git a/mods/ITEMS/mcl_beacons/locale/mcl_beacons.ja.tr b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.ja.tr new file mode 100644 index 000000000..ad2e79511 --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.ja.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_beacons +Beacon=ビーコン +Beacon:=ビーコン: +Primary Power:=プライマリーパワー: +Inventory:=インベントリ: + diff --git a/mods/ITEMS/mcl_beacons/locale/template.txt b/mods/ITEMS/mcl_beacons/locale/template.txt new file mode 100644 index 000000000..8f604d598 --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/template.txt @@ -0,0 +1,6 @@ +# textdomain: mcl_beacons +Beacon= +Beacon:= +Primary Power:= +Inventory:= + diff --git a/mods/ITEMS/mcl_beacons/mod.conf b/mods/ITEMS/mcl_beacons/mod.conf new file mode 100644 index 000000000..a8b7a467a --- /dev/null +++ b/mods/ITEMS/mcl_beacons/mod.conf @@ -0,0 +1,3 @@ +name = mcl_beacons +author=chmodsayshello +depends=mcl_formspec, mcl_init, mcl_wip, mesecons_mvps, mcl_core, mcl_sounds, awards, mcl_achievements, mcl_mobitems, mcl_nether diff --git a/mods/ITEMS/mcl_beacons/textures/beacon_UV.png b/mods/ITEMS/mcl_beacons/textures/beacon_UV.png new file mode 100644 index 000000000..e65e7b3ed Binary files /dev/null and b/mods/ITEMS/mcl_beacons/textures/beacon_UV.png differ diff --git a/mods/ITEMS/mcl_beacons/textures/beacon_achievement_icon.png b/mods/ITEMS/mcl_beacons/textures/beacon_achievement_icon.png new file mode 100644 index 000000000..dd10a5493 Binary files /dev/null and b/mods/ITEMS/mcl_beacons/textures/beacon_achievement_icon.png differ diff --git a/mods/ITEMS/mcl_beacons/textures/beacon_beam_palette.png b/mods/ITEMS/mcl_beacons/textures/beacon_beam_palette.png new file mode 100644 index 000000000..3cb9ecab6 Binary files /dev/null and b/mods/ITEMS/mcl_beacons/textures/beacon_beam_palette.png differ diff --git a/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_1.png b/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_1.png new file mode 100644 index 000000000..112cfcdb0 Binary files /dev/null and b/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_1.png differ diff --git a/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_2.png b/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_2.png new file mode 100644 index 000000000..efbec3776 Binary files /dev/null and b/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_2.png differ diff --git a/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_3.png b/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_3.png new file mode 100644 index 000000000..975013384 Binary files /dev/null and b/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_3.png differ diff --git a/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_4.png b/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_4.png new file mode 100644 index 000000000..42c471c35 Binary files /dev/null and b/mods/ITEMS/mcl_beacons/textures/custom_beacom_symbol_4.png differ diff --git a/mods/ITEMS/mcl_beacons/textures/mcl_beacon.b3d b/mods/ITEMS/mcl_beacons/textures/mcl_beacon.b3d new file mode 100644 index 000000000..b491586d8 Binary files /dev/null and b/mods/ITEMS/mcl_beacons/textures/mcl_beacon.b3d differ diff --git a/mods/ITEMS/mcl_beds/README.txt b/mods/ITEMS/mcl_beds/README.txt index 34b493702..c0d2549f2 100644 --- a/mods/ITEMS/mcl_beds/README.txt +++ b/mods/ITEMS/mcl_beds/README.txt @@ -15,4 +15,7 @@ This mod adds a bed to Minetest which allows to skip the night. 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. -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 + +Use the mcl_playersSleepingPercentage setting to enable/disable night skipping or set a percentage of how many players need to sleep to skip the night. + +mcl_beds.is_night([ time of day ]) - returns wether it's night with optional argument of a minetest time of day value between 0 and 1 diff --git a/mods/ITEMS/mcl_beds/api.lua b/mods/ITEMS/mcl_beds/api.lua index 86cc079fe..05a95f79d 100644 --- a/mods/ITEMS/mcl_beds/api.lua +++ b/mods/ITEMS/mcl_beds/api.lua @@ -124,32 +124,29 @@ end local default_sounds if minetest.get_modpath("mcl_sounds") then default_sounds = mcl_sounds.node_sound_wood_defaults({ - footstep = { gain = 0.5, name = "mcl_sounds_cloth" }, + footstep = mcl_sounds.node_sound_wool_defaults().footstep, }) end function mcl_beds.register_bed(name, def) - local node_box_bottom, selection_box_bottom, collision_box_bottom - if def.nodebox and def.nodebox.bottom then - node_box_bottom = { type = "fixed", fixed = def.nodebox.bottom } - end - if def.selectionbox and def.selectionbox.bottom then - selection_box_bottom = { type = "fixed", fixed = def.selectionbox.bottom } - end - if def.collisionbox and def.collisionbox.bottom then - collision_box_bottom = { type = "fixed", fixed = def.collisionbox.bottom } - end + local common_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, + } + minetest.register_node(name .. "_bottom", { description = def.description, _tt_help = S("Allows you to sleep"), + _doc_items_longdesc = def._doc_items_longdesc or beddesc, _doc_items_usagehelp = def._doc_items_usagehelp or beduse, _doc_items_create_entry = def._doc_items_create_entry, _doc_items_entry_name = def._doc_items_entry_name, inventory_image = def.inventory_image, wield_image = def.wield_image, - drawtype = "nodebox", - tiles = def.tiles.bottom, + drawtype = "mesh", + mesh = "mcl_beds_bed_bottom.obj", + tiles = def.tiles, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "facedir", @@ -159,11 +156,11 @@ function mcl_beds.register_bed(name, def) _mcl_hardness = 0.2, _mcl_blast_resistance = 1, sounds = def.sounds or default_sounds, - node_box = node_box_bottom, - selection_box = selection_box_bottom, - collision_box = collision_box_bottom, + selection_box = common_box, + collision_box = common_box, drop = "", node_placement_prediction = "", + on_place = function(itemstack, placer, pointed_thing) local under = pointed_thing.under @@ -229,20 +226,12 @@ function mcl_beds.register_bed(name, def) on_rotate = rotate, }) - local node_box_top, selection_box_top, collision_box_top - if def.nodebox and def.nodebox.top then - node_box_top = { type = "fixed", fixed = def.nodebox.top } - end - if def.selectionbox and def.selectionbox.top then - selection_box_top = { type = "fixed", fixed = def.selectionbox.top } - end - if def.collisionbox and def.collisionbox.top then - collision_box_top = { type = "fixed", fixed = def.collisionbox.top } - end + minetest.register_node(name .. "_top", { - drawtype = "nodebox", - tiles = def.tiles.top, + drawtype = "mesh", + mesh = "mcl_beds_bed_top.obj", + tiles = def.tiles, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "facedir", @@ -253,13 +242,14 @@ function mcl_beds.register_bed(name, def) _mcl_blast_resistance = 1, sounds = def.sounds or default_sounds, drop = "", - node_box = node_box_top, - selection_box = selection_box_top, - collision_box = collision_box_top, + selection_box = common_box, + collision_box = common_box, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) mcl_beds.on_rightclick(pos, clicker, true) return itemstack end, + on_rotate = rotate, after_destruct = destruct_bed, }) diff --git a/mods/ITEMS/mcl_beds/beds.lua b/mods/ITEMS/mcl_beds/beds.lua index 5043c85d2..7aa49f8c7 100644 --- a/mods/ITEMS/mcl_beds/beds.lua +++ b/mods/ITEMS/mcl_beds/beds.lua @@ -1,18 +1,6 @@ local S = minetest.get_translator(minetest.get_current_modname()) local mod_doc = minetest.get_modpath("doc") -local nodebox = { - bottom = { - {-0.5, -5/16, -0.5, 0.5, 0.06, 0.5}, - {-0.5, -0.5, -0.5, -5/16, -5/16, -5/16}, - {0.5, -0.5, -0.5, 5/16, -5/16, -5/16}, - }, - top = { - {-0.5, -5/16, -0.5, 0.5, 0.06, 0.5}, - {-0.5, -0.5, 0.5, -5/16, -5/16, 5/16}, - {0.5, -0.5, 0.5, 5/16, -5/16, 5/16}, - }, -} local colors = { -- { ID, decription, wool, dye } @@ -70,36 +58,13 @@ for c=1, #colors do description = colors[c][2], _doc_items_entry_name = entry_name, _doc_items_create_entry = create_entry, - inventory_image = "mcl_beds_bed_"..colorid..".png", - wield_image = "mcl_beds_bed_"..colorid..".png", + inventory_image = "mcl_beds_bed_"..colorid.."_inv.png", + wield_image = "mcl_beds_bed_"..colorid.."_inv.png", + tiles = { - bottom = { - "mcl_beds_bed_top_bottom_"..colorid..".png^[transformR90", - "default_wood.png^mcl_beds_bed_bottom_bottom.png", - "mcl_beds_bed_side_bottom_r_"..colorid..".png", - "mcl_beds_bed_side_bottom_r_"..colorid..".png^[transformfx", - "mcl_beds_bed_side_top_"..colorid..".png", - "mcl_beds_bed_side_bottom_"..colorid..".png" - }, - top = { - "mcl_beds_bed_top_top_"..colorid..".png^[transformR90", - "default_wood.png^mcl_beds_bed_bottom_top.png", - "mcl_beds_bed_side_top_r_"..colorid..".png", - "mcl_beds_bed_side_top_r_"..colorid..".png^[transformfx", - "mcl_beds_bed_side_top_"..colorid..".png", - "mcl_beds_bed_side_bottom_"..colorid..".png" - } - }, - nodebox = nodebox, - selectionbox = { - bottom = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, - top = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, - }, - -- Simplified collision box because Minetest acts weird if we use the nodebox one - collisionbox = { - bottom = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, - top = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, + "mcl_beds_bed_"..colorid..".png" }, + recipe = main_recipe, }) if mod_doc and not is_canonical then diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index c1e76c90a..7199c7b7e 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -10,6 +10,10 @@ local explosions_mod = minetest.get_modpath("mcl_explosions") local spawn_mod = minetest.get_modpath("mcl_spawn") local worlds_mod = minetest.get_modpath("mcl_worlds") +local function mcl_log (message) + mcl_util.mcl_log (message, "[Beds]") +end + -- Helper functions local function get_look_yaw(pos) @@ -58,6 +62,15 @@ local monster_exceptions = { ["mobs_mc:shulker"] = true, } +function mcl_beds.is_night(tod) + -- Values taken from Minecraft Wiki with offset of +600 + if not tod then + tod = minetest.get_timeofday() + end + tod = ( tod * 24000 ) % 24000 + return tod > 18541 or tod < 5458 +end + local function lay_down(player, pos, bed_pos, state, skip) local name = player:get_player_name() local hud_flags = player:hud_get_flags() @@ -76,6 +89,12 @@ local function lay_down(player, pos, bed_pos, state, skip) -- save respawn position when entering bed if spawn_mod and mcl_spawn.set_spawn_pos(player, bed_pos, nil) then minetest.chat_send_player(name, S("New respawn position set!")) + awards.unlock(player:get_player_name(), "mcl:sweetDreams") + end + + + if not mcl_beds.is_night() and (not weather_mod or (mcl_weather.get_weather() ~= "thunder")) then + return false, S("You can only sleep at night or during a thunderstorm.") end -- No sleeping if too far away @@ -157,13 +176,6 @@ local function lay_down(player, pos, bed_pos, state, skip) return false, S("It's too dangerous to sleep here!") end - -- Check day of time and weather - local tod = minetest.get_timeofday() * 24000 - -- Values taken from Minecraft Wiki with offset of +6000 - if tod < 18541 and tod > 5458 and (not weather_mod or (mcl_weather.get_weather() ~= "thunder")) then - return false, S("You can only sleep at night or during a thunderstorm.") - end - mcl_beds.player[name] = 1 mcl_beds.pos[name] = pos mcl_beds.bed_pos[name] = bed_pos2 @@ -250,16 +262,22 @@ end -- Handle environment stuff related to sleeping: skip night and thunderstorm function mcl_beds.sleep() - local storm_skipped = mcl_beds.skip_thunderstorm() - -- Always clear weather - if weather_mod then - mcl_weather.change_weather("none") - end if is_night_skip_enabled() then - if not storm_skipped then + if weather_mod and mcl_weather.get_weather() == "thunder" then + local endtime = (mcl_weather.end_time - minetest.get_gametime()) * 72 / 24000 + minetest.set_timeofday((minetest.get_timeofday() + endtime) %1) + if mcl_beds.is_night() then + mcl_beds.skip_night() + mcl_beds.kick_players() + else + mcl_beds.kick_players() + end + -- Always clear weather + mcl_weather.change_weather("none") + elseif mcl_beds.is_night() then mcl_beds.skip_night() + mcl_beds.kick_players() end - mcl_beds.kick_players() end end @@ -286,14 +304,35 @@ function mcl_beds.skip_night() minetest.set_timeofday(0.25) -- tod = 6000 end -function mcl_beds.skip_thunderstorm() - -- Skip thunderstorm - if weather_mod and mcl_weather.get_weather() == "thunder" then - -- Sleep for a half day (=minimum thunderstorm duration) - minetest.set_timeofday((minetest.get_timeofday() + 0.5) % 1) - return true +function mcl_beds.get_bed_top (pos) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + local bed_top_pos = vector.add(pos, dir) + local bed_top = minetest.get_node(bed_top_pos) + + if bed_top then + --mcl_log("Has a bed top") + else + --mcl_log("No bed top") end - return false + return bed_top_pos +end + +function mcl_beds.get_bed_bottom (pos) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + mcl_log("Dir: " .. tostring(dir)) + local bed_bottom = vector.add(pos, -dir) + mcl_log("bed_bottom: " .. tostring(bed_bottom)) + + local bed_bottom_node = minetest.get_node(bed_bottom) + if bed_bottom_node then + mcl_log("Bed bottom node name:" .. bed_bottom_node.name) + else + mcl_log("Didn't get bed bottom") + end + + return bed_bottom end function mcl_beds.on_rightclick(pos, player, is_top) @@ -325,9 +364,7 @@ function mcl_beds.on_rightclick(pos, player, is_top) if is_top then message = select(2, lay_down(player, ppos, pos)) else - local node = minetest.get_node(pos) - local dir = minetest.facedir_to_dir(node.param2) - local other = vector.add(pos, dir) + local other = mcl_beds.get_bed_top (pos) message = select(2, lay_down(player, ppos, other)) end if message then diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr index d85d48bf1..c9c6de71e 100644 --- a/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr @@ -37,5 +37,7 @@ Players in bed: @1/@2=Joueurs au lit: @1/@2 Note: Night skip is disabled.=Remarque: Le saut de nuit est désactivé. You're sleeping.=Tu dors. You will fall asleep when all players are in bed.=Vous vous endormirez lorsque tous les joueurs seront au lit. +You will fall asleep when @1% of all players are in bed.=Vous vous endormirez lorsque @1% de tous les joueurs seront au lit. You're in bed.=Tu es au lit. Allows you to sleep=Vous permet de dormir +Respawn Anchor=Ancre de réapparition \ No newline at end of file diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.ja.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.ja.tr new file mode 100644 index 000000000..51162b762 --- /dev/null +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.ja.tr @@ -0,0 +1,43 @@ +# textdomain: mcl_beds +Beds allow you to sleep at night and make the time pass faster.=ベッドがあると夜もぐっすり眠れますし、その時間もスキップできます。 +To use a bed, stand close to it and right-click the bed to sleep in it. Sleeping only works when the sun sets, at night or during a thunderstorm. The bed must also be clear of any danger.=ベッドで寝るには、その近くに立って右クリックします。寝られるのは、日没後の夜間、あるいは雷雨の間のみです。また、その周辺に危険がないことも条件です。 +You have heard of other worlds in which a bed would set the start point for your next life. But this world is not one of them.=ベッドが、来世のスタート地点になるような異世界の話を聞いたことがあると思います。しかしここは、そういった世界ではありません。 +By using a bed, you set the starting point for your next life. If you die, you will start your next life at this bed, unless it is obstructed or destroyed.=ベッドを使うことで、来世のスタート地点が設定されます。もし死んだら、このベッドで次の人生を始めることになるでしょう。ベッドが何かに妨げられていたり、壊されていたりしてない限りは。 +In this world, going to bed won't skip the night, but it will skip thunderstorms.=この世界では、ベッドに入っても夜時間をスキップできませんが、雷雨であればスキップできます。 +Sleeping allows you to skip the night. The night is skipped when all players in this world went to sleep. The night is skipped after sleeping for a few seconds. Thunderstorms can be skipped in the same manner.=寝ることで夜をスキップできます。スキップされるのは、このワールドのすべてのプレイヤーが寝たときです。数秒間眠ったのち、夜がスキップされます。雷雨も同様にスキップできます。 +Bed=ベッド +Red Bed=赤色のベッド +Blue Bed=青色のベッド +Cyan Bed=青緑色のベッド +Grey Bed=灰色のベッド +Light Grey Bed=薄灰色のベッド +Black Bed=黒色のベッド +Yellow Bed=黄色のベッド +Green Bed=緑色のベッド +Magenta Bed=赤紫色のベッド +Orange Bed=橙色のベッド +Purple Bed=紫色のベッド +Brown Bed=茶色のベッド +Pink Bed=桃色のベッド +Lime Bed=黄緑色のベッド +Light Blue Bed=空色のベッド +White Bed=白色のベッド +You can't sleep, the bed's too far away!=ベッドが遠くて、寝られません! +This bed is already occupied!=このベッドは、すでに占有されてます! +You have to stop moving before going to bed!=寝るなら、まず動くのを止めてからです! +You can't sleep now, monsters are nearby!=今は眠れません…モンスターが近くにいます! +You can't sleep, the bed is obstructed!=ベッドが妨げられていて、寝られません! +It's too dangerous to sleep here!=ここで寝るのは危険すぎます! +New respawn position set! But you can only sleep at night or during a thunderstorm.=新たなリスポーン地点を設定しました!ただし、眠れるのは夜間か雷雨のときだけです。 +You can only sleep at night or during a thunderstorm.=眠れるのは夜間か雷雨のときだけです。 +New respawn position set!=新たなリスポーン地点を設定しました! +Leave Bed=ベッドから起きる +Abort sleep=睡眠を中断する +Players in bed: @1/@2=就寝中のプレイヤー:@1/@2 +Note: Night skip is disabled.=注:夜間スキップは無効です。 +You're sleeping.=睡眠中… +You will fall asleep when all players are in bed.=プレイヤー全員がベッドに入ると、眠りにつきます。 +You will fall asleep when @1% of all players are in bed.=全プレイヤー(@1%)がベッドに入ると、眠りにつきます。 +You're in bed.=ベッドにいます。 +Allows you to sleep=睡眠を許可する +Respawn Anchor=リスポーンアンカー diff --git a/mods/ITEMS/mcl_beds/models/mcl_beds_bed_bottom.obj b/mods/ITEMS/mcl_beds/models/mcl_beds_bed_bottom.obj new file mode 100644 index 000000000..0e2fe2da9 --- /dev/null +++ b/mods/ITEMS/mcl_beds/models/mcl_beds_bed_bottom.obj @@ -0,0 +1,290 @@ +# Made in Blockbench 3.6.6 +mtllib mcl_beds_bed_bottom.mtl +o cube +v 0.5 0.0625 0.5 +v 0.5 0.0625 -0.5 +v 0.5 -0.3125 0.5 +v 0.5 -0.3125 -0.5 +v -0.5 0.0625 -0.5 +v -0.5 0.0625 0.5 +v -0.5 -0.3125 -0.5 +v -0.5 -0.3125 0.5 +vt 0.09375 0.5625 +vt 0 0.5625 +vt 0.09375 0.3125 +vt 0 0.5625 +vt 0 0.3125 +vt 0.09375 0.3125 +vt 0.34375 0.3125 +vt 0.4375 0.3125 +vt 0.34375 0.5625 +vt 0.4375 0.3125 +vt 0.4375 0.5625 +vt 0.34375 0.5625 +vt 0.34375 0.3125 +vt 0.34375 0.5625 +vt 0.09375 0.3125 +vt 0.34375 0.5625 +vt 0.09375 0.5625 +vt 0.09375 0.3125 +vt 0.43750000000000006 0.5625 +vt 0.43750000000000006 0.3125 +vt 0.6875 0.5625 +vt 0.43750000000000006 0.3125 +vt 0.6875 0.3125 +vt 0.6875 0.5625 +vt 0 0.015625 +vt 0 0 +vt 0.125 0.015625 +vt 0 0 +vt 0.125 0 +vt 0.125 0.015625 +vt 0.59375 0.5625 +vt 0.59375 0.65625 +vt 0.34374999999999994 0.5625 +vt 0.59375 0.65625 +vt 0.34374999999999994 0.65625 +vt 0.34374999999999994 0.5625 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +usemtl m_0 +f 1/1/1 3/2/2 2/3/3 +f 3/4/4 4/5/5 2/6/6 +usemtl m_0 +f 5/7/7 7/8/8 6/9/9 +f 7/10/10 8/11/11 6/12/12 +usemtl m_0 +f 5/13/13 6/14/14 2/15/15 +f 6/16/16 1/17/17 2/18/18 +usemtl m_0 +f 8/19/19 7/20/20 3/21/21 +f 7/22/22 4/23/23 3/24/24 +usemtl m_0 +f 2/31/31 4/32/32 5/33/33 +f 4/34/34 7/35/35 5/36/36 +o cube +v -0.3125 -0.3125 -0.3125 +v -0.3125 -0.3125 -0.5 +v -0.3125 -0.5 -0.3125 +v -0.3125 -0.5 -0.5 +v -0.5 -0.3125 -0.5 +v -0.5 -0.3125 -0.3125 +v -0.5 -0.5 -0.5 +v -0.5 -0.5 -0.3125 +vt 0.921875 0.671875 +vt 0.921875 0.625 +vt 0.96875 0.671875 +vt 0.921875 0.625 +vt 0.96875 0.625 +vt 0.96875 0.671875 +vt 0.828125 0.765625 +vt 0.828125 0.71875 +vt 0.875 0.765625 +vt 0.828125 0.71875 +vt 0.875 0.71875 +vt 0.875 0.765625 +vt 0.046875 0.953125 +vt 0.046875 1 +vt 0 0.953125 +vt 0.046875 1 +vt 0 1 +vt 0 0.953125 +vt 0.921875 0.765625 +vt 0.921875 0.8125 +vt 0.875 0.765625 +vt 0.921875 0.8125 +vt 0.875 0.8125 +vt 0.875 0.765625 +vt 0.875 0.765625 +vt 0.875 0.71875 +vt 0.921875 0.765625 +vt 0.875 0.71875 +vt 0.921875 0.71875 +vt 0.921875 0.765625 +vt 0.78125 0.765625 +vt 0.78125 0.71875 +vt 0.828125 0.765625 +vt 0.78125 0.71875 +vt 0.828125 0.71875 +vt 0.828125 0.765625 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +usemtl m_0 +f 9/37/37 11/38/38 10/39/39 +f 11/40/40 12/41/41 10/42/42 +usemtl m_0 +f 13/43/43 15/44/44 14/45/45 +f 15/46/46 16/47/47 14/48/48 +usemtl m_0 +f 16/55/55 15/56/56 11/57/57 +f 15/58/58 12/59/59 11/60/60 +usemtl m_0 +f 14/61/61 16/62/62 9/63/63 +f 16/64/64 11/65/65 9/66/66 +usemtl m_0 +f 10/67/67 12/68/68 13/69/69 +f 12/70/70 15/71/71 13/72/72 +o cube +v 0.5 -0.3125 -0.3125 +v 0.5 -0.3125 -0.5 +v 0.5 -0.5 -0.3125 +v 0.5 -0.5 -0.5 +v 0.3125 -0.3125 -0.5 +v 0.3125 -0.3125 -0.3125 +v 0.3125 -0.5 -0.5 +v 0.3125 -0.5 -0.3125 +vt 0.78125 0.953125 +vt 0.78125 0.90625 +vt 0.828125 0.953125 +vt 0.78125 0.90625 +vt 0.828125 0.90625 +vt 0.828125 0.953125 +vt 0.875 0.953125 +vt 0.875 0.90625 +vt 0.921875 0.953125 +vt 0.875 0.90625 +vt 0.921875 0.90625 +vt 0.921875 0.953125 +vt 0.046875 0.953125 +vt 0.046875 1 +vt 0 0.953125 +vt 0.046875 1 +vt 0 1 +vt 0 0.953125 +vt 0.921875 0.953125 +vt 0.921875 1 +vt 0.875 0.953125 +vt 0.921875 1 +vt 0.875 1 +vt 0.875 0.953125 +vt 0.921875 0.953125 +vt 0.921875 0.90625 +vt 0.96875 0.953125 +vt 0.921875 0.90625 +vt 0.96875 0.90625 +vt 0.96875 0.953125 +vt 0.828125 0.953125 +vt 0.828125 0.90625 +vt 0.875 0.953125 +vt 0.828125 0.90625 +vt 0.875 0.90625 +vt 0.875 0.953125 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +usemtl m_0 +f 17/73/73 19/74/74 18/75/75 +f 19/76/76 20/77/77 18/78/78 +usemtl m_0 +f 21/79/79 23/80/80 22/81/81 +f 23/82/82 24/83/83 22/84/84 +usemtl m_0 +f 24/91/91 23/92/92 19/93/93 +f 23/94/94 20/95/95 19/96/96 +usemtl m_0 +f 22/97/97 24/98/98 17/99/99 +f 24/100/100 19/101/101 17/102/102 +usemtl m_0 +f 18/103/103 20/104/104 21/105/105 +f 20/106/106 23/107/107 21/108/108 diff --git a/mods/ITEMS/mcl_beds/models/mcl_beds_bed_top.obj b/mods/ITEMS/mcl_beds/models/mcl_beds_bed_top.obj new file mode 100644 index 000000000..9a34a27ec --- /dev/null +++ b/mods/ITEMS/mcl_beds/models/mcl_beds_bed_top.obj @@ -0,0 +1,299 @@ +# Made in Blockbench 3.6.6 +mtllib mcl_beds_bed_top.mtl +o cube +v -0.5000000000000001 0.0625 -0.49999999999999994 +v -0.49999999999999994 0.0625 0.5000000000000001 +v -0.5000000000000001 -0.3125 -0.49999999999999994 +v -0.49999999999999994 -0.3125 0.5000000000000001 +v 0.5000000000000001 0.0625 0.49999999999999994 +v 0.49999999999999994 0.0625 -0.5000000000000001 +v 0.5000000000000001 -0.3125 0.49999999999999994 +v 0.49999999999999994 -0.3125 -0.5000000000000001 +vt 0.34374999999999994 0.65625 +vt 0.43749999999999994 0.65625 +vt 0.34374999999999994 0.90625 +vt 0.43749999999999994 0.65625 +vt 0.43749999999999994 0.90625 +vt 0.34374999999999994 0.90625 +vt 0.09375 0.90625 +vt 0 0.90625 +vt 0.09375 0.65625 +vt 0 0.90625 +vt 0 0.65625 +vt 0.09375 0.65625 +vt 0.09375 0.90625 +vt 0.09375 0.65625 +vt 0.34375 0.90625 +vt 0.09375 0.65625 +vt 0.34375 0.65625 +vt 0.34375 0.90625 +vt 0.6874843749999999 0.6562812499999999 +vt 0.6874843749999999 0.90628125 +vt 0.437484375 0.6562812499999999 +vt 0.6874843749999999 0.90628125 +vt 0.437484375 0.90628125 +vt 0.437484375 0.6562812499999999 +vt 0 1 +vt 0 0.875 +vt 0.1875 1 +vt 0 0.875 +vt 0.1875 0.875 +vt 0.1875 1 +vt 0.34375 0.90625 +vt 0.34375 1 +vt 0.09375 0.90625 +vt 0.34375 1 +vt 0.09375 1 +vt 0.09375 0.90625 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +usemtl m_0 +f 1/1/1 3/2/2 2/3/3 +f 3/4/4 4/5/5 2/6/6 +usemtl m_0 +f 5/7/7 7/8/8 6/9/9 +f 7/10/10 8/11/11 6/12/12 +usemtl m_0 +f 5/13/13 6/14/14 2/15/15 +f 6/16/16 1/17/17 2/18/18 +usemtl m_0 +f 8/19/19 7/20/20 3/21/21 +f 7/22/22 4/23/23 3/24/24 +usemtl none +f 6/25/25 8/26/26 1/27/27 +f 8/28/28 3/29/29 1/30/30 +usemtl m_0 +f 2/31/31 4/32/32 5/33/33 +f 4/34/34 7/35/35 5/36/36 +o cube +v 0.31250000000000006 -0.3125 0.31249999999999994 +v 0.31250000000000006 -0.3125 0.49999999999999994 +v 0.31250000000000006 -0.5 0.31249999999999994 +v 0.31250000000000006 -0.5 0.49999999999999994 +v 0.5000000000000001 -0.3125 0.49999999999999994 +v 0.5 -0.3125 0.31249999999999994 +v 0.5000000000000001 -0.5 0.49999999999999994 +v 0.5 -0.5 0.31249999999999994 +vt 0.921875 0.859375 +vt 0.921875 0.8125 +vt 0.96875 0.859375 +vt 0.921875 0.8125 +vt 0.96875 0.8125 +vt 0.96875 0.859375 +vt 0.828125 0.859375 +vt 0.828125 0.8125 +vt 0.875 0.859375 +vt 0.828125 0.8125 +vt 0.875 0.8125 +vt 0.875 0.859375 +vt 0 1 +vt 0 0.953125 +vt 0.046875 1 +vt 0 0.953125 +vt 0.046875 0.953125 +vt 0.046875 1 +vt 0.875 0.90625 +vt 0.875 0.859375 +vt 0.921875 0.90625 +vt 0.875 0.859375 +vt 0.921875 0.859375 +vt 0.921875 0.90625 +vt 0.875 0.859375 +vt 0.875 0.8125 +vt 0.921875 0.859375 +vt 0.875 0.8125 +vt 0.921875 0.8125 +vt 0.921875 0.859375 +vt 0.78125 0.859375 +vt 0.78125 0.8125 +vt 0.828125 0.859375 +vt 0.78125 0.8125 +vt 0.828125 0.8125 +vt 0.828125 0.859375 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +usemtl m_0 +f 9/37/37 11/38/38 10/39/39 +f 11/40/40 12/41/41 10/42/42 +usemtl m_0 +f 13/43/43 15/44/44 14/45/45 +f 15/46/46 16/47/47 14/48/48 +usemtl none +f 13/49/49 14/50/50 10/51/51 +f 14/52/52 9/53/53 10/54/54 +usemtl m_0 +f 16/55/55 15/56/56 11/57/57 +f 15/58/58 12/59/59 11/60/60 +usemtl m_0 +f 14/61/61 16/62/62 9/63/63 +f 16/64/64 11/65/65 9/66/66 +usemtl m_0 +f 10/67/67 12/68/68 13/69/69 +f 12/70/70 15/71/71 13/72/72 +o cube +v -0.5 -0.3125 0.31249999999999994 +v -0.4999999999999999 -0.3125 0.49999999999999994 +v -0.5 -0.5 0.31249999999999994 +v -0.4999999999999999 -0.5 0.49999999999999994 +v -0.3124999999999999 -0.3125 0.4999999999999999 +v -0.3125 -0.3125 0.3124999999999999 +v -0.3124999999999999 -0.5 0.4999999999999999 +v -0.3125 -0.5 0.3124999999999999 +vt 0.78125 0.671875 +vt 0.78125 0.625 +vt 0.828125 0.671875 +vt 0.78125 0.625 +vt 0.828125 0.625 +vt 0.828125 0.671875 +vt 0.875 0.671875 +vt 0.875 0.625 +vt 0.921875 0.671875 +vt 0.875 0.625 +vt 0.921875 0.625 +vt 0.921875 0.671875 +vt 0 1 +vt 0 0.953125 +vt 0.046875 1 +vt 0 0.953125 +vt 0.046875 0.953125 +vt 0.046875 1 +vt 0.87496875 0.7187656250000001 +vt 0.87496875 0.6719062499999999 +vt 0.921828125 0.7187656250000001 +vt 0.87496875 0.6719062499999999 +vt 0.921828125 0.6719062499999999 +vt 0.921828125 0.7187656250000001 +vt 0.921875 0.671875 +vt 0.921875 0.625 +vt 0.96875 0.671875 +vt 0.921875 0.625 +vt 0.96875 0.625 +vt 0.96875 0.671875 +vt 0.828125 0.671875 +vt 0.828125 0.625 +vt 0.875 0.671875 +vt 0.828125 0.625 +vt 0.875 0.625 +vt 0.875 0.671875 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +usemtl m_0 +f 17/73/73 19/74/74 18/75/75 +f 19/76/76 20/77/77 18/78/78 +usemtl m_0 +f 21/79/79 23/80/80 22/81/81 +f 23/82/82 24/83/83 22/84/84 +usemtl none +f 21/85/85 22/86/86 18/87/87 +f 22/88/88 17/89/89 18/90/90 +usemtl m_0 +f 24/91/91 23/92/92 19/93/93 +f 23/94/94 20/95/95 19/96/96 +usemtl m_0 +f 22/97/97 24/98/98 17/99/99 +f 24/100/100 19/101/101 17/102/102 +usemtl m_0 +f 18/103/103 20/104/104 21/105/105 +f 20/106/106 23/107/107 21/108/108 diff --git a/mods/ITEMS/mcl_beds/respawn_anchor.lua b/mods/ITEMS/mcl_beds/respawn_anchor.lua index 469a8ba4f..f167599c7 100644 --- a/mods/ITEMS/mcl_beds/respawn_anchor.lua +++ b/mods/ITEMS/mcl_beds/respawn_anchor.lua @@ -6,27 +6,6 @@ local S = minetest.get_translator(minetest.get_current_modname()) --local mod_doc = minetest.get_modpath("doc") -> maybe add documentation ? for i=0,4 do - local nodebox_uncharged = { --Reused the composter nodebox, since it is basicly the same - 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, -0.47, 0.5}, -- Bottom level, -0.47 because -0.5 is so low that you can see the texture of the block below through - } - } - - local nodebox_charged = { --Reused the composter nodebox, since it is basicly the same - 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, 0.5, 0.5}, -- Bottom level - } - } local function rightclick(pos, node, player, itemstack) if itemstack.get_name(itemstack) == "mcl_nether:glowstone" and i ~= 4 then @@ -39,6 +18,9 @@ for i=0,4 do elseif string.match(node.name, "mcl_beds:respawn_anchor_charged_") then minetest.chat_send_player(player.get_player_name(player), S"New respawn position set!") mcl_spawn.set_spawn_pos(player, pos, nil) + if i == 4 then + awards.unlock(player:get_player_name(), "mcl:notQuiteNineLives") + end end end @@ -51,8 +33,6 @@ for i=0,4 do "respawn_anchor_bottom.png", "respawn_anchor_side0.png" }, - drawtype = "nodebox", - node_box = nodebox_uncharged, on_rightclick = rightclick, groups = {pickaxey=1, material_stone=1}, _mcl_hardness = 22.5, @@ -64,12 +44,13 @@ for i=0,4 do minetest.register_node("mcl_beds:respawn_anchor_charged_"..i,{ description=S("Respawn Anchor"), tiles = { - "portal.png", + { + image="respawn_anchor_top_on.png^[noalpha", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, "respawn_anchor_bottom.png", "respawn_anchor_side"..i ..".png" }, - drawtype = "nodebox", - node_box = nodebox_charged, on_rightclick = rightclick, groups = {pickaxey=1, material_stone=1, not_in_creative_inventory=1}, _mcl_hardness = 22.5, @@ -88,11 +69,11 @@ for i=0,4 do end -minetest.register_craft({ --TODO: Please change this crafting recipe once crying obsidian is implemented! +minetest.register_craft({ output = "mcl_beds:respawn_anchor", recipe = { - {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}, + {"mcl_core:crying_obsidian", "mcl_core:crying_obsidian", "mcl_core:crying_obsidian"}, {"mcl_nether:glowstone", "mcl_nether:glowstone", "mcl_nether:glowstone"}, - {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"} + {"mcl_core:crying_obsidian", "mcl_core:crying_obsidian", "mcl_core:crying_obsidian"} } }) diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black.png index 6da9b5690..6e79589ce 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black_inv.png new file mode 100644 index 000000000..6da9b5690 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue.png index d6bee0a72..7be362c2c 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue_inv.png new file mode 100644 index 000000000..d6bee0a72 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_bottom.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_bottom.png deleted file mode 100644 index 35c9d59ca..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_top.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_top.png deleted file mode 100644 index 87a0e2abd..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown.png index 5cb0e4196..734ca550e 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown_inv.png new file mode 100644 index 000000000..5cb0e4196 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan.png index 03eec9c70..61a9f9ce4 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan_inv.png new file mode 100644 index 000000000..03eec9c70 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green.png index a2fa4bff5..e70331fcc 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green_inv.png new file mode 100644 index 000000000..a2fa4bff5 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey.png index a53dec153..da586dccf 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey_inv.png new file mode 100644 index 000000000..a53dec153 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue.png index 2e70475ae..ee8d68a03 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue_inv.png new file mode 100644 index 000000000..2e70475ae Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime.png index 9bfb2f9c4..bde92dd81 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime_inv.png new file mode 100644 index 000000000..9bfb2f9c4 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta.png index b223b591e..3d790fb16 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta_inv.png new file mode 100644 index 000000000..b223b591e Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange.png index df14acbf9..6cb474dd9 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange_inv.png new file mode 100644 index 000000000..df14acbf9 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink.png index e0f6365ba..5336fc74a 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink_inv.png new file mode 100644 index 000000000..e0f6365ba Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple.png index abf4c3593..ec5df9693 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple_inv.png new file mode 100644 index 000000000..abf4c3593 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red.png index 20fcd7ca6..d6cfef4c4 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red_inv.png new file mode 100644 index 000000000..20fcd7ca6 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_black.png deleted file mode 100644 index 302bc5b40..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_blue.png deleted file mode 100644 index 0d5b3f412..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_brown.png deleted file mode 100644 index 25983a530..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_cyan.png deleted file mode 100644 index 94614b075..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_green.png deleted file mode 100644 index f4990d58f..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_grey.png deleted file mode 100644 index 40727ca8e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_light_blue.png deleted file mode 100644 index dec15108d..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_lime.png deleted file mode 100644 index fef72ce3b..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_magenta.png deleted file mode 100644 index f1cfdde62..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_orange.png deleted file mode 100644 index e8faf315e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_pink.png deleted file mode 100644 index f536a7960..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_purple.png deleted file mode 100644 index acdf05e87..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_black.png deleted file mode 100644 index 84c1b31f2..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_blue.png deleted file mode 100644 index 474a8f6fb..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_brown.png deleted file mode 100644 index fe1e8e425..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_cyan.png deleted file mode 100644 index 5eacdf654..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_green.png deleted file mode 100644 index d98f4263a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_grey.png deleted file mode 100644 index 02e80ed96..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_light_blue.png deleted file mode 100644 index c3ca6ed88..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_lime.png deleted file mode 100644 index d33985789..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_magenta.png deleted file mode 100644 index 273f0f570..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_orange.png deleted file mode 100644 index 65333f73a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_pink.png deleted file mode 100644 index 5907ad86f..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_purple.png deleted file mode 100644 index 0bfa0a1b7..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_red.png deleted file mode 100644 index b324086d6..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_silver.png deleted file mode 100644 index 0269dc778..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_white.png deleted file mode 100644 index 1ed1e0239..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_yellow.png deleted file mode 100644 index 378b63341..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_red.png deleted file mode 100644 index 103570e14..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_silver.png deleted file mode 100644 index 490298dd1..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_white.png deleted file mode 100644 index 8cdbd2b1d..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_yellow.png deleted file mode 100644 index fed97cded..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_black.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_blue.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_brown.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_cyan.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_green.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_grey.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_light_blue.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_lime.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_magenta.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_orange.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_pink.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_purple.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_black.png deleted file mode 100644 index 5bfa983c3..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_blue.png deleted file mode 100644 index ecf58cd03..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_brown.png deleted file mode 100644 index f1473c36a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_cyan.png deleted file mode 100644 index e3c466ece..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_green.png deleted file mode 100644 index e59981a4c..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_grey.png deleted file mode 100644 index 65052ad02..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_light_blue.png deleted file mode 100644 index 974ac6566..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_lime.png deleted file mode 100644 index 88c367407..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_magenta.png deleted file mode 100644 index 04bdc7ddf..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_orange.png deleted file mode 100644 index 5271b820a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_pink.png deleted file mode 100644 index ca6b5047a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_purple.png deleted file mode 100644 index 740824b38..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_red.png deleted file mode 100644 index 638bdd508..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_silver.png deleted file mode 100644 index b0739432e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_white.png deleted file mode 100644 index 1e536432e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_yellow.png deleted file mode 100644 index a3d9c8c2b..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_red.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_silver.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_white.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_yellow.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver.png index 73de606f2..35691660a 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver_inv.png new file mode 100644 index 000000000..73de606f2 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_black.png deleted file mode 100644 index 046e847a6..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_blue.png deleted file mode 100644 index 0c6affda8..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_brown.png deleted file mode 100644 index cf3eaa405..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_cyan.png deleted file mode 100644 index 2963d1da2..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_gray.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_gray.png deleted file mode 100644 index d1cd63897..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_gray.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_green.png deleted file mode 100644 index 4eda85f33..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_grey.png deleted file mode 100644 index 1aa01946e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_light_blue.png deleted file mode 100644 index 949efb20e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_lime.png deleted file mode 100644 index 14ad57bd1..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_magenta.png deleted file mode 100644 index ce9e6a3de..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_orange.png deleted file mode 100644 index 036ec1169..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_pink.png deleted file mode 100644 index b94a3d989..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_purple.png deleted file mode 100644 index bf053e334..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_red.png deleted file mode 100644 index 77668f201..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_silver.png deleted file mode 100644 index d17a506e3..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_white.png deleted file mode 100644 index ee8105119..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_yellow.png deleted file mode 100644 index d10fb92fa..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_black.png deleted file mode 100644 index 1c2c0abcd..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_blue.png deleted file mode 100644 index ccc492158..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_brown.png deleted file mode 100644 index d18faece8..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_cyan.png deleted file mode 100644 index 0bddf475e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_green.png deleted file mode 100644 index 00b23cd8a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_grey.png deleted file mode 100644 index 1c4903075..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_light_blue.png deleted file mode 100644 index df13cf007..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_lime.png deleted file mode 100644 index b9194be16..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_magenta.png deleted file mode 100644 index 215ef796c..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_orange.png deleted file mode 100644 index 473caf37f..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_pink.png deleted file mode 100644 index ac8b29b9b..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_purple.png deleted file mode 100644 index e29210540..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_red.png deleted file mode 100644 index a418835b5..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_silver.png deleted file mode 100644 index 51609fb0c..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_white.png deleted file mode 100644 index d2dc47702..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_yellow.png deleted file mode 100644 index 10edecc3b..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white.png index f4ed87dac..f4fda7032 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white_inv.png new file mode 100644 index 000000000..f4ed87dac Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow.png index 6705b4a80..4e00bb2e0 100644 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow.png and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow_inv.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow_inv.png new file mode 100644 index 000000000..6705b4a80 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow_inv.png differ diff --git a/mods/ITEMS/mcl_beds/textures/respawn_anchor_top_on.png b/mods/ITEMS/mcl_beds/textures/respawn_anchor_top_on.png new file mode 100644 index 000000000..ce84dedf2 Binary files /dev/null and b/mods/ITEMS/mcl_beds/textures/respawn_anchor_top_on.png differ diff --git a/mods/ITEMS/mcl_beehives/init.lua b/mods/ITEMS/mcl_beehives/init.lua new file mode 100644 index 000000000..100277078 --- /dev/null +++ b/mods/ITEMS/mcl_beehives/init.lua @@ -0,0 +1,236 @@ +------------------ +---- Beehives ---- +------------------ + +-- Variables +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Function to allow harvesting honey and honeycomb from the beehive and bee nest. +local honey_harvest = function(pos, node, player, itemstack, pointed_thing) + local inv = player:get_inventory() + local shears = player:get_wielded_item():get_name() == "mcl_tools:shears" + local bottle = player:get_wielded_item():get_name() == "mcl_potions:glass_bottle" + local beehive = "mcl_beehives:beehive" + local is_creative = minetest.is_creative_enabled(player:get_player_name()) + + if node.name == "mcl_beehives:beehive_5" then + beehive = "mcl_beehives:beehive" + elseif node.name == "mcl_beehives:bee_nest_5" then + beehive = "mcl_beehives:bee_nest" + end + + local campfire_area = vector.offset(pos, 0, -5, 0) + local campfire = minetest.find_nodes_in_area(pos, campfire_area, "group:lit_campfire") + + if bottle then + local honey = "mcl_honey:honey_bottle" + if inv:room_for_item("main", honey) then + node.name = beehive + minetest.set_node(pos, node) + inv:add_item("main", "mcl_honey:honey_bottle") + if not is_creative then + itemstack:take_item() + end + if not campfire[1] then mcl_util.deal_damage(player, 10) else awards.unlock(player:get_player_name(), "mcl:bee_our_guest") end + end + elseif shears then + minetest.add_item(pos, "mcl_honey:honeycomb 3") + node.name = beehive + minetest.set_node(pos, node) + if not campfire[1] then mcl_util.deal_damage(player, 10) end + end +end + +-- Dig Function for Beehives +local dig_hive = function(pos, node, oldmetadata, digger) + local wield_item = digger:get_wielded_item() + local beehive = string.find(node.name, "mcl_beehives:beehive") + local beenest = string.find(node.name, "mcl_beehives:bee_nest") + local silk_touch = mcl_enchanting.has_enchantment(wield_item, "silk_touch") + local is_creative = minetest.is_creative_enabled(digger:get_player_name()) + + if beehive then + minetest.add_item(pos, "mcl_beehives:beehive") + if not silk_touch and not is_creative then mcl_util.deal_damage(digger, 10) end + elseif beenest then + if silk_touch or is_creative then + minetest.add_item(pos, "mcl_beehives:bee_nest") + awards.unlock(digger:get_player_name(), "mcl:total_beelocation") + else + mcl_util.deal_damage(digger, 10) + end + end +end + +-- Beehive +minetest.register_node("mcl_beehives:beehive", { + description = S("Beehive"), + _doc_items_longdesc = S("Artificial bee nest."), + tiles = { + "mcl_beehives_beehive_end.png", "mcl_beehives_beehive_end.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_side.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_front.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 5, material_wood = 1, beehive = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.6, + _mcl_hardness = 0.6, + drop = "", + after_dig_node = dig_hive, +}) + +for l = 1, 4 do + minetest.register_node("mcl_beehives:beehive_" .. l, { + description = S("Beehive"), + _doc_items_longdesc = S("Artificial bee nest."), + tiles = { + "mcl_beehives_beehive_end.png", "mcl_beehives_beehive_end.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_side.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_front.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 5, material_wood = 1, not_in_creative_inventory = 1, beehive = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.6, + _mcl_hardness = 0.6, + drop = "", + after_dig_node = dig_hive, + }) +end + +minetest.register_node("mcl_beehives:beehive_5", { + description = S("Beehive"), + _doc_items_longdesc = S("Artificial bee nest."), + tiles = { + "mcl_beehives_beehive_end.png", "mcl_beehives_beehive_end.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_side.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_front_honey.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 5, material_wood = 1, not_in_creative_inventory = 1, beehive = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.6, + _mcl_hardness = 0.6, + on_rightclick = honey_harvest, + drop = "", + after_dig_node = dig_hive, +}) + +-- Bee Nest +minetest.register_node("mcl_beehives:bee_nest", { + description = S("Bee Nest"), + _doc_items_longdesc = S("A naturally generating block that houses bees and a tasty treat...if you can get it."), + tiles = { + "mcl_beehives_bee_nest_top.png", "mcl_beehives_bee_nest_bottom.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_side.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_front.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 30, bee_nest = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.3, + _mcl_hardness = 0.3, + drop = "", + after_dig_node = dig_hive, +}) + +for i = 1, 4 do + minetest.register_node("mcl_beehives:bee_nest_"..i, { + description = S("Bee Nest"), + _doc_items_longdesc = S("A naturally generating block that houses bees and a tasty treat...if you can get it."), + tiles = { + "mcl_beehives_bee_nest_top.png", "mcl_beehives_bee_nest_bottom.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_side.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_front.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 30, not_in_creative_inventory = 1, bee_nest = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.3, + _mcl_hardness = 0.3, + drop = "", + after_dig_node = dig_hive, + }) +end + +minetest.register_node("mcl_beehives:bee_nest_5", { + description = S("Bee Nest"), + _doc_items_longdesc = S("A naturally generating block that houses bees and a tasty treat...if you can get it."), + tiles = { + "mcl_beehives_bee_nest_top.png", "mcl_beehives_bee_nest_bottom.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_side.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_front_honey.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 30, not_in_creative_inventory = 1, bee_nest = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.3, + _mcl_hardness = 0.3, + on_rightclick = honey_harvest, + drop = "", + after_dig_node = dig_hive, +}) + +-- Crafting +minetest.register_craft({ + output = "mcl_beehives:beehive", + recipe = { + { "group:wood", "group:wood", "group:wood" }, + { "mcl_honey:honeycomb", "mcl_honey:honeycomb", "mcl_honey:honeycomb" }, + { "group:wood", "group:wood", "group:wood" }, + }, +}) + +-- Temporary ABM to update honey levels +minetest.register_abm({ + label = "Update Beehive Honey Levels", + nodenames = "group:beehive", + interval = 500, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local beehive = "mcl_beehives:beehive" + if node.name == beehive then + node.name = beehive.."_1" + minetest.set_node(pos, node) + elseif node.name == beehive.."_1" then + node.name = beehive.."_2" + minetest.set_node(pos, node) + elseif node.name == beehive.."_2" then + node.name = beehive.."_3" + minetest.set_node(pos, node) + elseif node.name == beehive.."_3" then + node.name = beehive.."_4" + minetest.set_node(pos, node) + elseif node.name == beehive.."_4" then + node.name = beehive.."_5" + minetest.set_node(pos, node) + end + end, +}) + +minetest.register_abm({ + label = "Update Bee Nest Honey Levels", + nodenames = "group:bee_nest", + interval = 500, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local beehive = "mcl_beehives:bee_nest" + if node.name == beehive then + node.name = beehive.."_1" + minetest.set_node(pos, node) + elseif node.name == beehive.."_1" then + node.name = beehive.."_2" + minetest.set_node(pos, node) + elseif node.name == beehive.."_2" then + node.name = beehive.."_3" + minetest.set_node(pos, node) + elseif node.name == beehive.."_3" then + node.name = beehive.."_4" + minetest.set_node(pos, node) + elseif node.name == beehive.."_4" then + node.name = beehive.."_5" + minetest.set_node(pos, node) + end + end, +}) diff --git a/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ja.tr b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ja.tr new file mode 100644 index 000000000..a07e44376 --- /dev/null +++ b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ja.tr @@ -0,0 +1,4 @@ +Beehive=養蜂箱 +Artificial bee nest.=人工的なハチの巣です。 +Bee Nest=ハチの巣 +A naturally generating block that houses bees and a tasty treat...if you can get it.=ミツバチの住処となっている自然生成ブロックで、美味しいおやつが収まっています…手に入れられれば。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_beehives/locale/template.txt b/mods/ITEMS/mcl_beehives/locale/template.txt new file mode 100644 index 000000000..135786c7c --- /dev/null +++ b/mods/ITEMS/mcl_beehives/locale/template.txt @@ -0,0 +1,4 @@ +Beehive= +Artificial bee nest.= +Bee Nest= +A naturally generating block that houses bees and a tasty treat...if you can get it.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_beehives/mod.conf b/mods/ITEMS/mcl_beehives/mod.conf new file mode 100644 index 000000000..0a7855bec --- /dev/null +++ b/mods/ITEMS/mcl_beehives/mod.conf @@ -0,0 +1,4 @@ +name = mcl_beehives +author = PrairieWind +description = Adds beehives and bee nests to MineClone 2. +depends = mcl_util, mcl_enchanting diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_bottom.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_bottom.png new file mode 100644 index 000000000..f3ad4a418 Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_bottom.png differ diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_front.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_front.png new file mode 100644 index 000000000..023e79d92 Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_front.png differ diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_front_honey.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_front_honey.png new file mode 100644 index 000000000..d88dd6555 Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_front_honey.png differ diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_side.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_side.png new file mode 100644 index 000000000..9c0de93d7 Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_side.png differ diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_top.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_top.png new file mode 100644 index 000000000..5f80eb98e Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_bee_nest_top.png differ diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_end.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_end.png new file mode 100644 index 000000000..3ee339135 Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_end.png differ diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_front.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_front.png new file mode 100644 index 000000000..94e14d9f9 Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_front.png differ diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_front_honey.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_front_honey.png new file mode 100644 index 000000000..e47a7c776 Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_front_honey.png differ diff --git a/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_side.png b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_side.png new file mode 100644 index 000000000..820acb491 Binary files /dev/null and b/mods/ITEMS/mcl_beehives/textures/mcl_beehives_beehive_side.png differ diff --git a/mods/ITEMS/mcl_bells/init.lua b/mods/ITEMS/mcl_bells/init.lua index b216c6659..32bdfe3d7 100644 --- a/mods/ITEMS/mcl_bells/init.lua +++ b/mods/ITEMS/mcl_bells/init.lua @@ -9,7 +9,7 @@ function mcl_bells.ring_once(pos) local vv=minetest.get_objects_inside_radius(pos,150) for _,o in pairs(vv) do if o.type == "npc" then - mcl_mobs:gopath(o:get_luaentity(),pos,function() end) + o:get_luaentity():gopath(pos,function() end) end end end @@ -35,10 +35,14 @@ minetest.register_node("mcl_bells:bell", { is_ground_content = false, groups = {pickaxey=2, deco_block=1 }, sounds = mcl_sounds.node_sound_metal_defaults(), - _mcl_blast_resistance = 6, + _mcl_blast_resistance = 5, _mcl_hardness = 5, on_rightclick = mcl_bells.ring_once, use_texture_alpha = "clip", + mesecons = {effector = { + action_on = mcl_bells.ring_once, + rules = mesecon.rules.flat, + }}, }) if has_mcl_wip then diff --git a/mods/ITEMS/mcl_bells/locale/mcl_bells.fr.tr b/mods/ITEMS/mcl_bells/locale/mcl_bells.fr.tr index a1f7a075c..cfd5a65c9 100644 --- a/mods/ITEMS/mcl_bells/locale/mcl_bells.fr.tr +++ b/mods/ITEMS/mcl_bells/locale/mcl_bells.fr.tr @@ -1,2 +1,2 @@ -# textdomain: mcl_observers +# textdomain: mcl_bells Bell=Cloche diff --git a/mods/ITEMS/mcl_bells/locale/mcl_bells.ja.tr b/mods/ITEMS/mcl_bells/locale/mcl_bells.ja.tr new file mode 100644 index 000000000..2a8ee56ea --- /dev/null +++ b/mods/ITEMS/mcl_bells/locale/mcl_bells.ja.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_bells +Bell=鐘 diff --git a/mods/ITEMS/mcl_bells/locale/template.txt b/mods/ITEMS/mcl_bells/locale/template.txt index 2f554c2a0..c6475fb83 100644 --- a/mods/ITEMS/mcl_bells/locale/template.txt +++ b/mods/ITEMS/mcl_bells/locale/template.txt @@ -1,2 +1,2 @@ -# textdomain: mcl_observers +# textdomain: mcl_bells Bell= diff --git a/mods/ITEMS/mcl_bells/mod.conf b/mods/ITEMS/mcl_bells/mod.conf index 18e74a7a8..e25b1fc5c 100644 --- a/mods/ITEMS/mcl_bells/mod.conf +++ b/mods/ITEMS/mcl_bells/mod.conf @@ -1,2 +1,3 @@ name = mcl_bells -optional_depends = mcl_wip +depends = mesecons +optional_depends = mcl_wip \ No newline at end of file diff --git a/mods/ITEMS/mcl_blackstone/init.lua b/mods/ITEMS/mcl_blackstone/init.lua index 4909edf2f..cb6ef5493 100644 --- a/mods/ITEMS/mcl_blackstone/init.lua +++ b/mods/ITEMS/mcl_blackstone/init.lua @@ -9,27 +9,28 @@ end --Blocks minetest.register_node("mcl_blackstone:blackstone", { description = S("Blackstone"), - tiles = {"mcl_blackstone.png"}, + tiles = {"mcl_blackstone_top.png", "mcl_blackstone_top.png", "mcl_blackstone_side.png"}, sounds = mcl_sounds.node_sound_stone_defaults(), is_ground_content = false, groups = {cracky = 3, pickaxey=2, material_stone=1, cobble=1}, - _mcl_blast_resistance = 2, - _mcl_hardness = 2, + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, }) minetest.register_node("mcl_blackstone:blackstone_gilded", { description = S("Gilded Blackstone"), - tiles = {"mcl_blackstone.png^mcl_blackstone_gilded_side.png"}, + tiles = {"mcl_blackstone_gilded.png"}, sounds = mcl_sounds.node_sound_stone_defaults(), is_ground_content = false, groups = {cracky = 3, pickaxey=2, material_stone=1, xp=1}, drop = { max_items = 1, items = { - {items = {"mcl_core:gold_nugget 2"},rarity = 5}, - {items = {"mcl_core:gold_nugget 3"},rarity = 5}, - {items = {"mcl_core:gold_nugget 4"},rarity = 5}, - {items = {"mcl_core:gold_nugget 5"},rarity = 5}, - {items = {"mcl_blackstone:blackstone_gilded"}, rarity = 8}, + {items = {"mcl_core:gold_nugget 2"},rarity = 40}, + {items = {"mcl_core:gold_nugget 3"},rarity = 40}, + {items = {"mcl_core:gold_nugget 4"},rarity = 40}, + {items = {"mcl_core:gold_nugget 5"},rarity = 40}, + -- 4x 1 in 40 chance adds up to a 10% chance + {items = {"mcl_blackstone:blackstone_gilded"}, rarity = 1}, } }, _mcl_blast_resistance = 2, @@ -39,22 +40,22 @@ minetest.register_node("mcl_blackstone:blackstone_gilded", { }) minetest.register_node("mcl_blackstone:nether_gold", { description = S("Nether Gold Ore"), - tiles = {"mcl_nether_netherrack.png^mcl_blackstone_gilded_side.png"}, + tiles = {"mcl_nether_gold_ore.png"}, sounds = mcl_sounds.node_sound_stone_defaults(), is_ground_content = false, groups = {cracky = 3, pickaxey=2, material_stone=1, xp=1}, drop = { max_items = 1, items = { - {items = {"mcl_core:gold_nugget 2"},rarity = 5}, - {items = {"mcl_core:gold_nugget 3"},rarity = 5}, - {items = {"mcl_core:gold_nugget 4"},rarity = 5}, + {items = {"mcl_core:gold_nugget 6"},rarity = 5}, {items = {"mcl_core:gold_nugget 5"},rarity = 5}, - {items = {"mcl_blackstone:nether_gold"}, rarity = 8}, + {items = {"mcl_core:gold_nugget 4"},rarity = 5}, + {items = {"mcl_core:gold_nugget 3"},rarity = 5}, + {items = {"mcl_core:gold_nugget 2"},rarity = 1}, } }, - _mcl_blast_resistance = 2, - _mcl_hardness = 2, + _mcl_blast_resistance = 3, + _mcl_hardness = 3, _mcl_silk_touch_drop = true, _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) @@ -67,8 +68,8 @@ minetest.register_node("mcl_blackstone:basalt_polished", { on_rotate = on_rotate, is_ground_content = false, groups = {cracky = 3, pickaxey=2, material_stone=1}, - _mcl_blast_resistance = 2, - _mcl_hardness = 2, + _mcl_blast_resistance = 4.2, + _mcl_hardness = 1.25, }) minetest.register_node("mcl_blackstone:basalt", { description = S("Basalt"), @@ -79,8 +80,17 @@ minetest.register_node("mcl_blackstone:basalt", { on_rotate = on_rotate, is_ground_content = false, groups = {cracky = 3, pickaxey=2, material_stone=1}, - _mcl_blast_resistance = 2, - _mcl_hardness = 2, + _mcl_blast_resistance = 4.2, + _mcl_hardness = 1.25, +}) +minetest.register_node("mcl_blackstone:basalt_smooth", { + description = S("Smooth Basalt"), + tiles = {"mcl_blackstone_basalt_smooth.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + groups = {cracky = 3, pickaxey=2, material_stone=1}, + _mcl_blast_resistance = 4.2, + _mcl_hardness = 1.25, }) minetest.register_node("mcl_blackstone:blackstone_polished", { description = S("Polished Blackstone"), @@ -88,7 +98,7 @@ minetest.register_node("mcl_blackstone:blackstone_polished", { sounds = mcl_sounds.node_sound_stone_defaults(), is_ground_content = false, groups = {cracky = 3, pickaxey=2, material_stone=1}, - _mcl_blast_resistance = 2, + _mcl_blast_resistance = 6, _mcl_hardness = 2, }) minetest.register_node("mcl_blackstone:blackstone_chiseled_polished", { @@ -97,8 +107,8 @@ minetest.register_node("mcl_blackstone:blackstone_chiseled_polished", { sounds = mcl_sounds.node_sound_stone_defaults(), is_ground_content = false, groups = {cracky = 3, pickaxey=2, material_stone=1}, - _mcl_blast_resistance = 2, - _mcl_hardness = 2, + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, }) minetest.register_node("mcl_blackstone:blackstone_brick_polished", { description = S("Polished Blackstone Bricks"), @@ -106,8 +116,8 @@ minetest.register_node("mcl_blackstone:blackstone_brick_polished", { sounds = mcl_sounds.node_sound_stone_defaults(), is_ground_content = false, groups = {cracky = 3, pickaxey=2, material_stone=1}, - _mcl_blast_resistance = 2, - _mcl_hardness = 2, + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, }) minetest.register_node("mcl_blackstone:quartz_brick", { description = S("Quartz Bricks"), @@ -116,8 +126,8 @@ minetest.register_node("mcl_blackstone:quartz_brick", { is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), groups = {cracky = 3, pickaxey=2, material_stone=1}, - _mcl_blast_resistance = 2, - _mcl_hardness = 2, + _mcl_blast_resistance = 0.8, + _mcl_hardness = 0.8, }) minetest.register_node("mcl_blackstone:soul_soil", { description = S("Soul Soil"), @@ -177,21 +187,23 @@ minetest.registered_nodes["mcl_fire:fire"].on_construct=function(pos) end --slabs/stairs -mcl_stairs.register_stair_and_slab_simple("blackstone", "mcl_blackstone:blackstone", "Blackstone Stair", "Blackstone Slab", "Double Blackstone Slab") -mcl_stairs.register_stair_and_slab_simple("blackstone_polished", "mcl_blackstone:blackstone_polished", "Polished Blackstone Stair", "Polished Blackstone Slab", "Polished Double Blackstone Slab") -mcl_stairs.register_stair_and_slab_simple("blackstone_chiseled_polished", "mcl_blackstone:blackstone_chiseled_polished", "Polished Chiseled Blackstone Stair", "Chiseled Polished Blackstone Slab", "Double Polished Chiseled Blackstone Slab") -mcl_stairs.register_stair_and_slab_simple("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished", "Polished Blackstone Brick Stair", "Polished Blackstone Brick Slab", "Double Polished Blackstone Brick Slab") +mcl_stairs.register_stair_and_slab_simple("blackstone", "mcl_blackstone:blackstone", S("Blackstone Stair"), S("Blackstone Slab"), S("Double Blackstone Slab")) +mcl_stairs.register_stair_and_slab_simple("blackstone_polished", "mcl_blackstone:blackstone_polished", S("Polished Blackstone Stair"), S("Polished Blackstone Slab"), S("Polished Double Blackstone Slab")) +mcl_stairs.register_stair_and_slab_simple("blackstone_chiseled_polished", "mcl_blackstone:blackstone_chiseled_polished", S("Chiseled Polished Blackstone Stair"), S("Chiseled Polished Blackstone Slab"), S("Double Chiseled Polished Blackstone Slab")) +mcl_stairs.register_stair_and_slab_simple("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished", S("Polished Blackstone Brick Stair"), S("Polished Blackstone Brick Slab"), S("Double Polished Blackstone Brick Slab")) --Wall mcl_walls.register_wall("mcl_blackstone:wall", S("Blackstone Wall"), "mcl_blackstone:blackstone") --lavacooling + minetest.register_abm({ label = "Lava cooling (basalt)", nodenames = {"group:lava"}, neighbors = {"mcl_core:ice"}, interval = 1, chance = 1, + min_y = mcl_vars.mg_end_min, action = function(pos, node, active_object_count, active_object_count_wider) local water = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, "mcl_core:ice") local lavatype = minetest.registered_nodes[node.name].liquidtype @@ -215,6 +227,7 @@ minetest.register_abm({ neighbors = {"mcl_core:packed_ice"}, interval = 1, chance = 1, + min_y = mcl_vars.mg_end_min, action = function(pos, node, active_object_count, active_object_count_wider) local water = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, "mcl_core:packed_ice") local lavatype = minetest.registered_nodes[node.name].liquidtype @@ -314,36 +327,7 @@ for s=1, #specialstones do end if minetest.settings:get_bool("mcl_generate_ores", true) then - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_blackstone:blackstone_gilded", - wherein = "mcl_blackstone:blackstone", - clust_scarcity = 4775, - clust_num_ores = 2, - clust_size = 2, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_blackstone:nether_gold", - wherein = "mcl_nether:netherrack", - clust_scarcity = 830, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_blackstone:nether_gold", - wherein = "mcl_nether:netherrack", - clust_scarcity = 1660, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - }) + end --]] --soul torch @@ -361,6 +345,7 @@ mcl_torches.register_torch({ groups = {dig_immediate = 3, deco_block = 1}, sounds = mcl_sounds.node_sound_wood_defaults(), particles = true, + flame_type = 2, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr index dee9cd15e..11cf26fcd 100644 --- a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr @@ -1,17 +1,17 @@ # textdomain: mcl_blackstone Blackstone=Schwarzstein Polished Blackstone=Polierter Schwarzstein -Chieseled Polished Blackstone=Gemeißelter polierter Schwarzstein +Chiseled Polished Blackstone=Gemeißelter polierter Schwarzstein Polished Blackstone Bricks=Polierter Schwarzsteinziegel Basalt=Basalt Polished Basalt=Polierter Basalt Blackstone Slab=Schwarzstein Stufe Polished Blackstone Slab=Polierte Schwarzstein Stufe -Chieseled Polished Blackstone Slab=Gemeißelte Polierte Schwarzstein Stufe +Chiseled Polished Blackstone Slab=Gemeißelte Polierte Schwarzstein Stufe Polished Blackstone Brick Slab=Polierte Schwarzsteinziegel Stufe Blackstone Stairs=Schwarzstein Treppe Polished Blackstone Stairs=Polierte Schwarzstein Treppe -Chieseled Polished Blackstone Stairs=Gemeißelte Polierte Schwarzstein Treppe +Chiseled Polished Blackstone Stairs=Gemeißelte Polierte Schwarzstein Treppe Polished Blackstone Brick Stairs=Polierte Schwarzsteinziegel Treppe Quartz Bricks=Quartz Ziegel Soul Torch=Seelenfakel diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.fr.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.fr.tr new file mode 100644 index 000000000..b91769083 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.fr.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_blackstone +Blackstone=Roche noire +Polished Blackstone=Pierre noire +Chiseled Polished Blackstone=Pierre noire sculptée +Polished Blackstone Bricks=Briques de pierre noire +Basalt=Basalte +Polished Basalt=Basalte taillé +Blackstone Slab=Dalle de roche noire +Polished Blackstone Slab=Dalle de pierre noire +Chiseled Polished Blackstone Slab=Dalle de pierre noire sculptée +Polished Blackstone Brick Slab=Dalle de briques de pierre noire +Blackstone Stair=Escalier de roche noire +Polished Blackstone Stair=Escalier de pierre noire +Chiseled Polished Blackstone Stair=Escalier de pierre noire sculptée +Polished Blackstone Brick Stair=Escalier de briques de pierre noire +Quartz Bricks=Briques de quartz +Soul Torch=Torche des âmes +Soul Lantern=Lanterne des âmes +Soul Soil=Terre des âmes +Eternal Soul Fire=Feu éternel des âmes +Gilded Blackstone=Roche noire dorée +Nether Gold Ore=Minerai d'or du Nether +Smooth Basalt=Basalte lisse +Blackstone Wall=Muret de Roche noire +Double Blackstone Slab=Double Dalle de roche noire +Polished Double Blackstone Slab=Double Dalle de pierre noire +Double Chiseled Polished Blackstone Slab=Double Dalle de pierre noire sculptée +Double Polished Blackstone Brick Slab=Double Dalle de briques de pierre noire \ No newline at end of file diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ja.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ja.tr new file mode 100644 index 000000000..b85a4a9d6 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ja.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_blackstone +Blackstone=ブラックストーン +Polished Blackstone=磨かれたブラックストーン +Chiseled Polished Blackstone=模様入りの磨かれたブラックストーン +Polished Blackstone Bricks=磨かれたブラックストーンレンガ +Basalt=玄武岩 +Polished Basalt=磨かれた玄武岩 +Blackstone Slab=ブラックストーンのスラブ +Polished Blackstone Slab=磨かれたブラックストーンのスラブ +Chiseled Polished Blackstone Slab=模様入りの磨かれたブラックストーンのスラブ +Polished Blackstone Brick Slab=磨かれたブラックストーンレンガのスラブ +Blackstone Stair=ブラックストーンの階段 +Polished Blackstone Stair=磨かれたブラックストーンの階段 +Chiseled Polished Blackstone Stair=模様入りの磨かれたブラックストーンの階段 +Polished Blackstone Brick Stair=磨かれたブラックストーンレンガの階段 +Quartz Bricks=クォーツレンガ +Soul Torch=ソウルトーチ +Soul Lantern=ソウルランタン +Soul Soil=ソウルソイル +Eternal Soul Fire=永続的な魂の炎 +Gilded Blackstone=金色のブラックストーン +Nether Gold Ore=ネザー金鉱石 +Smooth Basalt=滑らかな玄武岩 +Blackstone Wall=ブラックストーンの塀 +Double Blackstone Slab=ブラックストーンの2重スラブ +Polished Double Blackstone Slab=磨かれたブラックストーンの2重スラブ +Double Chiseled Polished Blackstone Slab=模様入りの磨かれたブラックストーンの2重スラブ +Double Polished Blackstone Brick Slab=磨かれたブラックストーンレンガの2重スラブ \ No newline at end of file diff --git a/mods/ITEMS/mcl_blackstone/locale/template.txt b/mods/ITEMS/mcl_blackstone/locale/template.txt index 0af51d7d3..ff54c9fb5 100644 --- a/mods/ITEMS/mcl_blackstone/locale/template.txt +++ b/mods/ITEMS/mcl_blackstone/locale/template.txt @@ -1,18 +1,18 @@ # textdomain: mcl_blackstone Blackstone= Polished Blackstone= -Chieseled Polished Blackstone= +Chiseled Polished Blackstone= Polished Blackstone Bricks= Basalt= Polished Basalt= Blackstone Slab= Polished Blackstone Slab= -Chieseled Polished Blackstone Slab= +Chiseled Polished Blackstone Slab= Polished Blackstone Brick Slab= -Blackstone Stairs= -Polished Blackstone Stairs= -Chieseled Polished Blackstone Stairs= -Polished Blackstone Brick Stairs= +Blackstone Stair= +Polished Blackstone Stair= +Chiseled Polished Blackstone Stair= +Polished Blackstone Brick Stair= Quartz Bricks= Soul Torch= Soul Lantern= @@ -21,3 +21,8 @@ Eternal Soul Fire= Gilded Blackstone= Nether Gold Ore= Smooth Basalt= +Blackstone Wall= +Double Blackstone Slab= +Polished Double Blackstone Slab= +Double Chiseled Polished Blackstone Slab= +Double Polished Blackstone Brick Slab= \ No newline at end of file diff --git a/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_1.mts b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_1.mts new file mode 100644 index 000000000..7ec39bacf Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_1.mts differ diff --git a/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_2.mts b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_2.mts new file mode 100644 index 000000000..bafc88993 Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_2.mts differ diff --git a/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_3.mts b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_3.mts new file mode 100644 index 000000000..39809dda9 Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_3.mts differ diff --git a/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_4.mts b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_4.mts new file mode 100644 index 000000000..2acfefe70 Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_4.mts differ diff --git a/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_gilded.png b/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_gilded.png new file mode 100644 index 000000000..82423ca18 Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_gilded.png differ diff --git a/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_gilded_side.png b/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_gilded_side.png deleted file mode 100644 index 1b8b5dee0..000000000 Binary files a/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_gilded_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone.png b/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_side.png similarity index 100% rename from mods/ITEMS/mcl_blackstone/textures/mcl_blackstone.png rename to mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_side.png diff --git a/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_top.png b/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_top.png new file mode 100644 index 000000000..a811c6940 Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/textures/mcl_blackstone_top.png differ diff --git a/mods/ITEMS/mcl_blackstone/textures/soul_torch_on_floor.png b/mods/ITEMS/mcl_blackstone/textures/soul_torch_on_floor.png index 81bdddc07..fc93c82d8 100644 Binary files a/mods/ITEMS/mcl_blackstone/textures/soul_torch_on_floor.png and b/mods/ITEMS/mcl_blackstone/textures/soul_torch_on_floor.png differ diff --git a/mods/ITEMS/mcl_blackstone/textures/soul_torch_on_floor_animated.png b/mods/ITEMS/mcl_blackstone/textures/soul_torch_on_floor_animated.png index b125743b0..2193d4610 100644 Binary files a/mods/ITEMS/mcl_blackstone/textures/soul_torch_on_floor_animated.png and b/mods/ITEMS/mcl_blackstone/textures/soul_torch_on_floor_animated.png differ diff --git a/mods/ITEMS/mcl_blast_furnace/init.lua b/mods/ITEMS/mcl_blast_furnace/init.lua index 168c28bd5..b8bbe001f 100644 --- a/mods/ITEMS/mcl_blast_furnace/init.lua +++ b/mods/ITEMS/mcl_blast_furnace/init.lua @@ -288,7 +288,8 @@ local function blast_furnace_node_timer(pos, elapsed) -- Cooking -- - local el = elapsed_game_time + -- Run the blast_furnace at twice the speed of a furnace. + local el = elapsed_game_time * 2 -- Check if we have cookable content: cookable local aftercooked @@ -329,13 +330,12 @@ local function blast_furnace_node_timer(pos, elapsed) elseif active then el = math.min(el, fuel_totaltime - fuel_time) -- The furnace is currently active and has enough fuel - fuel_time = (fuel_time + el) *2 --multiply speed of fuel consumption to match proper output + fuel_time = fuel_time + el end -- If there is a cookable item then check if it is ready yet if cookable and active then - -- In the src_time variable, the *2 is the multiplication that makes the blast furnace work faster than a normal furnace. - src_time = (src_time + el)*2 + src_time = src_time + el -- Place result in dst list if done if src_time >= cooked.time then inv:add_item("dst", cooked.item) diff --git a/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.fr.tr b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.fr.tr new file mode 100644 index 000000000..16484251a --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.fr.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_blast_furnace +Inventory=Inventaire +Blast Furnace=Haut Fourneau +Smelts ores faster than furnace=fond le minerai plus vite que le fourneau +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Utiliser le livre de recettes pour voir ce que vous pouvez fondre, ce que vous pouvez utiliser comme combustible et combien de temps ça va brûler. +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=Utiliser le fourneau pour ouvrir le menu.\nPlacer le combustible dans la case en bas et le matériau source dans la case du haut.\nLe fourneau utilisera son combustible pour fondre lentement l'objet.\nLe résultat sera placé dans la case de sortie à droite. +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else.=Les hauts fourneaux fondent plusieurs objets, principalement du minerai et des pièces d'armure, en quelque chose d'autre. +Active Blast Furnace=Haut Fourneau Actif diff --git a/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ja.tr b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ja.tr new file mode 100644 index 000000000..2ac902b2d --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_blast_furnace +Inventory=インベントリ +Blast Furnace=溶鉱炉 +Smelts ores faster than furnace=かまどより早く製錬 +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=レシピ本で、何を製錬するか、何を燃料にするか、どのくらい燃えるかを確認します。 +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=炉を使用して溶鉱炉メニューを開きます。\n下側のスロットに炉の燃料を、上側のスロットに原料をセットします。\n炉はゆっくりと燃料を使い、アイテムを製錬します。\n右側の出力スロットに製錬結果が置かれます。 +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else.=溶鉱炉は燃料を使用して、いくつかのアイテム(主に鉱石や防具など)を製錬し、別のものに変えます。 +Active Blast Furnace=溶鉱炉 稼動中 \ No newline at end of file diff --git a/mods/ITEMS/mcl_blast_furnace/locale/template.txt b/mods/ITEMS/mcl_blast_furnace/locale/template.txt new file mode 100644 index 000000000..1c30844d8 --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/template.txt @@ -0,0 +1,8 @@ +# textdomain: mcl_blast_furnace +Inventory= +Blast Furnace= +Smelts ores faster than furnace= +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.= +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.= +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else.= +Active Blast Furnace= \ No newline at end of file diff --git a/mods/ITEMS/mcl_books/init.lua b/mods/ITEMS/mcl_books/init.lua index 446be8cd6..af84feb66 100644 --- a/mods/ITEMS/mcl_books/init.lua +++ b/mods/ITEMS/mcl_books/init.lua @@ -1,8 +1,12 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize local max_text_length = 4500 -- TODO: Increase to 12800 when scroll bar was added to written book local max_title_length = 64 +local bookshelf_inv = minetest.settings:get_bool("mcl_bookshelf_inventories",true) + local header = "" if minetest.get_modpath("mcl_init") then header = "no_prepend[]" .. mcl_vars.gui_nonbg .. mcl_vars.gui_bg_color .. @@ -331,6 +335,76 @@ if minetest.get_modpath("mcl_sounds") then wood_sound = mcl_sounds.node_sound_wood_defaults() end +-- Bookshelf GUI +local drop_content = mcl_util.drop_items_from_meta_container("main") + +local function on_blast(pos) + local node = minetest.get_node(pos) + drop_content(pos, node) + minetest.remove_node(pos) +end + +-- Simple protection checking functions +local function protection_check_move(pos, from_list, from_index, to_list, to_index, count, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return count + end +end + +local function protection_check_put_take(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + elseif minetest.get_item_group(stack:get_name(), "book") ~= 0 or stack:get_name() == "mcl_enchanting:book_enchanted" then + return stack:get_count() + else + return 0 + end +end + +local function bookshelf_gui(pos, node, clicker) + if not bookshelf_inv then return end + local name = minetest.get_meta(pos):get_string("name") + + if name == "" then + name = S("Bookshelf") + end + + local playername = clicker:get_player_name() + + minetest.show_formspec(playername, + "mcl_books:bookshelf_"..pos.x.."_"..pos.y.."_"..pos.z, + table.concat({ + "size[9,8.75]", + "label[0,0;"..F(C("#313131", name)).."]", + "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]", + mcl_formspec.get_itemslot_bg(0, 0.5, 9, 3), + "label[0,4.0;"..F(C("#313131", S("Inventory"))).."]", + "list[current_player;main;0,4.5;9,3;9]", + mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3), + "list[current_player;main;0,7.74;9,1;]", + mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1), + "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]", + "listring[current_player;main]", + }) + ) +end + +local function close_forms(pos) + local players = minetest.get_connected_players() + local formname = "mcl_books:bookshelf_"..pos.x.."_"..pos.y.."_"..pos.z + for p = 1, #players do + if vector.distance(players[p]:get_pos(), pos) <= 30 then + minetest.close_formspec(players[p]:get_player_name(), formname) + end + end +end + -- Bookshelf minetest.register_node("mcl_books:bookshelf", { description = S("Bookshelf"), @@ -340,13 +414,40 @@ minetest.register_node("mcl_books:bookshelf", { is_ground_content = false, groups = { handy=1, axey=1, deco_block=1, material_wood=1, - flammable=3, fire_encouragement=30, fire_flammability=20 + flammable=3, fire_encouragement=30, fire_flammability=20, container=1 }, drop = "mcl_books:book 3", sounds = wood_sound, _mcl_blast_resistance = 1.5, _mcl_hardness = 1.5, _mcl_silk_touch_drop = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 9*3) + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) + end, + allow_metadata_inventory_move = protection_check_move, + allow_metadata_inventory_take = protection_check_put_take, + allow_metadata_inventory_put = protection_check_put_take, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name().. + " moves stuff in bookshelf at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " moves stuff to bookshelf at "..minetest.pos_to_string(pos)) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name().. + " takes stuff from bookshelf at "..minetest.pos_to_string(pos)) + end, + after_dig_node = drop_content, + on_blast = on_blast, + on_rightclick = bookshelf_gui, + on_destruct = close_forms, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.fr.tr b/mods/ITEMS/mcl_books/locale/mcl_books.fr.tr index 7024cf5d0..4006d033c 100644 --- a/mods/ITEMS/mcl_books/locale/mcl_books.fr.tr +++ b/mods/ITEMS/mcl_books/locale/mcl_books.fr.tr @@ -1,6 +1,6 @@ # textdomain: mcl_books Book=Livre -Books are used to make bookshelves and book and quills.=Les livres sont utilisés pour fabriquer des étagères et des livres et des plumes. +Books are used to make bookshelves and book and quills.=Les livres sont utilisés pour fabriquer des étagères et des livres avec unes plumes. “@1”="@1" Copy of “@1”=Copie de "@1" Copy of Copy of “@1”=Copie de Copie de "@1" @@ -9,8 +9,8 @@ by @1=ar @1 # as in “to sign a book” Sign=Signer Done=Terminé -This item can be used to write down some notes.=Cet élément peut être utilisé pour écrire certaines notes. -Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.=Tenez-le dans la main, puis faites un clic droit pour lire les notes actuelles et modifiez-les ensuite. Vous pouvez modifier le texte aussi souvent que vous le souhaitez. Vous pouvez également signer le livre qui le transforme en livre écrit que vous pouvez empiler, mais il ne peut plus être édité. +This item can be used to write down some notes.=Cet élément peut être utilisé pour prendre quelques notes. +Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.=Tenez-le dans la main, puis faites un clic droit pour lire les notes actuelles et modifiez-les ensuite. Vous pouvez modifier le texte aussi souvent que vous le souhaitez. Vous pouvez également signer le livre ce qui le transforme en livre écrit que vous pouvez empiler, mais il ne peut plus être édité. A book can hold up to 4500 characters. The title length is limited to 64 characters.=Un livre peut contenir jusqu'à 4500 caractères. La longueur du titre est limitée à 64 caractères. Enter book title:=Entrez le titre du livre: by @1=par @1 @@ -21,8 +21,8 @@ Nameless Book=Livre sans nom Written Book=Livre écrit Written books contain some text written by someone. They can be read and copied, but not edited.=Les livres écrits contiennent du texte écrit par quelqu'un. Ils peuvent être lus et copiés, mais pas modifiés. Hold it in your hand, then rightclick to read the book.=Tenez-le dans votre main, puis faites un clic droit pour lire le livre. -To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied.=Pour copier le texte du livre écrit, placez-le dans la grille d'artisanat avec un livre et une plume (ou plusieurs de ceux-ci) et de l'artisanat. Le livre écrit ne sera pas consommé. Les copies de copies ne peuvent pas être copiées. +To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied.=Pour copier le texte du livre écrit, placez-le dans la grille d'artisanat avec un livre et une plume (ou plusieurs) et récupérez le résultat. Le livre copié ne sera pas consommé. Les copies de copies ne peuvent pas être copiées. Bookshelf=Bibliothèque Bookshelves are used for decoration.=Les bibliothèques sont utilisées pour la décoration. Book and Quill=Livre et Plume -Write down some notes=Notez quelques notes +Write down some notes=Prenez quelques notes diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.ja.tr b/mods/ITEMS/mcl_books/locale/mcl_books.ja.tr new file mode 100644 index 000000000..8f3755c42 --- /dev/null +++ b/mods/ITEMS/mcl_books/locale/mcl_books.ja.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_books +Book=本 +Books are used to make bookshelves and book and quills.=本は、本棚や本と羽根ペンの材料として使われています。 +“@1”=“@1” +Copy of “@1”=“@1”のコピー +Copy of Copy of “@1”=“@1”のコピーのコピー +Tattered Book=ボロボロの本 +by @1=@1 著 +# as in “to sign a book” +Sign=署名 +Done=完了 +This item can be used to write down some notes.=このアイテムは、ちょっとしたメモを書き留めるために使えます。 +Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.=手に持って右クリックすると、現在のメモを読み込んでから編集できます。編集は何度でも可能です。また、署名をすることで記入済みの本となり、スタックが可能になりますが、編集はできなくなります。 +A book can hold up to 4500 characters. The title length is limited to 64 characters.=1冊に4500文字まで収録可能です。タイトルの長さは64文字までです。 +Enter book title:=本の題名を入力: +by @1=@1 著 +Note: The book will no longer be editable after signing=注:署名後の本は編集不能 +Sign and Close=署名して閉じる +Cancel=キャンセル +Nameless Book=名もなき本 +Written Book=記入済みの本 +Written books contain some text written by someone. They can be read and copied, but not edited.=記入済みの本には、誰かが書いたテキストが含まれています。読んだりコピーしたりはできますが、編集は不能です。 +Hold it in your hand, then rightclick to read the book.=手に持ち、右クリックすると本が読めます。 +To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied.=記入済みの本のテキストをコピーするには、本と羽根ペン(またはそれらの複数)と一緒にクラフトグリッドに置き、クラフトします。記入済みの本は消費されません。「コピーのコピー」をコピーすることはできません。 +Bookshelf=本棚 +Bookshelves are used for decoration.=本棚は飾りとして使用します。 +Book and Quill=本と羽根ペン +Write down some notes=メモを書く diff --git a/mods/ITEMS/mcl_books/mod.conf b/mods/ITEMS/mcl_books/mod.conf index cea9a5dd8..cfa1f7622 100644 --- a/mods/ITEMS/mcl_books/mod.conf +++ b/mods/ITEMS/mcl_books/mod.conf @@ -1,4 +1,5 @@ name = mcl_books author = celeron55 description = Books mod for MCL2 +depends = mcl_util, mcl_formspec optional_depends = mcl_init, mcl_core, mcl_sounds, mcl_mobitems, mcl_dye, mcl_colors diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index 1816184bb..2181d7b98 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -1,6 +1,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) local mod_target = minetest.get_modpath("mcl_target") +local enable_pvp = minetest.settings:get_bool("enable_pvp") local math = math local vector = vector @@ -114,6 +115,8 @@ end function ARROW_ENTITY.on_step(self, dtime) mcl_burning.tick(self.object, dtime, self) + -- mcl_burning.tick may remove object immediately + if not self.object:get_pos() then return end self._time_in_air = self._time_in_air + .001 @@ -168,27 +171,24 @@ function ARROW_ENTITY.on_step(self, dtime) if self._damage >= 9 and self._in_player == false then minetest.add_particlespawner({ - amount = 1, - time = .001, - minpos = pos, - maxpos = pos, + amount = 20, + time = .2, + minpos = vector.new(0,0,0), + maxpos = vector.new(0,0,0), minvel = vector.new(-0.1,-0.1,-0.1), maxvel = vector.new(0.1,0.1,0.1), minexptime = 0.5, maxexptime = 0.5, minsize = 2, maxsize = 2, + attached = self.object, collisiondetection = false, vertical = false, texture = "mobs_mc_arrow_particle.png", glow = 1, }) end - -- 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 @@ -196,32 +196,33 @@ function ARROW_ENTITY.on_step(self, dtime) self._deflection_cooloff = self._deflection_cooloff - dtime end - -- Iterate through all objects and remember the closest attackable object - for k, obj in pairs(objs) do - local ok = false - -- Arrows can only damage players and mobs - if obj:is_player() then - ok = true - elseif obj:get_luaentity() then - if (obj:get_luaentity().is_mob or obj:get_luaentity()._hittable_by_projectile) then + local arrow_dir = self.object:get_velocity() + --create a raycast from the arrow based on the velocity of the arrow to deal with lag + local raycast = minetest.raycast(pos, vector.add(pos, vector.multiply(arrow_dir, 0.1)), true, false) + for hitpoint in raycast do + if hitpoint.type == "object" then + -- find the closest object that is in the way of the arrow + local ok = false + if hitpoint.ref:is_player() and enable_pvp then ok = true + elseif not hitpoint.ref:is_player() and hitpoint.ref:get_luaentity() then + if (hitpoint.ref:get_luaentity().is_mob or hitpoint.ref:get_luaentity()._hittable_by_projectile) then + ok = true + end end - end - - if ok then - local dist = vector.distance(pos, obj:get_pos()) - if not closest_object or not closest_distance then - closest_object = obj - closest_distance = dist - elseif dist < closest_distance then - closest_object = obj - closest_distance = dist + if ok then + local dist = vector.distance(hitpoint.ref:get_pos(), pos) + if not closest_object or not closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + elseif dist < closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + end end end end - -- If an attackable object was found, we will damage the closest one only - if closest_object then local obj = closest_object local is_player = obj:is_player() @@ -249,7 +250,7 @@ function ARROW_ENTITY.on_step(self, dtime) -- Punch target object but avoid hurting enderman. if not lua or lua.name ~= "mobs_mc:enderman" then if not self._in_player then - damage_particles(self.object:get_pos(), self._is_critical) + damage_particles(vector.add(pos, vector.multiply(self.object:get_velocity(), 0.1)), self._is_critical) end if mcl_burning.is_burning(self.object) then mcl_burning.set_on_fire(obj, 5) @@ -304,6 +305,8 @@ function ARROW_ENTITY.on_step(self, dtime) minetest.after(150, function() self.object:remove() end) + else + self.object:remove() end end end diff --git a/mods/ITEMS/mcl_bows/crossbow.lua b/mods/ITEMS/mcl_bows/crossbow.lua index b211f6b39..73d3f96f4 100644 --- a/mods/ITEMS/mcl_bows/crossbow.lua +++ b/mods/ITEMS/mcl_bows/crossbow.lua @@ -118,9 +118,9 @@ end 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".. + _doc_items_longdesc = S("Crossbows are ranged weapons to shoot arrows at your foes.").."\n".. S("The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead."), - _doc_items_usagehelp = S("To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot."), + _doc_items_usagehelp = S("To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot."), _doc_items_durability = BOW_DURABILITY, inventory_image = "mcl_bows_crossbow.png", wield_scale = mcl_vars.tool_wield_scale, @@ -151,11 +151,11 @@ S("The speed and damage of the arrow increases the longer you charge. The regula }) minetest.register_tool("mcl_bows:crossbow_loaded", { - description = S("Corssbow"), + description = S("Crossbow"), _tt_help = S("Launches arrows"), - _doc_items_longdesc = S("Corssbow are ranged weapons to shoot arrows at your foes.").."\n".. + _doc_items_longdesc = S("Crossbows are ranged weapons to shoot arrows at your foes.").."\n".. S("The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead."), - _doc_items_usagehelp = S("To use the 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_usagehelp = S("To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to load an arrow into the chamber, then to shoot press left mouse."), _doc_items_durability = BOW_DURABILITY, inventory_image = "mcl_bows_crossbow_3.png", wield_scale = mcl_vars.tool_wield_scale, @@ -181,7 +181,7 @@ S("The speed and damage of the arrow increases the longer you charge. The regula itemstack:get_meta():set_string("active", "true") return itemstack end, - groups = {weapon=1,weapon_ranged=1,crossbow=1,enchantability=1}, + groups = {weapon=1,weapon_ranged=1,crossbow=1,enchantability=1,not_in_creative_inventory=1}, _mcl_uses = 326, }) diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr index 313081e48..129095b4a 100644 --- a/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr @@ -13,3 +13,6 @@ Ammunition=Munition Damage from bow: 1-10=Dégâts de l'arc: 1-10 Damage from dispenser: 3=Dégâts du distributeur: 3 Launches arrows=Lance des flèches +Crossbow=Arbalète +Crossbows are ranged weapons to shoot arrows at your foes.=Les arbalètes sont des armes à distance pour tirer des flèches sur vos ennemis. +To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot.=Pour utiliser l'arbalète, vous devez d'abord avoir au moins une flèche n'importe où dans votre inventaire (sauf en mode créatif). Maintenez enfoncé le bouton droit de la souris pour charger, relâchez pour tirer. \ No newline at end of file diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.ja.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.ja.tr new file mode 100644 index 000000000..517622b47 --- /dev/null +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.ja.tr @@ -0,0 +1,18 @@ +# textdomain: mcl_bows +Arrow=矢 +Arrows are ammunition for bows and dispensers.=矢は、弓やディスペンサーの弾です。 +An arrow fired from a bow has a regular damage of 1-9. At full charge, there's a 20% chance of a critical hit dealing 10 damage instead. An arrow fired from a dispenser always deals 3 damage.=弓から放たれる矢は通常1~9のダメージです。最大タメで20%の確率でクリティカルヒットが発生し、代わりに10ダメージを与えます。ディスペンサーから発射された矢は、常に3ダメージを与えます。 +Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons.=矢は、固体のブロックに刺さる可能性があり、その場合は回収できます。また、木製のボタンも押せます。 +To use arrows as ammunition for a bow, just put them anywhere in your inventory, they will be used up automatically. To use arrows as ammunition for a dispenser, place them in the dispenser's inventory. To retrieve an arrow that sticks in a block, simply walk close to it.=矢を弓の弾として使うには、インベントリのどこかに入れるだけでよく、使い切るまで自動的に装填されます。矢をディスペンサーの弾薬として使用するには、ディスペンサーのインベントリに入れます。ブロックに刺さった矢を回収するには、ブロックの近くまで歩くだけです。 +Bow=弓 +Bows are ranged weapons to shoot arrows at your foes.=弓は、敵に矢を射るための遠距離武器です。 +The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead.=矢の速度とダメージは、タメ時間が長いほど増加します。通常の矢のダメージは1~9です。最大タメ時には20%の確率でクリティカルヒットすることがあり、その場合は代わりに10ダメージを与えます。 +To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot.=弓を使用するには、まずインベントリのどこかに少なくとも1本の矢が入っている必要があります(クリエイティブモードを除く)。マウスの右ボタンを押したままでタメ、離すと射ます。 +Bow=弓 +Ammunition=弾 +Damage from bow: 1-10=弓によるダメージ:1-10 +Damage from dispenser: 3=ディスペンサーによるダメージ:3 +Launches arrows=矢を発射 +Crossbow=クロスボウ +Crossbows are ranged weapons to shoot arrows at your foes.=クロスボウは、敵に矢を射るための遠距離武器です。 +To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot.=クロスボウを使用するには、まずインベントリのどこかに少なくとも1本の矢が入っている必要があります(クリエイティブモードを除く)。マウスの右ボタンを押したままでタメ、離すと射ます。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_bows/locale/template.txt b/mods/ITEMS/mcl_bows/locale/template.txt index 228b61709..ebdea9525 100644 --- a/mods/ITEMS/mcl_bows/locale/template.txt +++ b/mods/ITEMS/mcl_bows/locale/template.txt @@ -13,3 +13,6 @@ Ammunition= Damage from bow: 1-10= Damage from dispenser: 3= Launches arrows= +Crossbow= +Crossbows are ranged weapons to shoot arrows at your foes.= +To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to shoot.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_bows/rocket.lua b/mods/ITEMS/mcl_bows/rocket.lua index 9eb8ab8c4..e71c0c122 100644 --- a/mods/ITEMS/mcl_bows/rocket.lua +++ b/mods/ITEMS/mcl_bows/rocket.lua @@ -19,15 +19,18 @@ local function dir_to_pitch(dir) 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) + if self._harmless then return end + local p = self.object:get_pos() + if not p then return end + mcl_explosions.explode(p, 3, {}) + local objects = minetest.get_objects_inside_radius(p, 8) for _,obj in pairs(objects) do if obj:is_player() then - mcl_util.deal_damage(obj, damagemulitplier - vector.distance(self.object:get_pos(), obj:get_pos()), {type = "explosion"}) + mcl_util.deal_damage(obj, damagemulitplier - vector.distance(p, obj:get_pos()), {type = "explosion"}) elseif obj:get_luaentity().is_mob then obj:punch(self.object, 1.0, { full_punch_interval=1.0, - damage_groups={fleshy=damagemulitplier - vector.distance(self.object:get_pos(), obj:get_pos())}, + damage_groups={fleshy=damagemulitplier - vector.distance(p, obj:get_pos())}, }, self.object:get_velocity()) end end @@ -230,6 +233,7 @@ end local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") local mod_button = minetest.get_modpath("mesecons_button") local mod_target = minetest.get_modpath("mcl_target") +local enable_pvp = minetest.settings:get_bool("enable_pvp") minetest.register_craftitem("mcl_bows:rocket", { description = S("Arrow"), @@ -311,6 +315,8 @@ end function ARROW_ENTITY.on_step(self, dtime) mcl_burning.tick(self.object, dtime, self) + -- mcl_burning.tick may remove object immediately + if not self.object:get_pos() then return end self._time_in_air = self._time_in_air + .001 @@ -409,29 +415,34 @@ function ARROW_ENTITY.on_step(self, 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().is_mob or obj:get_luaentity()._hittable_by_projectile) then + local arrow_dir = self.object:get_velocity() + --create a raycast from the arrow based on the velocity of the arrow to deal with lag + local raycast = minetest.raycast(pos, vector.add(pos, vector.multiply(arrow_dir, 0.1)), true, false) + for hitpoint in raycast do + if hitpoint.type == "object" then + -- find the closest object that is in the way of the arrow + local ok = false + if hitpoint.ref:is_player() and enable_pvp then ok = true + elseif not hitpoint.ref:is_player() and hitpoint.ref:get_luaentity() then + if (hitpoint.ref:get_luaentity().is_mob or hitpoint.ref:get_luaentity()._hittable_by_projectile) then + ok = true + end end - end - - if ok then - local dist = vector.distance(pos, obj:get_pos()) - if not closest_object or not closest_distance then - closest_object = obj - closest_distance = dist - elseif dist < closest_distance then - closest_object = obj - closest_distance = dist + if ok then + local dist = vector.distance(hitpoint.ref:get_pos(), pos) + if not closest_object or not closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + elseif dist < closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + end end end end + -- If an attackable object was found, we will damage the closest one only if closest_object then diff --git a/mods/ITEMS/mcl_brewing/init.lua b/mods/ITEMS/mcl_brewing/init.lua index 2ff2a806f..9c6879430 100644 --- a/mods/ITEMS/mcl_brewing/init.lua +++ b/mods/ITEMS/mcl_brewing/init.lua @@ -369,6 +369,9 @@ local function allow_take(pos, listname, index, stack, player) minetest.record_protection_violation(pos, name) return 0 else + if listname == "stand" then + awards.unlock(name, "mcl:localBrewery") + end return stack:get_count() end end diff --git a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ja.tr b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ja.tr new file mode 100644 index 000000000..684a99b8f --- /dev/null +++ b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ja.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_brewing +Brewing Stand=醸造台 +Inventory=インベントリ +To use a brewing stand, rightclick it.=醸造台を使うには、右クリックします。 +To brew, you need blaze powder as fuel, a brewing material and at least 1 glass bottle filled with a liquid.=醸造するには、燃料となるブレイズパウダー、醸造材料、および液体の入ったガラス瓶が最低1本必要です。 +Place the blaze powder in the left slot, the brewing material in the middle slot and 1-3 bottles in the remaining slots.=左スロットにブレイズパウダー、中央スロットに醸造材料、残りのスロットに1~3本の瓶を配置します。 +When you have found a good combination, the brewing will commence automatically and steam starts to appear, using up the fuel and brewing material. The potions will soon be ready.=良い組み合わせであれば、自動的に醸造が開始され蒸気が発生し、燃料と醸造材料を消費していきます。やがてポーションが完成するでしょう。 +Different combinations of brewing materials and liquids will give different results. Try to experiment!=醸造材料と液体の組み合わせが異なれば、得られる結果も異なります。ぜひ試してみてください! +The stand allows you to brew potions!=このスタンドは、あなたのポーション醸造を許す! +Brew Potions=ポーションの醸造 diff --git a/mods/ITEMS/mcl_buckets/fishbuckets.lua b/mods/ITEMS/mcl_buckets/fishbuckets.lua new file mode 100644 index 000000000..9eb966084 --- /dev/null +++ b/mods/ITEMS/mcl_buckets/fishbuckets.lua @@ -0,0 +1,71 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Fish Buckets +local fish_names = { + ["cod"] = "Cod", + ["salmon"] = "Salmon", + ["tropical_fish"] = "Tropical Fish", + ["axolotl"] = "Axolotl", + --["pufferfish"] = "Pufferfish", --FIXME add pufferfish +} + +local fishbucket_prefix = "mcl_buckets:bucket_" + +local function on_place_fish(itemstack, placer, pointed_thing) + + local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing) + if new_stack then + return new_stack + end + + local pos = pointed_thing.above or pointed_thing.under + if not pos then return end + local n = minetest.get_node_or_nil(pos) + if n.name and minetest.registered_nodes[n.name].buildable_to or n.name == "mcl_portals:portal" then + local fish = itemstack:get_name():gsub(fishbucket_prefix,"") + if fish_names[fish] then + local o = minetest.add_entity(pos, "mobs_mc:" .. fish) + local props = itemstack:get_meta():get_string("properties") + if props ~= "" then + o:set_properties(minetest.deserialize(props)) + end + local water = "mcl_core:water_source" + if n.name == "mclx_core:river_water_source" then + water = n.name + elseif n.name == "mclx_core:river_water_flowing" then + water = nil + end + if mcl_worlds.pos_to_dimension(pos) == "nether" then + water = nil + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + end + if water then + minetest.set_node(pos,{name = water}) + end + if not placer or not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack = ItemStack("mcl_buckets:bucket_empty") + end + end + end + return itemstack +end + +for techname, fishname in pairs(fish_names) do + minetest.register_craftitem(fishbucket_prefix .. techname, { + description = S("Bucket of @1", S(fishname)), + _doc_items_longdesc = S("This bucket is filled with water and @1.", S(fishname)), + _doc_items_usagehelp = S("Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 with a bucket of water.", S(fishname), S(fishname)), + _tt_help = S("Places a water source and a @1.", S(fishname)), + inventory_image = techname .. "_bucket.png", + stack_max = 1, + groups = {bucket = 1, fish_bucket = 1}, + liquids_pointable = false, + on_place = on_place_fish, + on_secondary_use = on_place_fish, + _on_dispense = function(stack, pos, droppos, dropnode, dropdir) + return on_place_fish(stack, nil, {above=droppos}) + end, + }) + + minetest.register_alias("mcl_fishing:bucket_" .. techname, "mcl_buckets:bucket_" .. techname) +end diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 85215caaf..0851c3757 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -2,6 +2,7 @@ local modname = minetest.get_current_modname() local S = minetest.get_translator(modname) local modpath = minetest.get_modpath(modname) +local use_select_box = minetest.settings:get_bool("mcl_buckets_use_select_box", false) -- Compatibility with old bucket mod minetest.register_alias("bucket:bucket_empty", "mcl_buckets:bucket_empty") @@ -29,15 +30,15 @@ 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", - recipe = { - {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"}, - {"", "mcl_core:iron_ingot", ""}, - }, - }) -end + +minetest.register_craft({ + output = "mcl_buckets:bucket_empty 1", + recipe = { + {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"}, + {"", "mcl_core:iron_ingot", ""}, + }, +}) + mcl_buckets = { liquids = {}, @@ -87,27 +88,6 @@ 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 @@ -155,71 +135,76 @@ local function get_bucket_drop(itemstack, user, take_bucket) 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 function bucket_get_pointed_thing(user) + local start = user:get_pos() + start.y = start.y + user:get_properties().eye_height + local look_dir = user:get_look_dir() + _end = vector.add(start, vector.multiply(look_dir, 5)) - 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 + local ray = raycast(start, _end, false, true) + for pointed_thing in ray do + local name = get_node(pointed_thing.under).name + local def = registered_nodes[name] + if not def or def.drawtype ~= "flowingliquid" then + return pointed_thing end - 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(itemstack, user, pointed_thing) + if not use_select_box then + pointed_thing = bucket_get_pointed_thing(user) + end + + -- Must be pointing to node + if not pointed_thing or pointed_thing.type ~= "node" then + return + end + + -- Call on_rightclick if the pointed node defines it + local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing) + if new_stack then + return new_stack + end + + local bucket_def = mcl_buckets.buckets[itemstack:get_name()] + for _, pos in pairs({ pointed_thing.under, pointed_thing.above }) do + local node = get_node(pos) + local node_def = registered_nodes[node.name] + + if node_def and node_def.buildable_to or get_item_group(node.name, "cauldron") == 1 then + local result, take_bucket = get_extra_check(bucket_def.extra_check, pos, user) + if result then + local node_place = get_node_place(bucket_def.source_place, pos) + local player_name = user:get_player_name() + + -- Check protection + if is_protected(pos, player_name) then + record_protection_violation(pos, player_name) + return itemstack + end + + -- Place liquid + place_liquid(pos, node_place) + + -- Update doc mod + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) + end + end + return get_bucket_drop(itemstack, user, take_bucket) + end + end + return itemstack +end local function on_place_bucket_empty(itemstack, user, pointed_thing) + if not use_select_box then + pointed_thing = bucket_get_pointed_thing(user) + end + -- Must be pointing to node - if pointed_thing.type ~= "node" then + if not pointed_thing or pointed_thing.type ~= "node" then return itemstack end @@ -229,59 +214,59 @@ local function on_place_bucket_empty(itemstack, user, pointed_thing) 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()) + local under = pointed_thing.under + local node_name = get_node(under).name + if pointable_sources[node_name] then + if is_protected(under, user:get_player_name()) then + record_protection_violation(under, user:get_player_name()) end - local liquid_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 + local liquid_def = mcl_buckets.liquids[node_name] + if liquid_def then + -- Fill bucket, but not in Creative Mode + -- FIXME: remove this line + --if not is_creative_enabled(user:get_player_name()) then + if not false then + new_bucket = ItemStack({name = liquid_def.bucketname}) + if liquid_def.on_take then + liquid_def.on_take(user) end - 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 + add_node(under, {name="air"}) + sound_take(node_name, under) + + if mod_doc and doc.entry_exists("nodes", node_name) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_name) + end + if new_bucket then + return give_bucket(new_bucket, itemstack, user) + end + else + minetest.log("error", string.format("[mcl_buckets] Node [%s] has invalid group [_mcl_bucket_pointable]!", node_name)) end return itemstack else -- FIXME: replace this ugly code by cauldrons API - if nn == "mcl_cauldrons:cauldron_3" then + if node_name == "mcl_cauldrons:cauldron_3" then -- Take water out of full cauldron - set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) + set_node(under, {name="mcl_cauldrons:cauldron"}) if not is_creative_enabled(user:get_player_name()) then new_bucket = ItemStack("mcl_buckets:bucket_water") end - sound_take("mcl_core:water_source", pointed_thing.under) - elseif nn == "mcl_cauldrons:cauldron_3r" then + sound_take("mcl_core:water_source", under) + elseif node_name == "mcl_cauldrons:cauldron_3r" then -- Take river water out of full cauldron - set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) + set_node(under, {name="mcl_cauldrons:cauldron"}) if not is_creative_enabled(user:get_player_name()) then new_bucket = ItemStack("mcl_buckets:bucket_river_water") end - sound_take("mclx_core:river_water_source", pointed_thing.under) + sound_take("mclx_core:river_water_source", under) + elseif node_name == "mcl_cauldrons:cauldron_3_lava" then + set_node(under, {name="mcl_cauldrons:cauldron"}) + if not is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack("mcl_buckets:bucket_lava") + end + sound_take("mcl_core:lava_source", under) end if new_bucket then return give_bucket(new_bucket, itemstack, user) @@ -290,34 +275,6 @@ local function on_place_bucket_empty(itemstack, user, pointed_thing) 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 _,source in ipairs(def.source_take) do mcl_buckets.liquids[source] = { @@ -346,6 +303,9 @@ function mcl_buckets.register_liquid(def) inventory_image = def.inventory_image, stack_max = 1, groups = def.groups, + liquids_pointable = use_select_box, + on_place = on_place_bucket, + on_secondary_use = on_place_bucket, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) local buildable = registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" if not buildable then return stack end @@ -366,9 +326,11 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { _doc_items_longdesc = S("A bucket can be used to collect and release liquids."), _doc_items_usagehelp = S("Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else."), _tt_help = S("Collects liquids"), - --liquids_pointable = true, inventory_image = "bucket.png", stack_max = 16, + liquids_pointable = use_select_box, + on_place = on_place_bucket_empty, + on_secondary_use = on_place_bucket_empty, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Fill empty bucket with liquid or drop bucket if no liquid local collect_liquid = false @@ -396,3 +358,4 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { }) dofile(modpath.."/register.lua") +dofile(modpath.."/fishbuckets.lua") diff --git a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.fr.tr b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.fr.tr index 4320f7509..2562a2f84 100644 --- a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.fr.tr +++ b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.fr.tr @@ -3,7 +3,7 @@ Empty Bucket=Seau Vide A bucket can be used to collect and release liquids.=Un seau peut être utilisé pour recueillir et libérer les liquides. Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else.=Frappez une source de liquide pour la collecter. Vous pouvez ensuite utiliser le seau rempli pour placer le liquide ailleurs. Lava Bucket=Seau de Lave -A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.=Un seau peut être utilisé pour recueillir et libérer les liquides. Celui-ci est rempli de lave chaude, contenue en toute sécurité à l'intérieur. Utiliser avec précaution. +A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.=Un seau peut être utilisé pour recueillir et libérer les liquides. Celui-ci est rempli de lave chaude, contenue en toute sécurité à l'intérieur. À utiliser avec précaution. Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!=Eloignez-vous et placez le seau pour le vider et créez une source de lave à cet endroit. Ne vous brûlez pas! Water Bucket=Seau d'Eau A bucket can be used to collect and release liquids. This one is filled with water.=Un seau peut être utilisé pour recueillir et libérer les liquides. Celui-ci est rempli d'eau. @@ -15,3 +15,10 @@ Collects liquids=Collecte des liquides Places a lava source=Place une source de lave Places a water source=Place une source d'eau Places a river water source=Place une source d'eau de rivière +Cod=Morue +Salmon=Saumon +Tropical Fish=Poisson Tropical +Bucket of @1=Seau de @1 +This bucket is filled with water and @1.=Ce seau est rempli d'eau et de @1. +Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 fish with a bucket of water.=Le placer pour vider le seau et placer un @1. +Places a water source and a @1 fish.=Placer une source d'eau et un poisson @1. diff --git a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ja.tr b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ja.tr new file mode 100644 index 000000000..9da7d4dfb --- /dev/null +++ b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ja.tr @@ -0,0 +1,25 @@ +# textdomain: mcl_buckets +Empty Bucket=空のバケツ +A bucket can be used to collect and release liquids.=バケツは、液体の回収と放出に使えます。 +Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else.=液体の源に使うと、それを回収します。何処かに満ちたバケツを使うと、液体を配置できます。 +Lava Bucket=溶岩入りバケツ +A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.=バケツは、液体を集めたり出したりするのに使えます。この満たされた高温の溶岩は、安全に収容されています。使用の際はご注意ください。 +Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!=安全な距離を取り、バケツを置いて空にし、この場所に溶岩源を作ります。ヤケドしないように! +Water Bucket=水入りバケツ +A bucket can be used to collect and release liquids. This one is filled with water.=バケツは、液体を集めたり出したりするのに使えます。これは水で満たされています。 +Place it to empty the bucket and create a water source.=これを置いてバケツを空にし、水源を作ります。 +River Water Bucket=河川水入りバケツ +A bucket can be used to collect and release liquids. This one is filled with river water.=バケツは、液体を集めたり出したりするのに使えます。これは河川水で満たされています。 +Place it to empty the bucket and create a river water source.=これを置いてバケツを空にし、河川水源を作ります。 +Collects liquids=液体を回収 +Places a lava source=溶岩源を配置 +Places a water source=水源を配置 +Places a river water source=河川水源を配置 +Axolotl=ウーパールーパー +Cod=タラ +Salmon=サケ +Tropical Fish=クマノミ +Bucket of @1=@1入りバケツ +This bucket is filled with water and @1.=このバケツには、水と@1が入っています。 +Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 fish with a bucket of water.=バケツを空にするために@1を置きます。@2入りバケツを右クリックすると魚を入手します。 +Places a water source and a @1 fish.=水源と、@1の魚を配置 diff --git a/mods/ITEMS/mcl_buckets/locale/template.txt b/mods/ITEMS/mcl_buckets/locale/template.txt index 174d1b76b..29aaeace9 100644 --- a/mods/ITEMS/mcl_buckets/locale/template.txt +++ b/mods/ITEMS/mcl_buckets/locale/template.txt @@ -15,3 +15,11 @@ Collects liquids= Places a lava source= Places a water source= Places a river water source= +Axolotl= +Cod= +Salmon= +Tropical Fish= +Bucket of @1= +This bucket is filled with water and @1.= +Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 with a bucket of water.= +Places a water source and a @1.= diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua index 1a7c8fe14..365966724 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -10,13 +10,6 @@ local function sound_place(itemname, pos) end end ---[[local sound_take = function(itemname, pos) - local def = minetest.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]] - if mod_mcl_core then -- Lava bucket mcl_buckets.register_liquid({ @@ -29,11 +22,21 @@ if mod_mcl_core then end end, source_take = {"mcl_core:lava_source", "mcl_nether:nether_lava_source"}, - on_take = function(user) - if has_awards and user and user:is_player() then - awards.unlock(user:get_player_name(), "mcl:hotStuff") - end - end, + on_take = function(user) + if has_awards and user and user:is_player() then + awards.unlock(user:get_player_name(), "mcl:hotStuff") + end + end, + extra_check = function(pos, placer) + local nn = minetest.get_node(pos).name + if minetest.get_item_group(nn, "cauldron") ~= 0 then + if nn ~= "mcl_cauldrons:cauldron_3_lava" then + minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3_lava"}) + end + sound_place("mcl_core:lava_source", pos) + return false, true + end + end, bucketname = "mcl_buckets:bucket_lava", inventory_image = "bucket_lava.png", name = S("Lava Bucket"), diff --git a/mods/ITEMS/mcl_buckets/textures/axolotl_bucket.png b/mods/ITEMS/mcl_buckets/textures/axolotl_bucket.png new file mode 100644 index 000000000..1923991c1 Binary files /dev/null and b/mods/ITEMS/mcl_buckets/textures/axolotl_bucket.png differ diff --git a/mods/ITEMS/mcl_cake/locale/mcl_cake.ja.tr b/mods/ITEMS/mcl_cake/locale/mcl_cake.ja.tr new file mode 100644 index 000000000..69b0dd78f --- /dev/null +++ b/mods/ITEMS/mcl_cake/locale/mcl_cake.ja.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_cake +Cake=ケーキ +Cakes can be placed and eaten to restore hunger points. A cake has 7 slices. Each slice restores 2 hunger points and 0.4 saturation points. Cakes will be destroyed when dug or when the block below them is broken.=ケーキは置くと食べる事ができ、満腹度が回復します。一つのケーキは7口分に切ってあります。1口につき満腹度が2、隠し満腹度が0.4回復します。ケーキは、それを掘ったり、その下のブロックを壊したりすると消滅します。 +Place the cake anywhere, then rightclick it to eat a single slice. You can't eat from the cake when your hunger bar is full.=ケーキを任意の場所に置き、右クリックで一切れ食べます。満腹ゲージが満タンの状態では、食べられません。 +Cake (6 Slices Left)=ケーキ(残り6切れ) +Cake (5 Slices Left)=ケーキ(残り5切れ) +Cake (4 Slices Left)=ケーキ(残り4切れ) +Cake (3 Slices Left)=ケーキ(残り3切れ) +Cake (2 Slices Left)=ケーキ(残り2切れ) +Cake (1 Slice Left)=ケーキ(残り1切れ) +With 7 tasty slices!=7枚切りのおいしいスイーツ! +Hunger points: +@1 per slice=満腹度:+@1/1切れ diff --git a/mods/ITEMS/mcl_campfires/README.md b/mods/ITEMS/mcl_campfires/README.md new file mode 100644 index 000000000..8747aa7e3 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/README.md @@ -0,0 +1,21 @@ +mcl_campfires +=============== +Adds the campfire and its soul variant. + +License of code +--------------- +See the main MineClone 2 README.md file. +Authors: +Gerold55 - Code Start + Models? +PrairieWind - Improved and Cleaned Up Code, and added the soul campfire and crafting recipes. +cora - Added burning damage. + +License of media +---------------- +See the main MineClone 2 README.md file for license on most of the textures. + +For the following textures: +mcl_campfires_campfire_inv.png +mcl_campfires_soul_campfire_inv.png +License: CC0 1.0 Universal (CC0 1.0) +Author: RandomLegoBrick diff --git a/mods/ITEMS/mcl_campfires/init.lua b/mods/ITEMS/mcl_campfires/init.lua new file mode 100644 index 000000000..083fbce57 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/init.lua @@ -0,0 +1,147 @@ +-- |||||||||||||||||||||||||||||||| +-- ||||||||||| CAMPFIRES |||||||||| +-- |||||||||||||||||||||||||||||||| + +-- TO-DO: +-- * Add Smoke Particles +-- * Add Spark Particles +-- * Add Cooking Meat +-- * Add Working Sounds + +local S = minetest.get_translator(minetest.get_current_modname()) + +local campfires = { + { name = "Campfire", lightlevel = 14, techname = "campfire", damage = 1, drops = "mcl_core:charcoal_lump 2" }, + { name = "Soul Campfire", lightlevel = 10, techname = "soul_campfire", damage = 2, drops = "mcl_blackstone:soul_soil" }, +} + +for _, campfire in pairs(campfires) do +-- Define Campfire + minetest.register_node("mcl_campfires:" .. campfire.techname, { + description = S(campfire.name), + _tt_help = S("Cooks food and keeps bees happy."), + _doc_items_longdesc = S("Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap."), + inventory_image = "mcl_campfires_" .. campfire.techname .. "_inv.png", + drawtype = "mesh", + mesh = "mcl_campfires_campfire.obj", + tiles = {{name="mcl_campfires_log.png"},}, + use_texture_alpha = "clip", + groups = { handy=1, axey=1, material_wood=1, not_in_creative_inventory=1, campfire=1, }, + paramtype = "light", + paramtype2 = "facedir", + on_rightclick = function (pos, node, player, itemstack, pointed_thing) + if player:get_wielded_item():get_name() == "mcl_fire:flint_and_steel" then + node.name = "mcl_campfires:" .. campfire.techname .. "_lit" + minetest.set_node(pos, node) + end + end, + drop = campfire.drops, + _mcl_silk_touch_drop = {"mcl_campfires:" .. campfire.techname}, + mcl_sounds.node_sound_wood_defaults(), + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, -.05, .5}, + }, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + }) + + --Define Lit Campfire + minetest.register_node("mcl_campfires:" .. campfire.techname .. "_lit", { + description = S(campfire.name), + _tt_help = S("Cooks food and keeps bees happy."), + _doc_items_longdesc = S("Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap."), + inventory_image = "mcl_campfires_" .. campfire.techname .. "_inv.png", + drawtype = "mesh", + mesh = "mcl_campfires_campfire_lit.obj", + tiles = {{ + name="mcl_campfires_" .. campfire.techname .. "_fire.png", + animation={ + type="vertical_frames", + aspect_w=16, + aspect_h=16, + length=2.0 + }}, + {name="mcl_campfires_" .. campfire.techname .. "_log_lit.png", + animation={ + type="vertical_frames", + aspect_w=16, + aspect_h=16, + length=2.0 + }} + }, + use_texture_alpha = "clip", + groups = { handy=1, axey=1, material_wood=1, campfire=1, lit_campfire=1 }, + paramtype = "light", + paramtype2 = "facedir", + on_rightclick = function (pos, node, player, itemstack, pointed_thing) + if player:get_wielded_item():get_name():find("shovel") then + node.name = "mcl_campfires:" .. campfire.techname + minetest.set_node(pos, node) + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + end + end, + drop = campfire.drops, + _mcl_silk_touch_drop = {"mcl_campfires:" .. campfire.techname .. "_lit"}, + light_source = campfire.lightlevel, + mcl_sounds.node_sound_wood_defaults(), + selection_box = { + type = "fixed", + fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top + }, + collision_box = { + type = "fixed", + fixed = {-.5, -.5, -.5, .5, -.05, .5}, + }, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + damage_per_second = campfire.damage, + }) +end + +minetest.register_craft({ + output = "mcl_campfires:campfire_lit", + recipe = { + { "", "mcl_core:stick", "" }, + { "mcl_core:stick", "group:coal", "mcl_core:stick" }, + { "group:tree", "group:tree", "group:tree" }, + } +}) + +minetest.register_craft({ + output = "mcl_campfires:soul_campfire_lit", + recipe = { + { "", "mcl_core:stick", "" }, + { "mcl_core:stick", "group:soul_block", "mcl_core:stick" }, + { "group:tree", "group:tree", "group:tree" }, + } +}) + +local function burn_in_campfire(obj) + local p = obj:get_pos() + if p then + local n = minetest.find_node_near(p,0.4,{"group:lit_campfire"},true) + if n then + mcl_burning.set_on_fire(obj, 5) + end + end +end + +local etime = 0 +minetest.register_globalstep(function(dtime) + etime = dtime + etime + if etime < 0.5 then return end + etime = 0 + for _,pl in pairs(minetest.get_connected_players()) do + burn_in_campfire(pl) + end + for _,ent in pairs(minetest.luaentities) do + if ent.is_mob then + burn_in_campfire(ent.object) + end + end +end) diff --git a/mods/ITEMS/mcl_campfires/locale/mcl_campfires.fr.tr b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.fr.tr new file mode 100644 index 000000000..0708aaeb7 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.fr.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_campfires +Campfire=Feu de camp +Soul Campfire=Feu de camp des âmes +Cooks food and keeps bees happy.=Cuit la nourriture et garde les abeilles heureuses +Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap.=Les feux de camp ont des usages multiples, incluant garder les abeilles heureuses, cuisiner de la viande crue et du poisson, et comme piège. \ No newline at end of file diff --git a/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ja.tr b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ja.tr new file mode 100644 index 000000000..cf311ebd2 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_campfires +Campfire=焚き火 +Soul Campfire=魂の焚き火 +Cooks food and keeps bees happy.=食料を調理したり、ミツバチ達を温和にしたりします。 +Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap.=焚き火には色々な用途があります:ミツバチを温和にする、生の肉や魚を調理する、罠として使う \ No newline at end of file diff --git a/mods/ITEMS/mcl_campfires/locale/template.txt b/mods/ITEMS/mcl_campfires/locale/template.txt new file mode 100644 index 000000000..d357de0ed --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/template.txt @@ -0,0 +1,5 @@ +# textdomain: mcl_campfires +Campfire= +Soul Campfire= +Cooks food and keeps bees happy.= +Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_campfires/mod.conf b/mods/ITEMS/mcl_campfires/mod.conf new file mode 100644 index 000000000..5c4b77dda --- /dev/null +++ b/mods/ITEMS/mcl_campfires/mod.conf @@ -0,0 +1,3 @@ +name = mcl_campfires +depends = mcl_sounds +author = PrairieWind, Gerold55 \ No newline at end of file diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire.obj b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire.obj new file mode 100644 index 000000000..a559fdd4f --- /dev/null +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire.obj @@ -0,0 +1,224 @@ +# Blender v2.78 (sub 0) OBJ File: '' +# www.blender.org +mtllib campfire.mtl +o nodebox4 +v 0.500000 -0.312500 0.250000 +v 0.500000 -0.312500 0.500000 +v 0.500000 -0.062500 0.500000 +v 0.500000 -0.062500 0.250000 +v -0.500000 -0.312500 0.250000 +v -0.500000 -0.312500 0.500000 +v -0.500000 -0.062500 0.500000 +v -0.500000 -0.062500 0.250000 +v 0.500000 -0.312500 0.500000 +v 0.500000 -0.062500 0.500000 +v -0.500000 -0.062500 0.500000 +v -0.500000 -0.312500 0.500000 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +usemtl none +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/1 6/6/1 7/7/1 8/8/1 +f 1/9/2 4/10/2 8/11/2 5/5/2 +f 1/9/3 2/12/3 6/13/3 5/5/3 +f 4/14/3 3/15/3 7/16/3 8/17/3 +f 9/18/2 10/19/2 11/20/2 12/21/2 +o nodebox4.001 +v 0.500000 -0.312500 -0.498288 +v 0.500000 -0.312500 -0.248288 +v 0.500000 -0.062500 -0.248288 +v 0.500000 -0.062500 -0.498288 +v -0.500000 -0.312500 -0.498288 +v -0.500000 -0.312500 -0.248288 +v -0.500000 -0.062500 -0.248288 +v -0.500000 -0.062500 -0.498288 +v 0.500000 -0.312500 -0.248288 +v 0.500000 -0.062500 -0.248288 +v -0.500000 -0.062500 -0.248288 +v -0.500000 -0.312500 -0.248288 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +usemtl none +s 1 +f 13/22/4 14/23/4 15/24/4 16/25/4 +f 17/26/4 18/27/4 19/28/4 20/29/4 +f 13/30/5 16/31/5 20/32/5 17/26/5 +f 13/30/6 14/33/6 18/34/6 17/26/6 +f 16/35/6 15/36/6 19/37/6 20/38/6 +f 21/39/5 22/40/5 23/41/5 24/42/5 +o nodebox3 +v 0.250000 -0.500000 -0.500000 +v 0.250000 -0.437500 -0.500000 +v -0.250000 -0.437500 -0.500000 +v -0.250000 -0.500000 -0.500000 +v 0.250000 -0.500000 0.500000 +v 0.250000 -0.437500 0.500000 +v -0.250000 -0.437500 0.500000 +v -0.250000 -0.500000 0.500000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vt 1.0000 0.1250 +vt 0.0000 0.1250 +vt 1.0000 0.0000 +vt 1.0000 0.1250 +vt 0.0000 0.1250 +vt 1.0000 0.5000 +vt 0.0000 0.5000 +vt 0.0001 0.0001 +vt 1.0000 0.0000 +vt 1.0000 0.5000 +vt 0.0000 0.5000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +usemtl none_NONE +s 1 +f 25/43/7 29/44/7 30/45/7 26/46/7 +f 28/47/7 32/48/7 31/49/7 27/50/7 +usemtl none +f 25/51/8 26/52/8 27/53/8 28/47/8 +f 29/54/8 30/55/8 31/56/8 32/48/8 +f 25/51/9 29/57/9 32/58/9 28/59/9 +f 26/46/9 30/60/9 31/61/9 27/62/9 +o nodebox4.003 +v -0.248335 -0.500045 0.508619 +v -0.498333 -0.500045 0.509533 +v -0.498334 -0.250045 0.509533 +v -0.248335 -0.250045 0.508619 +v -0.251992 -0.500045 -0.491375 +v -0.501991 -0.500045 -0.490460 +v -0.501991 -0.250045 -0.490460 +v -0.251992 -0.250045 -0.491375 +v -0.498333 -0.500045 0.509533 +v -0.498334 -0.250045 0.509533 +v -0.501991 -0.250045 -0.490460 +v -0.501991 -0.500045 -0.490460 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vn -0.0037 -0.0000 -1.0000 +vn -1.0000 0.0000 0.0037 +vn -0.0000 -1.0000 -0.0000 +usemtl none +s 1 +f 33/63/10 34/64/10 35/65/10 36/66/10 +f 37/67/10 38/68/10 39/69/10 40/70/10 +f 33/71/11 36/72/11 40/73/11 37/67/11 +f 33/71/12 34/74/12 38/75/12 37/67/12 +f 36/76/12 35/77/12 39/78/12 40/79/12 +f 41/80/11 42/81/11 43/82/11 44/83/11 +o nodebox4.002 +v 0.499948 -0.500045 0.505882 +v 0.249950 -0.500045 0.506796 +v 0.249950 -0.250045 0.506796 +v 0.499948 -0.250045 0.505882 +v 0.496291 -0.500045 -0.494111 +v 0.246293 -0.500045 -0.493197 +v 0.246293 -0.250045 -0.493197 +v 0.496291 -0.250045 -0.494111 +v 0.249950 -0.500045 0.506796 +v 0.249950 -0.250045 0.506796 +v 0.246293 -0.250045 -0.493197 +v 0.246293 -0.500045 -0.493197 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vn -0.0037 0.0000 -1.0000 +vn -1.0000 -0.0000 0.0037 +vn -0.0000 -1.0000 -0.0000 +usemtl none +s 1 +f 45/84/13 46/85/13 47/86/13 48/87/13 +f 49/88/13 50/89/13 51/90/13 52/91/13 +f 45/92/14 48/93/14 52/94/14 49/88/14 +f 45/92/15 46/95/15 50/96/15 49/88/15 +f 48/97/15 47/98/15 51/99/15 52/100/15 +f 53/101/14 54/102/14 55/103/14 56/104/14 diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl new file mode 100644 index 000000000..7355efe9f --- /dev/null +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl @@ -0,0 +1,35 @@ +# Blender MTL File: 'campfire.blend' +# Material Count: 3 + +newmtl Material.001 +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 +map_Kd G:\minetest-0.4.16-win641\textures\Pixel Perfection v4.0\mcl_campfire_fire.png + +newmtl none +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 +map_Kd \home\nathan\Downloads\mcl_campfire_log.png + +newmtl none_NONE +Ns 96.078431 +Ka 1.000000 1.000000 1.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.000000 +d 1.000000 +illum 2 +map_Kd \\home\\nathan\\Downloads\\mcl_campfire_log.png diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.obj b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.obj new file mode 100644 index 000000000..92a377303 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.obj @@ -0,0 +1,248 @@ +# Blender v2.78 (sub 0) OBJ File: 'campfire.blend' +# www.blender.org +mtllib campfire1.mtl +o nodebox4.005_nodebox4.006 +v 0.243779 -0.499707 -0.497529 +v 0.493779 -0.499707 -0.497421 +v 0.493779 -0.249707 -0.497421 +v 0.243779 -0.249707 -0.497529 +v 0.243349 -0.499707 0.502471 +v 0.493349 -0.499707 0.502578 +v 0.493349 -0.249707 0.502578 +v 0.243349 -0.249707 0.502471 +v 0.493779 -0.499707 -0.497421 +v 0.493779 -0.249707 -0.497421 +v 0.493349 -0.499707 0.502578 +v 0.493349 -0.249707 0.502578 +vt -0.0000 0.7500 +vt -0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt -0.0000 0.7500 +vt -0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt -0.0000 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt -0.0000 0.7500 +vn -0.0004 0.0000 1.0000 +vn 1.0000 -0.0000 0.0004 +vn -0.0000 -1.0000 0.0000 +usemtl none +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/1 6/6/1 7/7/1 8/8/1 +f 1/9/2 4/10/2 8/11/2 5/5/2 +f 1/9/3 2/12/3 6/13/3 5/5/3 +f 4/14/3 3/15/3 7/16/3 8/17/3 +f 9/18/2 10/19/2 12/20/2 11/21/2 +o nodebox4.004_nodebox4.005 +v -0.500021 -0.499707 -0.497848 +v -0.250021 -0.499707 -0.497741 +v -0.250021 -0.249707 -0.497741 +v -0.500021 -0.249707 -0.497848 +v -0.500451 -0.499707 0.502152 +v -0.250451 -0.499707 0.502259 +v -0.250451 -0.249707 0.502259 +v -0.500451 -0.249707 0.502152 +v -0.250021 -0.499707 -0.497741 +v -0.250021 -0.249707 -0.497741 +v -0.250451 -0.499707 0.502259 +v -0.250451 -0.249707 0.502259 +vt -0.0000 0.7500 +vt -0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt -0.0000 0.7500 +vt -0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt -0.0000 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt -0.0000 0.7500 +vn -0.0004 0.0000 1.0000 +vn 1.0000 -0.0000 0.0004 +vn -0.0000 -1.0000 0.0000 +usemtl none +s off +f 13/22/4 14/23/4 15/24/4 16/25/4 +f 17/26/4 18/27/4 19/28/4 20/29/4 +f 13/30/5 16/31/5 20/32/5 17/26/5 +f 13/30/6 14/33/6 18/34/6 17/26/6 +f 16/35/6 15/36/6 19/37/6 20/38/6 +f 21/39/5 22/40/5 24/41/5 23/42/5 +o nodebox4.001_nodebox4.004 +v 0.500000 -0.312500 -0.493800 +v 0.500000 -0.312500 -0.243800 +v 0.500000 -0.062500 -0.243800 +v 0.500000 -0.062500 -0.493800 +v -0.500000 -0.312500 -0.493800 +v -0.500000 -0.312500 -0.243800 +v -0.500000 -0.062500 -0.243800 +v -0.500000 -0.062500 -0.493800 +v 0.500000 -0.312500 -0.243800 +v 0.500000 -0.062500 -0.243800 +v -0.500000 -0.312500 -0.243800 +v -0.500000 -0.062500 -0.243800 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.7500 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +usemtl none +s off +f 25/43/7 26/44/7 27/45/7 28/46/7 +f 29/47/7 30/48/7 31/49/7 32/50/7 +f 25/51/8 28/52/8 32/53/8 29/47/8 +f 25/51/9 26/54/9 30/55/9 29/47/9 +f 28/56/9 27/57/9 31/58/9 32/59/9 +f 33/60/8 34/61/8 36/62/8 35/63/8 +o Plane +v -0.311754 -0.438770 -0.196249 +v 0.276360 -0.438621 0.247948 +v -0.311276 0.135801 -0.196634 +v 0.276838 0.135950 0.247562 +v -0.274993 -0.438696 0.270317 +v 0.240407 -0.438696 -0.218656 +v -0.275322 0.135875 0.269969 +v 0.240077 0.135875 -0.219003 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt -0.0000 1.0000 +vn -0.6027 0.0010 0.7980 +vn 0.6883 0.0008 0.7255 +usemtl Material.001 +s off +f 37/64/10 38/65/10 40/66/10 39/67/10 +f 41/68/11 42/69/11 44/70/11 43/71/11 +o nodebox3 +v 0.250000 -0.500000 -0.500000 +v 0.250000 -0.500000 0.500000 +v 0.250000 -0.437500 0.500000 +v 0.250000 -0.437500 -0.500000 +v -0.250000 -0.500000 -0.500000 +v -0.250000 -0.500000 0.500000 +v -0.250000 -0.437500 0.500000 +v -0.250000 -0.437500 -0.500000 +vt 1.0000 0.0000 +vt 1.0000 0.0625 +vt 0.0000 0.0625 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vt 1.0000 0.0625 +vt 0.0000 0.0625 +vt 0.0000 0.0000 +vt 1.0000 0.4375 +vt 0.0000 0.4375 +vt 0.0001 0.0001 +vt 0.9999 0.0001 +vt 1.0000 0.5000 +vt 0.0000 0.5000 +vt 0.0001 0.0001 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vt 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +vn -1.0000 0.0000 0.0000 +usemtl none +s off +f 45/72/12 48/73/12 52/74/12 49/75/12 +f 46/76/12 47/77/12 51/78/12 50/79/12 +f 45/72/13 46/80/13 50/81/13 49/82/13 +f 48/83/13 47/84/13 51/85/13 52/86/13 +usemtl none_NONE +f 45/87/14 46/88/14 47/89/14 48/90/14 +f 49/75/14 50/79/14 51/91/14 52/92/14 +o nodebox4 +v 0.500000 -0.312500 0.250000 +v 0.500000 -0.312500 0.500000 +v 0.500000 -0.062500 0.500000 +v 0.500000 -0.062500 0.250000 +v -0.500000 -0.312500 0.250000 +v -0.500000 -0.312500 0.500000 +v -0.500000 -0.062500 0.500000 +v -0.500000 -0.062500 0.250000 +v 0.500000 -0.312500 0.500000 +v 0.500000 -0.062500 0.500000 +v -0.500000 -0.312500 0.500000 +v -0.500000 -0.062500 0.500000 +vt -0.0000 0.7500 +vt 0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt -0.0000 0.7500 +vt -0.0000 0.5000 +vt 0.2500 0.5000 +vt 0.2500 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt -0.0000 0.7500 +vt 1.0000 0.7500 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt -0.0000 0.7500 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +usemtl none +s off +f 53/93/15 54/94/15 55/95/15 56/96/15 +f 57/97/15 58/98/15 59/99/15 60/100/15 +f 53/101/16 56/102/16 60/103/16 57/97/16 +f 53/101/17 54/104/17 58/105/17 57/97/17 +f 56/106/17 55/107/17 59/108/17 60/109/17 +f 61/110/16 62/111/16 64/112/16 63/113/16 diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire_lit.obj b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire_lit.obj new file mode 100644 index 000000000..a17acc05f --- /dev/null +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire_lit.obj @@ -0,0 +1,225 @@ +# Blender v2.79 (sub 7) OBJ File: 'campfire.blend' +# www.blender.org +o Plane +v -0.240246 -0.438696 -0.141059 +v 0.205043 -0.438696 0.192756 +v -0.239959 0.135875 -0.141442 +v 0.205331 0.135875 0.192373 +v -0.216088 -0.438696 0.214432 +v 0.181502 -0.438696 -0.162771 +v -0.216417 0.135875 0.214085 +v 0.181172 0.135875 -0.163119 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt -0.000000 1.000000 +vn -0.5998 0.0008 0.8001 +vn 0.6883 0.0008 0.7255 +g Plane_Plane_Material.001 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 5/5/2 6/6/2 8/7/2 7/8/2 +o nodebox3 +v 0.250000 -0.500000 -0.500000 +v 0.250000 -0.500000 0.500000 +v 0.250000 -0.437500 0.500000 +v 0.250000 -0.437500 -0.500000 +v -0.250000 -0.500000 -0.500000 +v -0.250000 -0.500000 0.500000 +v -0.250000 -0.437500 0.500000 +v -0.250000 -0.437500 -0.500000 +v 0.243779 -0.499707 -0.497529 +v 0.493779 -0.499707 -0.497421 +v 0.493779 -0.249707 -0.497421 +v 0.243779 -0.249707 -0.497529 +v 0.243349 -0.499707 0.502471 +v 0.493349 -0.499707 0.502579 +v 0.493349 -0.249707 0.502578 +v 0.243349 -0.249707 0.502471 +v 0.493779 -0.499707 -0.497421 +v 0.493779 -0.249707 -0.497421 +v 0.493349 -0.499707 0.502579 +v 0.493349 -0.249707 0.502578 +v -0.500021 -0.499707 -0.497848 +v -0.250021 -0.499707 -0.497741 +v -0.250021 -0.249707 -0.497741 +v -0.500021 -0.249707 -0.497848 +v -0.500451 -0.499707 0.502152 +v -0.250451 -0.499707 0.502259 +v -0.250451 -0.249707 0.502259 +v -0.500451 -0.249707 0.502152 +v -0.250021 -0.499707 -0.497741 +v -0.250021 -0.249707 -0.497741 +v -0.250451 -0.499707 0.502259 +v -0.250451 -0.249707 0.502259 +v 0.500000 -0.312500 -0.493800 +v 0.500000 -0.312500 -0.243800 +v 0.500000 -0.062500 -0.243800 +v 0.500000 -0.062500 -0.493800 +v -0.500000 -0.312500 -0.493800 +v -0.500000 -0.312500 -0.243800 +v -0.500000 -0.062500 -0.243800 +v -0.500000 -0.062500 -0.493800 +v 0.500000 -0.312500 -0.243800 +v 0.500000 -0.062500 -0.243800 +v -0.500000 -0.312500 -0.243800 +v -0.500000 -0.062500 -0.243800 +v 0.500000 -0.312500 0.250000 +v 0.500000 -0.312500 0.500000 +v 0.500000 -0.062500 0.500000 +v 0.500000 -0.062500 0.250000 +v -0.500000 -0.312500 0.250000 +v -0.500000 -0.312500 0.500000 +v -0.500000 -0.062500 0.500000 +v -0.500000 -0.062500 0.250000 +v 0.500000 -0.312500 0.500000 +v 0.500000 -0.062500 0.500000 +v -0.500000 -0.312500 0.500000 +v -0.500000 -0.062500 0.500000 +vt 0.999982 0.000018 +vt 1.000000 0.062500 +vt 0.000000 0.062500 +vt 0.000018 0.000018 +vt 0.999982 0.000018 +vt 1.000000 0.062500 +vt 0.000000 0.062500 +vt 0.000018 0.000018 +vt 1.000000 0.437500 +vt 0.000000 0.437500 +vt 0.000071 0.000071 +vt 0.999929 0.000071 +vt 1.000000 0.500000 +vt 0.000000 0.500000 +vt 0.000071 0.000071 +vt -0.000000 0.750000 +vt -0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt -0.000000 0.750000 +vt -0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.750000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.750000 +vt -0.000000 0.750000 +vt -0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt -0.000000 0.750000 +vt -0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.750000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.750000 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.750000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.750000 +vt -0.000000 0.750000 +vt 0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt -0.000000 0.750000 +vt -0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.750000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt -0.000000 0.750000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +vn -0.0004 0.0000 1.0000 +vn 1.0000 -0.0000 0.0004 +vn -1.0000 0.0000 0.0000 +g nodebox3_nodebox3_none +s off +f 9/9/3 12/10/3 16/11/3 13/12/3 +f 10/13/3 11/14/3 15/15/3 14/16/3 +f 9/9/4 10/17/4 14/18/4 13/19/4 +f 12/20/4 11/21/4 15/22/4 16/23/4 +f 17/24/5 18/25/5 19/26/5 20/27/5 +f 21/28/5 22/29/5 23/30/5 24/31/5 +f 17/32/6 20/33/6 24/34/6 21/28/6 +f 17/32/4 18/35/4 22/36/4 21/28/4 +f 20/37/4 19/38/4 23/39/4 24/40/4 +f 25/41/6 26/42/6 28/43/6 27/44/6 +f 29/45/5 30/46/5 31/47/5 32/48/5 +f 33/49/5 34/50/5 35/51/5 36/52/5 +f 29/53/6 32/54/6 36/55/6 33/49/6 +f 29/53/4 30/56/4 34/57/4 33/49/4 +f 32/58/4 31/59/4 35/60/4 36/61/4 +f 37/62/6 38/63/6 40/64/6 39/65/6 +f 41/66/7 42/67/7 43/68/7 44/69/7 +f 45/70/7 46/71/7 47/72/7 48/73/7 +f 41/74/3 44/75/3 48/76/3 45/70/3 +f 41/74/4 42/77/4 46/78/4 45/70/4 +f 44/79/4 43/80/4 47/81/4 48/82/4 +f 49/83/3 50/84/3 52/85/3 51/86/3 +f 53/87/7 54/88/7 55/89/7 56/90/7 +f 57/91/7 58/92/7 59/93/7 60/94/7 +f 53/95/3 56/96/3 60/97/3 57/91/3 +f 53/95/4 54/98/4 58/99/4 57/91/4 +f 56/100/4 55/101/4 59/102/4 60/103/4 +f 61/104/3 62/105/3 64/106/3 63/107/3 +g nodebox3_nodebox3_none_NONE +f 9/108/7 10/109/7 11/110/7 12/111/7 +f 13/12/7 14/16/7 15/112/7 16/113/7 diff --git a/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_fire.png b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_fire.png new file mode 100644 index 000000000..d1288ec9d Binary files /dev/null and b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_fire.png differ diff --git a/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_inv.png b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_inv.png new file mode 100644 index 000000000..6d8ee3c06 Binary files /dev/null and b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_inv.png differ diff --git a/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_log_lit.png b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_log_lit.png new file mode 100644 index 000000000..7dd086000 Binary files /dev/null and b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_campfire_log_lit.png differ diff --git a/mods/ITEMS/mcl_campfires/textures/mcl_campfires_fire1.png b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_fire1.png new file mode 100644 index 000000000..865d6e3e0 Binary files /dev/null and b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_fire1.png differ diff --git a/mods/ITEMS/mcl_campfires/textures/mcl_campfires_log.png b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_log.png new file mode 100644 index 000000000..2401f4889 Binary files /dev/null and b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_log.png differ diff --git a/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_fire.png b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_fire.png new file mode 100644 index 000000000..ecf149833 Binary files /dev/null and b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_fire.png differ diff --git a/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_inv.png b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_inv.png new file mode 100644 index 000000000..88c7a6e4c Binary files /dev/null and b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_inv.png differ diff --git a/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_log_lit.png b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_log_lit.png new file mode 100644 index 000000000..1cc1f8043 Binary files /dev/null and b/mods/ITEMS/mcl_campfires/textures/mcl_campfires_soul_campfire_log_lit.png differ diff --git a/mods/ITEMS/mcl_cartography_table/init.lua b/mods/ITEMS/mcl_cartography_table/init.lua index d2f065880..a7c66b4e2 100644 --- a/mods/ITEMS/mcl_cartography_table/init.lua +++ b/mods/ITEMS/mcl_cartography_table/init.lua @@ -11,7 +11,9 @@ minetest.register_node("mcl_cartography_table:cartography_table", { "cartography_table_side3.png", "cartography_table_side1.png" }, paramtype2 = "facedir", - groups = {choppy=1, deco_block=1, material_wood=1,flammable=1} + groups = { axey = 2, handy = 1, deco_block = 1, material_wood = 1, flammable = 1 }, + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5 }) diff --git a/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.fr.tr b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.fr.tr new file mode 100644 index 000000000..5229d087d --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_cartography_table +Cartography Table=Table de Cartographie +Used to create or copy maps=Utilisée pour créer ou copier des cartes +Is used to create or copy maps for use..=Est utilisée pour créer ou copier des cartes.. \ No newline at end of file diff --git a/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ja.tr b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ja.tr new file mode 100644 index 000000000..91c01c2d0 --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_cartography_table +Cartography Table=製図台 +Used to create or copy maps=地図の作成やコピーに使用 +Is used to create or copy maps for use..=地図の作成やコピーに使用します。 diff --git a/mods/ITEMS/mcl_cartography_table/locale/template.txt b/mods/ITEMS/mcl_cartography_table/locale/template.txt new file mode 100644 index 000000000..e85502e31 --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: mcl_cartography_table +Cartography Table= +Used to create or copy maps= +Is used to create or copy maps for use..= diff --git a/mods/ITEMS/mcl_cauldrons/init.lua b/mods/ITEMS/mcl_cauldrons/init.lua index 55866f5cc..6a8270794 100644 --- a/mods/ITEMS/mcl_cauldrons/init.lua +++ b/mods/ITEMS/mcl_cauldrons/init.lua @@ -5,7 +5,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) -- TODO: Extinguish fire of burning entities -- Convenience function because the cauldron nodeboxes are very similar -local create_cauldron_nodebox = function(water_level) +local function create_cauldron_nodebox(water_level) local floor_y if water_level == 0 then -- empty floor_y = -0.1875 @@ -36,12 +36,6 @@ local create_cauldron_nodebox = function(water_level) } end -local cauldron_nodeboxes = {} -for w=0,3 do - cauldron_nodeboxes[w] = create_cauldron_nodebox(w) -end - - -- Empty cauldron minetest.register_node("mcl_cauldrons:cauldron", { description = S("Cauldron"), @@ -55,7 +49,7 @@ minetest.register_node("mcl_cauldrons:cauldron", { paramtype = "light", is_ground_content = false, groups = {pickaxey=1, deco_block=1, cauldron=1}, - node_box = cauldron_nodeboxes[0], + node_box = create_cauldron_nodebox(0), selection_box = { type = "regular" }, tiles = { "mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_top.png", @@ -68,12 +62,15 @@ minetest.register_node("mcl_cauldrons:cauldron", { }) -- Template function for cauldrons with water -local register_filled_cauldron = function(water_level, description, river_water) +local function register_filled_cauldron(water_level, description, liquid) local id = "mcl_cauldrons:cauldron_"..water_level local water_tex - if river_water then + if liquid == "river_water" then id = id .. "r" water_tex = "default_river_water_source_animated.png^[verticalframe:16:0" + elseif liquid == "lava" then + id = id .. "_lava" + water_tex = "default_lava_source_animated.png^[verticalframe:16:0" else water_tex = "default_water_source_animated.png^[verticalframe:16:0" end @@ -85,8 +82,8 @@ local register_filled_cauldron = function(water_level, description, river_water) paramtype = "light", is_ground_content = false, groups = {pickaxey=1, not_in_creative_inventory=1, cauldron=(1+water_level), cauldron_filled=water_level, comparator_signal=water_level}, - node_box = cauldron_nodeboxes[water_level], - collision_box = cauldron_nodeboxes[0], + node_box = create_cauldron_nodebox(water_level), + collision_box = create_cauldron_nodebox(0), selection_box = { type = "regular" }, tiles = { "("..water_tex..")^mcl_cauldrons_cauldron_top.png", @@ -106,14 +103,12 @@ local register_filled_cauldron = function(water_level, description, river_water) end -- Filled cauldrons (3 levels) -register_filled_cauldron(1, S("Cauldron (1/3 Water)")) -register_filled_cauldron(2, S("Cauldron (2/3 Water)")) -register_filled_cauldron(3, S("Cauldron (3/3 Water)")) - -if minetest.get_modpath("mclx_core") then - register_filled_cauldron(1, S("Cauldron (1/3 River Water)"), true) - register_filled_cauldron(2, S("Cauldron (2/3 River Water)"), true) - register_filled_cauldron(3, S("Cauldron (3/3 River Water)"), true) +for i=1,3 do + register_filled_cauldron(i, S("Cauldron (" ..i .. "/3 Water)")) + register_filled_cauldron(i, S("Cauldron (" ..i .. "/3 Water)"),"lava") + if minetest.get_modpath("mclx_core") then + register_filled_cauldron(i, S("Cauldron (" ..i .. "/3 Water)"),"river_water") + end end minetest.register_craft({ @@ -125,19 +120,36 @@ minetest.register_craft({ } }) -minetest.register_abm({ - label = "cauldrons", - nodenames = {"group:cauldron_filled"}, - interval = 0.5, - chance = 1, - action = function(pos, node) - for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.4)) do - if mcl_burning.is_burning(obj) then - mcl_burning.extinguish(obj) - local new_group = minetest.get_item_group(node.name, "cauldron_filled") - 1 - minetest.swap_node(pos, {name = "mcl_cauldrons:cauldron" .. (new_group == 0 and "" or "_" .. new_group)}) - break +local function cauldron_extinguish(obj,pos) + local node = minetest.get_node(pos) + if mcl_burning.is_burning(obj) then + mcl_burning.extinguish(obj) + local new_group = minetest.get_item_group(node.name, "cauldron_filled") - 1 + minetest.swap_node(pos, {name = "mcl_cauldrons:cauldron" .. (new_group == 0 and "" or "_" .. new_group)}) + end +end + +local etime = 0 +minetest.register_globalstep(function(dtime) + etime = dtime + etime + if etime < 0.5 then return end + etime = 0 + for _,pl in pairs(minetest.get_connected_players()) do + local n = minetest.find_node_near(pl:get_pos(),0.4,{"group:cauldron_filled"},true) + if n and not minetest.get_node(n).name:find("lava") then + cauldron_extinguish(pl,n) + elseif n and minetest.get_node(n).name:find("lava") then + mcl_burning.set_on_fire(pl, 5) + end + end + for _,ent in pairs(minetest.luaentities) do + if ent.object:get_pos() and ent.is_mob then + local n = minetest.find_node_near(ent.object:get_pos(),0.4,{"group:cauldron_filled"},true) + if n and not minetest.get_node(n).name:find("lava") then + cauldron_extinguish(ent.object,n) + elseif n and minetest.get_node(n).name:find("lava") then + mcl_burning.set_on_fire(ent.object, 5) end end end -}) +end) diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.de.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.de.tr index fe1d9aa81..fa2ae6874 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.de.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.de.tr @@ -1,4 +1,4 @@ -# textdomain: mcl_cauldron +# textdomain: mcl_cauldrons Cauldron=Kessel Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Kessel werden benutzt, um Wasser zu lagern, im Regen werden sie langsam aufgefüllt. Kessel können auch verwendet werden, um Banner abzuwaschen. Place a water bucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water. Use an emblazoned banner on a cauldron with water to wash off its top layer.=Platzieren Sie einen Wassereinmer in den Kessel, um ihn mit Wasser zu füllen. Platzieren Sie einen leeren Eimer auf einen vollen Kessel, um das Wasser aufzusammeln. Platzieren Sie eine Wasserflasche in den Kessel, um ihn zu einem Drittel mit Wasser zu füllen. Benutzen Sie ein bemaltes Banner auf den Kessel, um die oberste Schicht abzuwaschen. diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.es.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.es.tr index 9748e61b4..16af1a5c9 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.es.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.es.tr @@ -1,4 +1,4 @@ -# textdomain: mcl_cauldron +# textdomain: mcl_cauldrons Cauldron=Caldera Cauldrons are used to store water and slowly fill up under rain.=Los calderos se usan para almacenar agua y llenarse lentamente bajo la lluvia. Place a water bucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water.=Coloque un cubo de agua en el caldero para llenarlo con agua. Coloque un cubo vacío en un caldero lleno para recuperar el agua. Coloque una botella de agua en el caldero para llenar el caldero hasta un tercio con agua. Coloque una botella de vidrio en un caldero con agua para recuperar un tercio del agua. diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ja.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ja.tr new file mode 100644 index 000000000..da0a3495a --- /dev/null +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ja.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_cauldrons +Cauldron=大釜 +Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=大釜は水を溜めるためのもので、雨が降るとゆっくりと水が溜まっていきます。また、旗を洗い流すのにも使えます。 +Place a water bucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water. Use an emblazoned banner on a cauldron with water to wash off its top layer.=大釜に水入りバケツを置くと、水で満たします。満杯の大釜に空のバケツを置くと、水を回収します。大釜に水入り瓶を置くと、大釜に1段階分(容積の1/3)の水を注ぎます。水入りの大釜にガラス瓶を置くと、大釜から1段階分の水を回収します。水入りの大釜にエンブレム入りの旗を使うと、その一番上にあるレイヤーを洗い落とします。 +Cauldron (1/3 Water)=大釜(水 1/3) +Cauldron (2/3 Water)=大釜(水 2/3) +Cauldron (3/3 Water)=大釜(水 3/3) +Cauldron (1/3 River Water)=大釜(河川水 1/3) +Cauldron (2/3 River Water)=大釜(河川水 2/3) +Cauldron (3/3 River Water)=大釜(河川水 3/3) +Stores water=水を溜めておく diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pl.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pl.tr index 58826d9ab..32adf9851 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pl.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pl.tr @@ -1,4 +1,4 @@ -# textdomain: mcl_cauldron +# textdomain: mcl_cauldrons Cauldron=Kocioł Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Kotły są wykorzystywane do przechowywania wody oraz powoli wypełniają się podczas deszczu. Place a water bucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water. Use an emblazoned banner on a cauldron with water to wash off its top layer.=Umieść wiadro wody w kotle by wypełnić go wodą. Umieść puste wiadro na pełnym kotle by odzyskać wodę. Umieść szklaną butelkę w kotle z wodą aby odzyskać jedną trzecią wody. Użyj upiększonego sztandaru na kotle z wodą aby zmyć górną warstwę. diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr index ea3b97c41..40e37e129 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr @@ -1,4 +1,4 @@ -# textdomain: mcl_cauldron +# textdomain: mcl_cauldrons Cauldron=鍋釜 Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=鍋釜是用來儲水的,在雨水的作用下慢慢填滿。它們也可以用來清洗旗幟。 Place a water pucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water. Use an emblazoned banner on a cauldron with water to wash off its top layer.=將水桶放入鍋釜中,使其充滿水。將一個空桶放在裝滿水的大鍋上,以取回水。將一個水瓶放入鍋釜內,使大鍋內增加三分之一的水。將一個玻璃瓶放在有水的鍋釜裡,取回三分之一的水。在有水的鍋釜上使用印有圖案的旗幟,以洗掉其上層。 diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.fr.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.fr.tr index a241c5cb0..76c85e8e9 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.fr.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.fr.tr @@ -1,5 +1,5 @@ -# textdomain: mcl_cauldron -Cauldron=Chaudrons +# textdomain: mcl_cauldrons +Cauldron=Chaudron Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Les chaudrons sont utilisés pour stocker l'eau et se remplissent lentement sous la pluie. Ils peuvent également être utilisés pour laver les bannières. Place a water bucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water. Use an emblazoned banner on a cauldron with water to wash off its top layer.=Placez une marmite d'eau dans le chaudron pour le remplir d'eau. Placez un seau vide sur un chaudron plein pour récupérer l'eau. Placez une bouteille d'eau dans le chaudron pour remplir le chaudron au tiers avec de l'eau. Placez une bouteille en verre dans un chaudron avec de l'eau pour récupérer un tiers de l'eau. Utilisez une bannière blasonnée sur un chaudron avec de l'eau pour laver sa couche supérieure. Cauldron (1/3 Water)=Chaudron (1/3 d'eau) diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr index 6ecae1025..272ff7c44 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr @@ -1,4 +1,4 @@ -# textdomain: mcl_cauldron +# textdomain: mcl_cauldrons Cauldron=Котёл Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Котлы используются для хранения воды и медленного наполнения под дождём. Они также могут использоваться для промывания флагов. Place a water 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.=Попытайтесь поместить ведро воды в котёл, чтобы наполнить его водой. Попытка поместить пустое ведро приведёт к освобождению котла. Поместите в котёл бутылку воды, чтобы наполнить его на треть. diff --git a/mods/ITEMS/mcl_cauldrons/locale/template.txt b/mods/ITEMS/mcl_cauldrons/locale/template.txt index 5e18f3283..4c476e166 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/template.txt +++ b/mods/ITEMS/mcl_cauldrons/locale/template.txt @@ -1,4 +1,4 @@ -# textdomain: mcl_cauldron +# textdomain: mcl_cauldrons Cauldron= Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.= Place a water 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.= diff --git a/mods/ITEMS/mcl_cauldrons/mod.conf b/mods/ITEMS/mcl_cauldrons/mod.conf index 4787d60f9..36d5b303b 100644 --- a/mods/ITEMS/mcl_cauldrons/mod.conf +++ b/mods/ITEMS/mcl_cauldrons/mod.conf @@ -1,3 +1,3 @@ name = mcl_cauldrons depends = mcl_core, mcl_sounds -optional_depends = mclx_core, doc +optional_depends = mclx_core, doc, mcl_burning diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 9fe3a81e2..6d46103a3 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -32,8 +32,10 @@ end local tiles_chest_ender_small = {"mcl_chests_ender.png"} +local ender_chest_texture = {"mcl_chests_ender.png"} if it_is_christmas then tiles_chest_ender_small = {"mcl_chests_ender_present.png^mcl_chests_noise.png"} + ender_chest_texture = {"mcl_chests_ender_present.png"} end -- Chest Entity @@ -54,7 +56,6 @@ local entity_animations = { minetest.register_entity("mcl_chests:chest", { initial_properties = { visual = "mesh", - visual_size = {x = 3, y = 3}, pointable = false, physical = false, static_save = false, @@ -140,7 +141,6 @@ minetest.register_entity("mcl_chests:chest", { local function get_entity_pos(pos, dir, double) pos = vector.new(pos) - pos.y = pos.y - 0.49 if double then local add, mul, vec, cross = vector.add, vector.multiply, vector.new, vector.cross pos = add(pos, mul(cross(dir, vec(0, 1, 0)), -0.5)) @@ -363,7 +363,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile _doc_items_usagehelp = usagehelp, _doc_items_hidden = hidden, drawtype = "mesh", - mesh = "mcl_chests_chest.obj", + mesh = "mcl_chests_chest.b3d", tiles = small_textures, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", @@ -401,7 +401,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile type = "fixed", fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, }, - tiles = {"mcl_chests_blank.png"}, + tiles = {"blank.png^[resize:16x16"}, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, _chest_entity_textures = small_textures, _chest_entity_sound = "default_chest", @@ -527,7 +527,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile type = "fixed", fixed = {-0.4375, -0.5, -0.4375, 0.5, 0.375, 0.4375}, }, - tiles = {"mcl_chests_blank.png"}, + tiles = {"blank.png^[resize:16x16"}, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, _chest_entity_textures = left_textures, _chest_entity_sound = "default_chest", @@ -684,7 +684,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile type = "fixed", fixed = {-0.5, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, }, - tiles = {"mcl_chests_blank.png"}, + tiles = {"blank.png^[resize:16x16"}, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, groups = {handy=1,axey=1, container=6,not_in_creative_inventory=1, material_wood=1,flammable=-1,double_chest=2}, drop = drop, @@ -842,15 +842,6 @@ register_chest("chest", { small = tiles_chest_normal_small, double = tiles_chest_normal_double, - inv = {"default_chest_top.png", "mcl_chests_chest_bottom.png", - "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", - "mcl_chests_chest_back.png", "default_chest_front.png"}, - --[[left = {"default_chest_top_big.png", "default_chest_top_big.png", - "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", - "default_chest_side_big.png^[transformFX", "default_chest_front_big.png"}, - right = {"default_chest_top_big.png^[transformFX", "default_chest_top_big.png^[transformFX", - "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", - "default_chest_side_big.png", "default_chest_front_big.png^[transformFX"},]]-- }, false ) @@ -858,15 +849,6 @@ register_chest("chest", local traptiles = { small = tiles_chest_trapped_small, double = tiles_chest_trapped_double, - inv = {"mcl_chests_chest_trapped_top.png", "mcl_chests_chest_trapped_bottom.png", - "mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_left.png", - "mcl_chests_chest_trapped_back.png", "mcl_chests_chest_trapped_front.png"}, - --[[left = {"mcl_chests_chest_trapped_top_big.png", "mcl_chests_chest_trapped_top_big.png", - "mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_left.png", - "mcl_chests_chest_trapped_side_big.png^[transformFX", "mcl_chests_chest_trapped_front_big.png"}, - right = {"mcl_chests_chest_trapped_top_big.png^[transformFX", "mcl_chests_chest_trapped_top_big.png^[transformFX", - "mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_left.png", - "mcl_chests_chest_trapped_side_big.png", "mcl_chests_chest_trapped_front_big.png^[transformFX"},]]-- } register_chest("trapped_chest", @@ -992,7 +974,7 @@ minetest.register_node("mcl_chests:ender_chest", { _doc_items_longdesc = S("Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), _doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."), drawtype = "mesh", - mesh = "mcl_chests_chest.obj", + mesh = "mcl_chests_chest.b3d", tiles = tiles_chest_ender_small, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", @@ -1028,17 +1010,14 @@ minetest.register_node("mcl_chests:ender_chest_small", { drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.5, 0.375, 0.4375}, + fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, }, - _chest_entity_textures = {"mcl_chests_ender.png"}, + _chest_entity_textures = ender_chest_texture, _chest_entity_sound = "mcl_chests_enderchest", _chest_entity_mesh = "mcl_chests_chest", _chest_entity_animation_type = "chest", - tiles = {"mcl_chests_blank.png"}, + tiles = {"blank.png^[resize:16x16"}, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, - --[[{"mcl_chests_ender_chest_top.png", "mcl_chests_ender_chest_bottom.png", - "mcl_chests_ender_chest_right.png", "mcl_chests_ender_chest_left.png", - "mcl_chests_ender_chest_back.png", "mcl_chests_ender_chest_front.png"},]]-- -- Note: The “container” group is missing here because the ender chest does not -- have an inventory on its own groups = {pickaxey=1, deco_block=1, material_stone=1, chest_entity=1, not_in_creative_inventory=1}, @@ -1049,7 +1028,7 @@ minetest.register_node("mcl_chests:ender_chest_small", { sounds = mcl_sounds.node_sound_stone_defaults(), drop = "mcl_core:obsidian 8", on_construct = function(pos) - create_entity(pos, "mcl_chests:ender_chest_small", {"mcl_chests_ender.png"}, minetest.get_node(pos).param2, false, "mcl_chests_enderchest", "mcl_chests_chest", "chest") + create_entity(pos, "mcl_chests:ender_chest_small", ender_chest_texture, minetest.get_node(pos).param2, false, "mcl_chests_enderchest", "mcl_chests_chest", "chest") end, on_rightclick = function(pos, node, clicker) if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 then @@ -1057,7 +1036,7 @@ minetest.register_node("mcl_chests:ender_chest_small", { return false end minetest.show_formspec(clicker:get_player_name(), "mcl_chests:ender_chest_"..clicker:get_player_name(), formspec_ender_chest) - player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", {"mcl_chests_ender.png"}, node.param2, false, "mcl_chests_enderchest", "mcl_chests_chest") + player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", ender_chest_texture, node.param2, false, "mcl_chests_enderchest", "mcl_chests_chest") end, on_receive_fields = function(pos, formname, fields, sender) if fields.quit then @@ -1188,13 +1167,7 @@ for color, desc in pairs(boxtypes) do tiles = {mob_texture}, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, drawtype = "mesh", - mesh = "mcl_chests_shulker.obj", - --[["mcl_chests_"..color.."_shulker_box_top.png", -- top - "[combine:16x16:-32,-28="..mob_texture, -- bottom - "[combine:16x16:0,-36="..mob_texture..":0,-16="..mob_texture, -- side - "[combine:16x16:-32,-36="..mob_texture..":-32,-16="..mob_texture, -- side - "[combine:16x16:-16,-36="..mob_texture..":-16,-16="..mob_texture, -- side - "[combine:16x16:-48,-36="..mob_texture..":-48,-16="..mob_texture, -- side]]-- + mesh = "mcl_chests_shulker.b3d", groups = {handy=1,pickaxey=1, container=3, deco_block=1, dig_by_piston=1, shulker_box=1, old_shulker_box_node=1}, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -1250,7 +1223,11 @@ for color, desc in pairs(boxtypes) do _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, drawtype = "nodebox", - tiles = {"mcl_chests_blank.png"}, + node_box = { + type = "fixed", + fixed = {-0.48, -0.5, -0.48, 0.48, 0.489, 0.48}, + }, + tiles = {"blank.png^[resize:16x16"}, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, _chest_entity_textures = {mob_texture}, _chest_entity_sound = "mcl_chests_shulker", diff --git a/mods/ITEMS/mcl_chests/locale/mcl_chests.ja.tr b/mods/ITEMS/mcl_chests/locale/mcl_chests.ja.tr new file mode 100644 index 000000000..8f6525411 --- /dev/null +++ b/mods/ITEMS/mcl_chests/locale/mcl_chests.ja.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_chests +Chest=チェスト +Chests are containers which provide 27 inventory slots. Chests can be turned into large chests with double the capacity by placing two chests next to each other.=チェストは、27個のインベントリースロットを備える収納箱です。チェストを2つ並べると、2倍の容量を備えるラージチェストになります。 +To access its inventory, rightclick it. When broken, the items will drop out.=インベントリにアクセスするには、右クリックします。壊れると、アイテムがドロップアウトします。 +Trapped Chest=トラップチェスト +A trapped chest is a container which provides 27 inventory slots. When it is opened, it sends a redstone signal to its adjacent blocks as long it stays open. Trapped chests can be turned into large trapped chests with double the capacity by placing two trapped chests next to each other.=トラップチェストは、27個のインベントリースロットを備える収納箱です。それを開いている間は、隣接するブロックにレッドストーン信号を送ります。トラップチェストを2つ並べると、2倍の容量を備えるラージトラップチェストになります。 +Ender Chest=エンダーチェスト +Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players.=エンダーチェストからは、「ただ1つの、個人専用の次元間インベントリ」にアクセスできます。そのインベントリには27個のスロットが備わっています。どのエンダーチェストを開けても、そのただ1つのインベントリにアクセスする仕組みになっています。例えば、あるエンダーチェストにアイテムを入れておくと、他にあるどのエンダーチェストからでもそのアイテムが見え、取り出せます。このインベントリは各プレイヤー専用であるため、他のプレイヤーが開けた時は、そのプレイヤーには当人専用のインベントリが見えています。つまり他人のインベントリにはアクセスできません。 +Rightclick the ender chest to access your personal interdimensional inventory.=エンダーチェストを右クリックすると、個人専用の次元間インベントリにアクセスします。 +White Shulker Box=白色のシュルカーボックス +Light Grey Shulker Box=薄灰色のシュルカーボックス +Orange Shulker Box=橙色のシュルカーボックス +Cyan Shulker Box=青緑色のシュルカーボックス +Magenta Shulker Box=赤紫色のシュルカーボックス +Purple Shulker Box=紫色のシュルカーボックス +Light Blue Shulker Box=空色のシュルカーボックス +Blue Shulker Box=青色のシュルカーボックス +Yellow Shulker Box=黄色のシュルカーボックス +Brown Shulker Box=茶色のシュルカーボックス +Lime Shulker Box=黄緑色のシュルカーボックス +Green Shulker Box=緑色のシュルカーボックス +Pink Shulker Box=桃色のシュルカーボックス +Red Shulker Box=赤色のシュルカーボックス +Grey Shulker Box=灰色のシュルカーボックス +Black Shulker Box=黒色のシュルカーボックス +A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.=シュルカーボックスは、27個のインベントリスロットを備える「持ち運び可能な収納箱」で、シュルカーボックス以外のアイテムを保管できます。シュルカーボックスは壊れても、中身をドロップアウトせず保持したそのままで、1つのアイテムとしてドロップされます。それを回収し再設置できます。シュルカーボックスにはさまざまな色があります。 +To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.=シュルカーボックスのインベントリにアクセスするには、設置して右クリックします。シュルカーボックスとその中身を持ち運ぶには、壊して回収するだけです。中身はこぼれ落ちません。再びシュルカーボックスを置くと、中身を取り出せます。 +Shulker Box=シュルカーボックス +Large Chest=ラージチェスト +Inventory=インベントリ +27 inventory slots=27個のインベントリスロット +Can be carried around with its contents=中身を入れたまま持ち運び可能 +Can be combined to a large chest=ラージチェストに連結可能 +27 interdimensional inventory slots=27個の次元間インベントリスロット +Put items inside, retrieve them from any ender chest=中にアイテムを入れ、任意のエンダーチェストから取り出し可能 +Emits a redstone signal when opened=開くとレッドストーン信号を発する diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_chest.b3d b/mods/ITEMS/mcl_chests/models/mcl_chests_chest.b3d index e82c7e363..5cc1b8edc 100644 Binary files a/mods/ITEMS/mcl_chests/models/mcl_chests_chest.b3d and b/mods/ITEMS/mcl_chests/models/mcl_chests_chest.b3d differ diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_chest.obj b/mods/ITEMS/mcl_chests/models/mcl_chests_chest.obj deleted file mode 100644 index 36268146f..000000000 --- a/mods/ITEMS/mcl_chests/models/mcl_chests_chest.obj +++ /dev/null @@ -1,91 +0,0 @@ -# Blender v2.76 (sub 0) OBJ File: 'chest.small.facedir.blend' -# www.blender.org -mtllib chest.small.facedir.mtl -o chest_upper_upper -v 0.062513 -0.063134 -0.500468 -v 0.062513 0.186920 -0.500468 -v 0.062514 -0.063134 -0.437955 -v 0.062514 0.186920 -0.437955 -v -0.062514 -0.063134 -0.500468 -v -0.062514 0.186920 -0.500468 -v -0.062514 -0.063134 -0.437955 -v -0.062514 0.186920 -0.437955 -v 0.437907 0.061263 -0.438085 -v 0.437907 0.373830 -0.438085 -v 0.437907 0.061263 0.437729 -v 0.437907 0.373830 0.437729 -v -0.437907 0.061263 -0.438085 -v -0.437907 0.373830 -0.438085 -v -0.437907 0.061263 0.437729 -v -0.437907 0.373830 0.437729 -v 0.437595 -0.500754 -0.437772 -v 0.437595 0.124381 -0.437772 -v 0.437595 -0.500754 0.437417 -v 0.437595 0.124381 0.437417 -v -0.437595 -0.500754 -0.437772 -v -0.437595 0.124381 -0.437772 -v -0.437595 -0.500754 0.437417 -v -0.437595 0.124381 0.437417 -vt 0.015625 0.921875 -vt 0.015625 0.984375 -vt 0.000000 0.984375 -vt 0.000000 0.921875 -vt 0.093750 0.921875 -vt 0.093750 0.984375 -vt 0.062500 0.984375 -vt 0.062500 0.921875 -vt 0.046875 0.984375 -vt 0.046875 0.921875 -vt 0.078125 0.984375 -vt 0.078125 1.000000 -vt 0.046875 1.000000 -vt 0.015625 1.000000 -vt 0.218750 0.703125 -vt 0.218750 0.781250 -vt 0.000000 0.781250 -vt 0.000000 0.703125 -vt 0.875000 0.703125 -vt 0.875000 0.781250 -vt 0.656250 0.781250 -vt 0.656250 0.703125 -vt 0.437500 0.781250 -vt 0.437500 0.703125 -vt 0.656250 1.000000 -vt 0.437500 1.000000 -vt 0.218750 1.000000 -vt 0.218750 0.328125 -vt 0.218750 0.484375 -vt -0.000000 0.484375 -vt -0.000000 0.328125 -vt 0.875000 0.328125 -vt 0.875000 0.484375 -vt 0.656250 0.484375 -vt 0.656250 0.328125 -vt 0.437500 0.484375 -vt 0.437500 0.328125 -vn 1.000000 0.000000 -0.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -usemtl None -s off -f 1/1/1 2/2/1 4/3/1 3/4/1 -f 3/5/2 4/6/2 8/7/2 7/8/2 -f 7/8/3 8/7/3 6/9/3 5/10/3 -f 5/10/4 6/9/4 2/2/4 1/1/4 -f 3/9/5 7/11/5 5/12/5 1/13/5 -f 8/13/6 4/14/6 2/2/6 6/9/6 -f 9/15/1 10/16/1 12/17/1 11/18/1 -f 11/19/2 12/20/2 16/21/2 15/22/2 -f 15/22/3 16/21/3 14/23/3 13/24/3 -f 13/24/4 14/23/4 10/16/4 9/15/4 -f 11/25/5 15/26/5 13/23/5 9/21/5 -f 16/26/6 12/27/6 10/16/6 14/23/6 -f 17/28/1 18/29/1 20/30/1 19/31/1 -f 19/32/2 20/33/2 24/34/2 23/35/2 -f 23/35/3 24/34/3 22/36/3 21/37/3 -f 21/37/4 22/36/4 18/29/4 17/28/4 -f 19/22/5 23/24/5 21/36/5 17/34/5 -f 24/24/6 20/15/6 18/29/6 22/36/6 diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_chest_double.b3d b/mods/ITEMS/mcl_chests/models/mcl_chests_chest_double.b3d index 8d79b8ff7..578b3cb72 100644 Binary files a/mods/ITEMS/mcl_chests/models/mcl_chests_chest_double.b3d and b/mods/ITEMS/mcl_chests/models/mcl_chests_chest_double.b3d differ diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.b3d b/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.b3d index 2592f86a0..58508348a 100644 Binary files a/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.b3d and b/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.b3d differ diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.obj b/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.obj deleted file mode 100644 index ca12b682e..000000000 --- a/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.obj +++ /dev/null @@ -1,159 +0,0 @@ -# Blender v2.79 (sub 0) OBJ File: 'shulkerbox2.blend' -# www.blender.org -mtllib shulkerbox2.mtl -o low1_Cube.006 -v -0.500000 -0.500001 0.500000 -v -0.500000 0.062499 0.500000 -v -0.500000 -0.500001 -0.500000 -v -0.500000 0.062499 -0.500000 -v 0.500000 -0.500001 0.500000 -v 0.500000 0.062499 0.500000 -v 0.500000 -0.500001 -0.500000 -v 0.500000 0.062499 -0.500000 -vt 0.250000 0.187500 -vt -0.000000 0.187500 -vt -0.000000 0.312500 -vt 0.250000 0.312500 -vt 1.000000 0.187500 -vt 0.750000 0.187500 -vt 0.750000 0.312500 -vt 1.000000 0.312500 -vt 0.500000 0.187500 -vt 0.500000 0.312500 -vt 0.750000 0.562500 -vt 0.750000 0.312500 -vt 0.500000 0.312500 -vt 0.500000 0.562500 -vt 0.500000 0.562500 -vt 0.250000 0.562500 -vn 1.0000 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -usemtl None -s off -f 1/1/1 3/2/1 4/3/1 2/4/1 -f 3/5/2 7/6/2 8/7/2 4/8/2 -f 7/6/3 5/9/3 6/10/3 8/7/3 -f 5/9/4 1/1/4 2/4/4 6/10/4 -f 3/11/5 1/12/5 5/13/5 7/14/5 -f 8/15/6 6/10/6 2/4/6 4/16/6 -o top1_Cube.005 -v -0.500313 -0.220552 0.500313 -v -0.500313 0.530073 0.500313 -v -0.500313 -0.220552 -0.500313 -v -0.500313 0.530073 -0.500313 -v 0.500313 -0.220552 0.500313 -v 0.500313 0.530073 0.500313 -v 0.500313 -0.220552 -0.500313 -v 0.500313 0.530073 -0.500313 -vt 0.250000 0.562500 -vt -0.000000 0.562500 -vt -0.000000 0.750000 -vt 0.250000 0.750000 -vt 1.000000 0.562500 -vt 0.750000 0.562500 -vt 0.750000 0.750000 -vt 1.000000 0.750000 -vt 0.500000 0.562500 -vt 0.500000 0.750000 -vt 0.750000 1.000000 -vt 0.750000 0.750000 -vt 0.500000 0.750000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.250000 1.000000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -usemtl None -s off -f 9/17/7 11/18/7 12/19/7 10/20/7 -f 11/21/8 15/22/8 16/23/8 12/24/8 -f 15/22/9 13/25/9 14/26/9 16/23/9 -f 13/25/10 9/17/10 10/20/10 14/26/10 -f 11/27/11 9/28/11 13/29/11 15/30/11 -f 16/31/12 14/26/12 10/20/12 12/32/12 -o top2_Cube.002 -v -0.500247 -0.220392 0.500247 -v -0.500247 0.530234 0.500247 -v -0.500247 -0.220392 -0.500378 -v -0.500247 0.530234 -0.500378 -v 0.500378 -0.220392 0.500247 -v 0.500378 0.530234 0.500247 -v 0.500378 -0.220392 -0.500378 -v 0.500378 0.530234 -0.500378 -vt 0.250000 0.562500 -vt 0.250000 0.750000 -vt -0.000000 0.750000 -vt -0.000000 0.562500 -vt 1.000000 0.562500 -vt 1.000000 0.750000 -vt 0.750000 0.750000 -vt 0.750000 0.562500 -vt 0.500000 0.750000 -vt 0.500000 0.562500 -vt 0.750000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 0.750000 -vt 0.750000 0.750000 -vt 0.500000 1.000000 -vt 0.250000 1.000000 -vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 1.0000 0.0000 -usemtl None -s off -f 17/33/13 18/34/13 20/35/13 19/36/13 -f 19/37/14 20/38/14 24/39/14 23/40/14 -f 23/40/15 24/39/15 22/41/15 21/42/15 -f 21/42/16 22/41/16 18/34/16 17/33/16 -f 19/43/17 23/44/17 21/45/17 17/46/17 -f 24/47/18 20/48/18 18/34/18 22/41/18 -o low2_Cube.001 -v -0.499935 -0.499936 0.499935 -v -0.499935 0.062565 0.499935 -v -0.499935 -0.499936 -0.500066 -v -0.499935 0.062565 -0.500066 -v 0.500066 -0.499936 0.499935 -v 0.500066 0.062565 0.499935 -v 0.500066 -0.499936 -0.500066 -v 0.500066 0.062565 -0.500066 -vt 0.250000 0.187500 -vt 0.250000 0.312500 -vt -0.000000 0.312500 -vt -0.000000 0.187500 -vt 1.000000 0.187500 -vt 1.000000 0.312500 -vt 0.750000 0.312500 -vt 0.750000 0.187500 -vt 0.500000 0.312500 -vt 0.500000 0.187500 -vt 0.750000 0.562500 -vt 0.500000 0.562500 -vt 0.500000 0.312500 -vt 0.750000 0.312500 -vt 0.500000 0.562500 -vt 0.250000 0.562500 -vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 1.0000 0.0000 -usemtl None -s off -f 25/49/19 26/50/19 28/51/19 27/52/19 -f 27/53/20 28/54/20 32/55/20 31/56/20 -f 31/56/21 32/55/21 30/57/21 29/58/21 -f 29/58/22 30/57/22 26/50/22 25/49/22 -f 27/59/23 31/60/23 29/61/23 25/62/23 -f 32/63/24 28/64/24 26/50/24 30/57/24 diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_front.png b/mods/ITEMS/mcl_chests/textures/default_chest_front.png deleted file mode 100644 index 866a33984..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_front.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_front_big.png b/mods/ITEMS/mcl_chests/textures/default_chest_front_big.png deleted file mode 100644 index bde286673..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_front_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_side_big.png b/mods/ITEMS/mcl_chests/textures/default_chest_side_big.png deleted file mode 100644 index deb006807..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_side_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_top.png b/mods/ITEMS/mcl_chests/textures/default_chest_top.png deleted file mode 100644 index 5c1beb4b5..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_top_big.png b/mods/ITEMS/mcl_chests/textures/default_chest_top_big.png deleted file mode 100644 index de56e2cab..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_top_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_black_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_black_shulker_box_top.png deleted file mode 100644 index a8564e42e..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_black_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_blank.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_blank.png deleted file mode 100644 index baee128d4..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_blank.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_blue_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_blue_shulker_box_top.png deleted file mode 100644 index 608887df4..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_blue_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_brown_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_brown_shulker_box_top.png deleted file mode 100644 index 95b6cbdc8..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_brown_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_back.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_back.png deleted file mode 100644 index f347e921a..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_back.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_bottom.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_bottom.png deleted file mode 100644 index cb43e55e2..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_left.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_left.png deleted file mode 100644 index d420aaba0..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_left.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_right.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_right.png deleted file mode 100644 index 4536ada86..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_right.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_back.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_back.png deleted file mode 100644 index f347e921a..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_back.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_bottom.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_bottom.png deleted file mode 100644 index cb43e55e2..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front.png deleted file mode 100644 index 67cc716bd..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front_big.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front_big.png deleted file mode 100644 index b65bfc231..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_left.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_left.png deleted file mode 100644 index d420aaba0..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_left.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_right.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_right.png deleted file mode 100644 index 4536ada86..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_right.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_side_big.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_side_big.png deleted file mode 100644 index deb006807..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_side_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top.png deleted file mode 100644 index 5c1beb4b5..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top_big.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top_big.png deleted file mode 100644 index de56e2cab..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_cyan_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_cyan_shulker_box_top.png deleted file mode 100644 index d8fe60f50..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_cyan_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_green_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_green_shulker_box_top.png deleted file mode 100644 index a0d32088b..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_green_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_grey_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_grey_shulker_box_top.png deleted file mode 100644 index 8859361ec..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_grey_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_back.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_back.png deleted file mode 100644 index 7cfbe1d7d..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_back.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_bottom.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_bottom.png deleted file mode 100644 index 03a61a59c..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_front.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_front.png deleted file mode 100644 index bbc68e78b..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_front.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_left.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_left.png deleted file mode 100644 index 1a0ceaef2..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_left.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_right.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_right.png deleted file mode 100644 index f547532f2..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_right.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_top.png deleted file mode 100644 index c109aa826..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_green_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_green_shulker_box_top.png deleted file mode 100644 index 513612da9..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_green_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_grey_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_grey_shulker_box_top.png deleted file mode 100644 index e483f6ed7..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_grey_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_lightblue_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_lightblue_shulker_box_top.png deleted file mode 100644 index 9efc68fe0..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_lightblue_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_magenta_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_magenta_shulker_box_top.png deleted file mode 100644 index 9f167d4d9..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_magenta_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_orange_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_orange_shulker_box_top.png deleted file mode 100644 index 166f9c3da..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_orange_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_pink_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_pink_shulker_box_top.png deleted file mode 100644 index a69548c31..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_pink_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_red_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_red_shulker_box_top.png deleted file mode 100644 index 8c458cdd9..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_red_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_violet_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_violet_shulker_box_top.png deleted file mode 100644 index eb461d395..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_violet_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_white_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_white_shulker_box_top.png deleted file mode 100644 index 8c12525bd..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_white_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_yellow_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_yellow_shulker_box_top.png deleted file mode 100644 index 5e657412d..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_yellow_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/locale/mcl_clock.ja.tr b/mods/ITEMS/mcl_clock/locale/mcl_clock.ja.tr new file mode 100644 index 000000000..454788a29 --- /dev/null +++ b/mods/ITEMS/mcl_clock/locale/mcl_clock.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_clock +Clocks are tools which shows the current time of day in the Overworld.=時計は、オーバーワールドの現在時刻を表示する道具です。 +The clock contains a rotating disc with a sun symbol (yellow disc) and moon symbol and a little “pointer” which shows the current time of day by estimating the real position of the sun and the moon in the sky. Noon is represented by the sun symbol and midnight is represented by the moon symbol.=この時計は、太陽マーク(黄色い円)と月マークが描かれた回転ディスクと、小さな「ポインター」で構成されています。太陽と月の位置から現在時刻を推定しましょう。ポインターにちょうど太陽マークがきた時が正午、月マークなら零時です。 +Clock=時計 +Displays the time of day in the Overworld=オーバーワールドの現在時刻を表示 diff --git a/mods/ITEMS/mcl_cocoas/init.lua b/mods/ITEMS/mcl_cocoas/init.lua index 60ea9e573..0792972be 100644 --- a/mods/ITEMS/mcl_cocoas/init.lua +++ b/mods/ITEMS/mcl_cocoas/init.lua @@ -3,7 +3,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) mcl_cocoas = {} -- Place cocoa -function mcl_cocoas.place(itemstack, placer, pt, plantname) +local function cocoa_place(itemstack, placer, pt, plantname) -- check if pointing at a node if not pt or pt.type ~= "node" then return @@ -62,36 +62,21 @@ function mcl_cocoas.grow(pos) return false end --- Note: cocoa beans are implemented as mcl_dye:brown - -- Cocoa definition -- 1st stage - ---[[ TODO: Use a mesh for cocoas for perfect texture compability. ]] local crop_def = { description = S("Premature Cocoa Pod"), _doc_items_create_entry = true, _doc_items_longdesc = S("Cocoa pods grow on the side of jungle trees in 3 stages."), - drawtype = "nodebox", - tiles = { - "[combine:16x16:6,1=mcl_cocoas_cocoa_stage_0.png", "[combine:16x16:6,11=mcl_cocoas_cocoa_stage_0.png", - "mcl_cocoas_cocoa_stage_0.png", "mcl_cocoas_cocoa_stage_0.png^[transformFX", - "[combine:16x16:-5,0=mcl_cocoas_cocoa_stage_0.png", "[combine:16x16:-5,0=mcl_cocoas_cocoa_stage_0.png", - }, + drawtype = "mesh", + mesh = "mcl_cocoas_cocoa_stage_0.obj", + tiles = {"mcl_cocoas_cocoa_stage_0.png"}, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", walkable = true, - drop = "mcl_dye:brown", - node_box = { - type = "fixed", - fixed = { - {-0.125, -0.0625, 0.1875, 0.125, 0.25, 0.4375}, -- Pod - -- FIXME: This has a thickness of 0. Is this OK in Minetest? - {0, 0.25, 0.25, 0, 0.5, 0.5}, -- Stem - }, - }, + drop = "mcl_cocoas:cocoa_beans", collision_box = { type = "fixed", fixed = { @@ -105,7 +90,11 @@ local crop_def = { }, }, groups = { - handy=1,axey=1, cocoa=1, not_in_creative_inventory=1, dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1, attached_node_facedir=1, + handy = 1, axey = 1, + dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1, + attached_node_facedir=1, + not_in_creative_inventory=1, + cocoa=1 }, sounds = mcl_sounds.node_sound_wood_defaults(), on_rotate = false, @@ -119,18 +108,8 @@ minetest.register_node("mcl_cocoas:cocoa_1", table.copy(crop_def)) crop_def.description = S("Medium Cocoa Pod") crop_def._doc_items_create_entry = false crop_def.groups.cocoa = 2 -crop_def.tiles = { - "[combine:16x16:5,1=mcl_cocoas_cocoa_stage_1.png", "[combine:16x16:5,9=mcl_cocoas_cocoa_stage_1.png", - "mcl_cocoas_cocoa_stage_1.png", "mcl_cocoas_cocoa_stage_1.png^[transformFX", - "[combine:16x16:-4,0=mcl_cocoas_cocoa_stage_1.png", "[combine:16x16:-4,0=mcl_cocoas_cocoa_stage_1.png", -} -crop_def.node_box = { - type = "fixed", - fixed = { - {-0.1875, -0.1875, 0.0625, 0.1875, 0.25, 0.4375}, -- Pod - {0, 0.25, 0.25, 0, 0.5, 0.5}, -- Stem - }, -} +crop_def.mesh = "mcl_cocoas_cocoa_stage_1.obj" +crop_def.tiles = {"mcl_cocoas_cocoa_stage_1.png"} crop_def.collision_box = { type = "fixed", fixed = { @@ -151,20 +130,8 @@ crop_def.description = S("Mature Cocoa Pod") crop_def._doc_items_longdesc = S("A mature cocoa pod grew on a jungle tree to its full size and it is ready to be harvested for cocoa beans. It won't grow any further.") crop_def._doc_items_create_entry = true crop_def.groups.cocoa = 3 -crop_def.tiles = { - -- The following 2 textures were derived from the original because the size of the top/bottom is slightly different :-( - -- TODO: Find a way to *only* use the base texture - "mcl_cocoas_cocoa_top_stage_2.png", "mcl_cocoas_cocoa_top_stage_2.png^[transformFY", - "mcl_cocoas_cocoa_stage_2.png", "mcl_cocoas_cocoa_stage_2.png^[transformFX", - "[combine:16x16:-3,0=mcl_cocoas_cocoa_stage_2.png", "[combine:16x16:-3,0=mcl_cocoas_cocoa_stage_2.png", -} -crop_def.node_box = { - type = "fixed", - fixed = { - {-0.25, -0.3125, -0.0625, 0.25, 0.25, 0.4375}, -- Pod - {0, 0.25, 0.25, 0, 0.5, 0.5}, -- Stem - }, -} +crop_def.mesh = "mcl_cocoas_cocoa_stage_2.obj" +crop_def.tiles = {"mcl_cocoas_cocoa_stage_2.png"} crop_def.collision_box = { type = "fixed", fixed = { @@ -177,9 +144,20 @@ crop_def.selection_box = { {-0.25, -0.3125, -0.0625, 0.25, 0.5, 0.5}, }, } -crop_def.drop = "mcl_dye:brown 3" +crop_def.drop = "mcl_cocoas:cocoa_beans 3" minetest.register_node("mcl_cocoas:cocoa_3", table.copy(crop_def)) +minetest.register_craftitem("mcl_cocoas:cocoa_beans", { + description = S("Cocoa Beans"), + _tt_help = S("Grows at the side of jungle trees"), + _doc_items_longdesc = S("Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye."), + _doc_items_usagehelp = S("Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa."), + inventory_image = "mcl_cocoas_cocoa_beans.png", + groups = {craftitem = 1, compostability = 65}, + on_place = function(itemstack, placer, pointed_thing) + return cocoa_place(itemstack, placer, pointed_thing, "mcl_cocoas:cocoa_1") + end, +}) minetest.register_abm({ label = "Cocoa pod growth", @@ -197,4 +175,3 @@ minetest.register_abm({ if minetest.get_modpath("doc") then doc.add_entry_alias("nodes", "mcl_cocoas:cocoa_1", "nodes", "mcl_cocoas:cocoa_2") end - diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.de.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.de.tr index 479e3845e..3740c41cf 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.de.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.de.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Kakaobohnen +Grows at the side of jungle trees=Wächst an der Seite von Dschungelbäumen +Cocoa beans can be used to plant cocoa pods, bake chocolate cookies or craft brown dye.=Kakaobohnen können benutzt werden, um Kakao anzupflanzen, Kekse zu backen oder braune Farbstoffe herzustellen. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Rechtsklicken Sie an die Seite eines Dschungelbaumstamms (Dschungelholz), um eine junge Kakaoschote zu pflanzen. Premature Cocoa Pod=Junge Kakaoschote Cocoa pods grow on the side of jungle trees in 3 stages.=Kakaoschoten wachsen an der Seite von Dschungelbäumen in 3 Stufen. Medium Cocoa Pod=Mittelgroße Kakaoschote diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.es.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.es.tr index e1477c79c..c76fc512f 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.es.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.es.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Granos de cacao +Grows at the side of jungle trees=Crece al lado de los árboles de la jungla +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Los granos de cacao se pueden usar para plantar cacao, hornear galletas o hacer tintes marrones. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Haga clic derecho en el costado del tronco de un árbol de la jungla para plantar un cacao joven. Premature Cocoa Pod=Vaina de cacao prematura Cocoa pods grow on the side of jungle trees in 3 stages.=Las vainas de cacao crecen al lado de los árboles de jungla en 3 etapas. Medium Cocoa Pod=Vaina de cacao mediana diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.fr.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.fr.tr index bf5468953..5d64eb5be 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.fr.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.fr.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Fèves de Cacao +Grows at the side of jungle trees=Pousse à côté des arbres de la jungle +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Les fèves de cacao peuvent être utilisées pour planter du cacao, faire des biscuits ou fabriquer de la teinture brune. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Clic droit sur le côté d'un tronc d'arbre de la jungle (Bois Acajou) pour planter un jeune cacaoyer. Premature Cocoa Pod=Gousse de cacao prématurée Cocoa pods grow on the side of jungle trees in 3 stages.=Les cabosses de cacao poussent sur le côté des arbres d'Acajou en 3 étapes. Medium Cocoa Pod=Gousse de cacao moyenne diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ja.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ja.tr new file mode 100644 index 000000000..56117c811 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ja.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_cocoas +Premature Cocoa Pod=未成熟なカカオの実 +Cocoa pods grow on the side of jungle trees in 3 stages.=カカオの実は、ジャングルの木の側面に3段階で成長します。 +Medium Cocoa Pod=成熟しつつあるカカオの実 +Mature Cocoa Pod=成熟したカカオの実 +A mature cocoa pod grew on a jungle tree to its full size and it is ready to be harvested for cocoa beans. It won't grow any further.=成熟したカカオの実は、ジャングルの木で最大まで成長し、カカオ豆を収穫できるようになった状態です。これ以上は成長しません。 diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pl.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pl.tr index bfd0d707e..83df9be7a 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pl.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pl.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Ziarna kakaowe +Grows at the side of jungle trees=Rośnie na boku tropikalnych drzew +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Ziarna kakaowe mogą być używane do sadzenia kakao, pieczenia ciasteczek lub robienia brązowego barwnika. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao. Premature Cocoa Pod=Niedojrzała roślina kakao Cocoa pods grow on the side of jungle trees in 3 stages.=Roślina kakao rośnie na bokach tropikalnych drzew w 3 etapach Medium Cocoa Pod=Średnio-dojrzała roślina kakao diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr index 524c28bcc..064c01fd3 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Какао-бобы +Grows at the side of jungle trees=Растут на стволах деревьев джунглей +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Какао-бобы можно использовать для посадки какао, выпечки печенья или изготовления коричневого красителя. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по боковой части ствола дерева джунглей, чтобы посадить молодое какао. Premature Cocoa Pod=Молодой стручок какао Cocoa pods grow on the side of jungle trees in 3 stages.=Стручки какао растут на деревьях джунглей в 3 этапа. Medium Cocoa Pod=Средний стручок какао diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr index d71e2b11b..038746155 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=可可豆 +Grows at the side of jungle trees=在叢林木側生長 +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=可可豆可用於種植可可、烘烤餅乾或製作棕色染料。 +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=右鍵點擊叢林木的一側,可以種植一個可可。 Premature Cocoa Pod=成長中的可可豆莢(第1階段) Cocoa pods grow on the side of jungle trees in 3 stages.=可可莢果分3個階段生長在叢林樹的側面。 Medium Cocoa Pod=成長中的可可豆莢(第2階段) diff --git a/mods/ITEMS/mcl_cocoas/locale/template.txt b/mods/ITEMS/mcl_cocoas/locale/template.txt index f68318cae..cb8c5bbfd 100644 --- a/mods/ITEMS/mcl_cocoas/locale/template.txt +++ b/mods/ITEMS/mcl_cocoas/locale/template.txt @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans= +Grows at the side of jungle trees= +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.= +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.= Premature Cocoa Pod= Cocoa pods grow on the side of jungle trees in 3 stages.= Medium Cocoa Pod= diff --git a/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_0.obj b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_0.obj new file mode 100644 index 000000000..35dbb2d00 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_0.obj @@ -0,0 +1,95 @@ +# Made in Blockbench 4.5.1 +mtllib Cocoa Pod 0.mtl + +o cube +v 0.125 0.25 0.4375 +v 0.125 0.25 0.1875 +v 0.125 -0.0625 0.4375 +v 0.125 -0.0625 0.1875 +v -0.125 0.25 0.1875 +v -0.125 0.25 0.4375 +v -0.125 -0.0625 0.1875 +v -0.125 -0.0625 0.4375 +vt 0.6875 0.75 +vt 0.9375 0.75 +vt 0.9375 0.4375 +vt 0.6875 0.4375 +vt 0.6875 0.75 +vt 0.9375 0.75 +vt 0.9375 0.4375 +vt 0.6875 0.4375 +vt 0.6875 0.75 +vt 0.9375 0.75 +vt 0.9375 0.4375 +vt 0.6875 0.4375 +vt 0.6875 0.75 +vt 0.9375 0.75 +vt 0.9375 0.4375 +vt 0.6875 0.4375 +vt 0 1 +vt 0.25 1 +vt 0.25 0.75 +vt 0 0.75 +vt 0 1 +vt 0.25 1 +vt 0.25 0.75 +vt 0 0.75 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_a7cd0525-4079-c203-6c53-7d43da5fa1e5 +f 4/4/1 7/3/1 5/2/1 2/1/1 +f 3/8/2 4/7/2 2/6/2 1/5/2 +f 8/12/3 3/11/3 1/10/3 6/9/3 +f 7/16/4 8/15/4 6/14/4 5/13/4 +f 6/20/5 1/19/5 2/18/5 5/17/5 +f 7/24/6 4/23/6 3/22/6 8/21/6 +o cube +v 0 0.5 0.5 +v 0 0.5 0.25 +v 0 0.25 0.5 +v 0 0.25 0.25 +v 0 0.5 0.25 +v 0 0.5 0.5 +v 0 0.25 0.25 +v 0 0.25 0.5 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0.75 1 +vt 1 1 +vt 1 0.75 +vt 0.75 0.75 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_a7cd0525-4079-c203-6c53-7d43da5fa1e5 +f 12/28/7 15/27/7 13/26/7 10/25/7 +f 11/32/8 12/31/8 10/30/8 9/29/8 +f 16/36/9 11/35/9 9/34/9 14/33/9 +f 15/40/10 16/39/10 14/38/10 13/37/10 +f 14/44/11 9/43/11 10/42/11 13/41/11 +f 15/48/12 12/47/12 11/46/12 16/45/12 \ No newline at end of file diff --git a/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_1.obj b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_1.obj new file mode 100644 index 000000000..2a5277856 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_1.obj @@ -0,0 +1,95 @@ +# Made in Blockbench 4.5.1 +mtllib Cocoa Pod 1.mtl + +o cube +v 0.1875 0.25 0.4375 +v 0.1875 0.25 0.0625 +v 0.1875 -0.1875 0.4375 +v 0.1875 -0.1875 0.0625 +v -0.1875 0.25 0.0625 +v -0.1875 0.25 0.4375 +v -0.1875 -0.1875 0.0625 +v -0.1875 -0.1875 0.4375 +vt 0.5625 0.75 +vt 0.9375 0.75 +vt 0.9375 0.3125 +vt 0.5625 0.3125 +vt 0.5625 0.75 +vt 0.9375 0.75 +vt 0.9375 0.3125 +vt 0.5625 0.3125 +vt 0.5625 0.75 +vt 0.9375 0.75 +vt 0.9375 0.3125 +vt 0.5625 0.3125 +vt 0.5625 0.75 +vt 0.9375 0.75 +vt 0.9375 0.3125 +vt 0.5625 0.3125 +vt 0 1 +vt 0.375 1 +vt 0.375 0.625 +vt 0 0.625 +vt 0 1 +vt 0.375 1 +vt 0.375 0.625 +vt 0 0.625 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_3316e529-b95a-149b-2db3-3eee58b06c25 +f 4/4/1 7/3/1 5/2/1 2/1/1 +f 3/8/2 4/7/2 2/6/2 1/5/2 +f 8/12/3 3/11/3 1/10/3 6/9/3 +f 7/16/4 8/15/4 6/14/4 5/13/4 +f 6/20/5 1/19/5 2/18/5 5/17/5 +f 7/24/6 4/23/6 3/22/6 8/21/6 +o cube +v 0 0.5 0.5 +v 0 0.5 0.25 +v 0 0.25 0.5 +v 0 0.25 0.25 +v 0 0.5 0.25 +v 0 0.5 0.5 +v 0 0.25 0.25 +v 0 0.25 0.5 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0.75 1 +vt 1 1 +vt 1 0.75 +vt 0.75 0.75 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_3316e529-b95a-149b-2db3-3eee58b06c25 +f 12/28/7 15/27/7 13/26/7 10/25/7 +f 11/32/8 12/31/8 10/30/8 9/29/8 +f 16/36/9 11/35/9 9/34/9 14/33/9 +f 15/40/10 16/39/10 14/38/10 13/37/10 +f 14/44/11 9/43/11 10/42/11 13/41/11 +f 15/48/12 12/47/12 11/46/12 16/45/12 \ No newline at end of file diff --git a/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_2.obj b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_2.obj new file mode 100644 index 000000000..8dfd20af1 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_2.obj @@ -0,0 +1,95 @@ +# Made in Blockbench 4.5.1 +mtllib Cocoa Pod 2 Fixed.mtl + +o cube +v 0.25 0.25 0.4375 +v 0.25 0.25 -0.0625 +v 0.25 -0.3125 0.4375 +v 0.25 -0.3125 -0.0625 +v -0.25 0.25 -0.0625 +v -0.25 0.25 0.4375 +v -0.25 -0.3125 -0.0625 +v -0.25 -0.3125 0.4375 +vt 0.5 0.75 +vt 1 0.75 +vt 1 0.1875 +vt 0.5 0.1875 +vt 0.5 0.75 +vt 1 0.75 +vt 1 0.1875 +vt 0.5 0.1875 +vt 0.5 0.75 +vt 1 0.75 +vt 1 0.1875 +vt 0.5 0.1875 +vt 0.5 0.75 +vt 1 0.75 +vt 1 0.1875 +vt 0.5 0.1875 +vt 0 1 +vt 0.5 1 +vt 0.5 0.5 +vt 0 0.5 +vt 0 1 +vt 0.5 1 +vt 0.5 0.5 +vt 0 0.5 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_9809ffe0-030e-1955-c510-8df6b242b4e2 +f 4/4/1 7/3/1 5/2/1 2/1/1 +f 3/8/2 4/7/2 2/6/2 1/5/2 +f 8/12/3 3/11/3 1/10/3 6/9/3 +f 7/16/4 8/15/4 6/14/4 5/13/4 +f 6/20/5 1/19/5 2/18/5 5/17/5 +f 7/24/6 4/23/6 3/22/6 8/21/6 +o cube +v 0 0.5 0.5 +v 0 0.5 0.25 +v 0 0.25 0.5 +v 0 0.25 0.25 +v 0 0.5 0.25 +v 0 0.5 0.5 +v 0 0.25 0.25 +v 0 0.25 0.5 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0.75 1 +vt 1 1 +vt 1 0.75 +vt 0.75 0.75 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_9809ffe0-030e-1955-c510-8df6b242b4e2 +f 12/28/7 15/27/7 13/26/7 10/25/7 +f 11/32/8 12/31/8 10/30/8 9/29/8 +f 16/36/9 11/35/9 9/34/9 14/33/9 +f 15/40/10 16/39/10 14/38/10 13/37/10 +f 14/44/11 9/43/11 10/42/11 13/41/11 +f 15/48/12 12/47/12 11/46/12 16/45/12 \ No newline at end of file diff --git a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_beans.png b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_beans.png new file mode 100644 index 000000000..877ee69dc Binary files /dev/null and b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_beans.png differ diff --git a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_0.png b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_0.png index de58245f4..37510cb52 100644 Binary files a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_0.png and b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_0.png differ diff --git a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_2.png b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_2.png index 47bc159b7..c5f2c17fc 100644 Binary files a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_2.png and b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_2.png differ diff --git a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_top_stage_2.png b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_top_stage_2.png deleted file mode 100644 index 4e12f623b..000000000 Binary files a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_top_stage_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ja.tr b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ja.tr new file mode 100644 index 000000000..153b1a55a --- /dev/null +++ b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ja.tr @@ -0,0 +1,76 @@ +# textdomain: mcl_colorblocks +White Terracotta=白色のテラコッタ +White Glazed Terracotta=白色の彩釉テラコッタ +White Concrete Powder=白色のコンクリートパウダー +White Concrete=白色のコンクリート +Grey Terracotta=灰色のテラコッタ +Grey Glazed Terracotta=灰色の彩釉テラコッタ +Grey Concrete Powder=灰色のコンクリートパウダー +Grey Concrete=灰色のコンクリート +Light Grey Terracotta=薄灰色のテラコッタ +Light Grey Glazed Terracotta=薄灰色の彩釉テラコッタ +Light Grey Concrete Powder=薄灰色のコンクリートパウダー +Light Grey Concrete=薄灰色のコンクリート +Black Terracotta=黒色のテラコッタ +Black Glazed Terracotta=黒色の彩釉テラコッタ +Black Concrete Powder=黒色のコンクリートパウダー +Black Concrete=黒色のコンクリート +Red Terracotta=赤色のテラコッタ +Red Glazed Terracotta=赤色の彩釉テラコッタ +Red Concrete Powder=赤色のコンクリートパウダー +Red Concrete=赤色のコンクリート +Yellow Terracotta=黄色のテラコッタ +Yellow Glazed Terracotta=黄色の彩釉テラコッタ +Yellow Concrete Powder=黄色のコンクリートパウダー +Yellow Concrete=黄色のコンクリート +Green Terracotta=緑色のテラコッタ +Green Glazed Terracotta=緑色の彩釉テラコッタ +Green Concrete Powder=緑色のコンクリートパウダー +Green Concrete=緑色のコンクリート +Cyan Terracotta=青緑色のテラコッタ +Cyan Glazed Terracotta=青緑色の彩釉テラコッタ +Cyan Concrete Powder=青緑色のコンクリートパウダー +Cyan Concrete=青緑色のコンクリート +Blue Terracotta=青色のテラコッタ +Blue Glazed Terracotta=青色の彩釉テラコッタ +Blue Concrete Powder=青色のコンクリートパウダー +Blue Concrete=青色のコンクリート +Magenta Terracotta=赤紫色のテラコッタ +Magenta Glazed Terracotta=赤紫色の彩釉テラコッタ +Magenta Concrete Powder=赤紫色のコンクリートパウダー +Magenta Concrete=赤紫色のコンクリート +Orange Terracotta=橙色のテラコッタ +Orange Glazed Terracotta=橙色の彩釉テラコッタ +Orange Concrete Powder=橙色のコンクリートパウダー +Orange Concrete=橙色のコンクリート +Purple Terracotta=紫色のテラコッタ +Purple Glazed Terracotta=紫色の彩釉テラコッタ +Purple Concrete Powder=紫色のコンクリートパウダー +Purple Concrete=紫色のコンクリート +Brown Terracotta=茶色のテラコッタ +Brown Glazed Terracotta=茶色の彩釉テラコッタ +Brown Concrete Powder=茶色のコンクリートパウダー +Brown Concrete=茶色のコンクリート +Pink Terracotta=桃色のテラコッタ +Pink Glazed Terracotta=桃色の彩釉テラコッタ +Pink Concrete Powder=桃色のコンクリートパウダー +Pink Concrete=桃色のコンクリート +Lime Terracotta=黄緑色のテラコッタ +Lime Glazed Terracotta=黄緑色の彩釉テラコッタ +Lime Concrete Powder=黄緑色のコンクリートパウダー +Lime Concrete=黄緑色のコンクリート +Light Blue Terracotta=空色のテラコッタ +Light Blue Glazed Terracotta=空色の彩釉テラコッタ +Light Blue Concrete Powder=空色のコンクリートパウダー +Light Blue Concrete=空色のコンクリート +Terracotta is a basic building material. It comes in many different colors.=テラコッタは基本的な建築材料です。さまざまな色があります。 +Glazed terracotta is a decorative block with a complex pattern. It can be rotated by placing it in different directions.=彩釉テラコッタは、複雑な模様の装飾ブロックです。 配置するときの向きによって回転が可能です。 +Concrete powder is used for creating concrete, but it can also be used as decoration itself. It comes in different colors. Concrete powder turns into concrete of the same color when it comes in contact with water.=コンクリートパウダーはコンクリートを作るために使われますが、それ自体も色とりどりの装飾として使えます。コンクリートパウダーは、水に触れると同じ色のコンクリートに変化します。 +Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.=コンクリートは、さまざまな色がある装飾ブロックです。非常に強く、すっきりとした色合いで知られます。 +Terracotta=テラコッタ +Terracotta is a basic building material which comes in many different colors. This particular block is uncolored.=テラコッタは基本的な建築材料で、さまざまな色があります。このブロックは無着色です。 +Colored Terracotta=色付きテラコッタ +Glazed Terracotta=彩釉テラコッタ +Concrete Powder=コンクリートパウダー +Concrete=コンクリート +Turns into concrete on water contact=水との接触でコンクリートに変化 diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index 0bcc3f0af..2905c0b3b 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -16,6 +16,13 @@ local compass_types = { tt = S("Points to a lodestone"), longdesc = S("Lodestone compasses resemble regular compasses, but they point to a specific lodestone."), usagehelp = S("A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone."), + }, + { + name = "compass_recovery", + desc = S("Recovery Compass"), + tt = S("Points to your last death location"), + longdesc = S("Recovery Compasses are compasses that point to your last death location"), + usagehelp = S("Recovery Compasses always point to the location of your last death, in case you haven't died yet, it will just randomly spin around"), } } @@ -182,18 +189,35 @@ minetest.register_globalstep(function(dtime) inv = player:get_inventory() for j, stack in pairs(inv:get_list("main")) do compass_nr = get_item_group(stack:get_name(), "compass") - if compass_nr ~= 0 then + if compass_nr ~= 0 and not string_find(stack:get_name(), "_recovery") then -- check if current compass image still matches true orientation compass_frame = get_compass_frame(pos, dir, stack) if compass_nr - 1 ~= compass_frame then if string_find(stack:get_name(), "_lodestone") then stack:set_name("mcl_compass:" .. compass_frame .. "_lodestone") + awards.unlock(player:get_player_name(), "mcl:countryLode") else stack:set_name("mcl_compass:" .. compass_frame) end inv:set_stack("main", j, stack) end + elseif compass_nr ~= 0 then + local meta = player:get_meta() + local posstring = meta:get_string("mcl_compass:recovery_pos") + if not posstring or posstring == "" then + stack:set_name("mcl_compass:"..random_frame .. "_recovery") + else + local targetpos = minetest.string_to_pos(posstring) + local _, target_dim = y_to_layer(targetpos.y) + local _, p_dim = y_to_layer(pos.y) + if p_dim ~= target_dim then + stack:set_name("mcl_compass:"..random_frame.."_recovery") + else + stack:set_name("mcl_compass:"..get_compass_angle(pos,targetpos,dir).."_recovery") + end + end + inv:set_stack("main",j,stack) end end end @@ -212,6 +236,9 @@ for _, item in pairs(compass_types) do elseif item.name == "compass_lodestone" then name_fmt = "mcl_compass:%d_lodestone" img_fmt = "mcl_compass_compass_%02d.png^[colorize:purple:50" + elseif item.name == "compass_recovery" then + name_fmt = "mcl_compass:%d_recovery" + img_fmt = "mcl_compass_recovery_compass_%02d.png" end for i = 0, compass_frames - 1 do local itemstring = string.format(name_fmt, i) @@ -250,6 +277,16 @@ minetest.register_craft({ } }) +minetest.register_craft({ --TODO: update once echo shards are a thing + output = "mcl_compass:" .. random_frame .. "_recovery", + recipe = { + {"","mcl_nether:netherite_ingot",""}, + {"mcl_core:diamondblock","mcl_compass:" .. stereotype_frame ,"mcl_core:diamondblock"}, + {"mcl_core:diamondblock","mcl_core:diamondblock","mcl_core:diamondblock"} + + } +}) + minetest.register_alias("mcl_compass:compass", "mcl_compass:" .. stereotype_frame) @@ -284,7 +321,13 @@ minetest.register_craft({ output = "mcl_compass:lodestone", recipe = { {"mcl_core:stonebrickcarved","mcl_core:stonebrickcarved","mcl_core:stonebrickcarved"}, - {"mcl_core:stonebrickcarved", "mcl_core:diamondblock", "mcl_core:stonebrickcarved"}, + {"mcl_core:stonebrickcarved", "mcl_nether:netherite_ingot", "mcl_core:stonebrickcarved"}, {"mcl_core:stonebrickcarved", "mcl_core:stonebrickcarved", "mcl_core:stonebrickcarved"} } }) + +--set recovery meta +minetest.register_on_dieplayer(function(player) + local meta = player:get_meta(); + meta:set_string("mcl_compass:recovery_pos",minetest.pos_to_string(player:get_pos())) +end) \ No newline at end of file diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr index 9e0366508..9ae821e2b 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr @@ -7,3 +7,7 @@ Lodestone Compass=Leitstein Kompass Points to a lodestone=Zeigt zu einem Leitstein Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=Leitstein Kompasse ähneln normalen Kompassen, aber sie zeigen zu einen spezifischen Leitstein. A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.=Ein Leitstein Kompass kann mit einem normalen Kompass erstellt werden indem man ihn auf einem Leitstein benutzt. Nachdem er ein Leitstein Kompass geworden ist, wird er immer zu seinem Leitstein zeigen, sofern sie in der selben Dimension sind. Wenn sie nicht in der selben Dimension sind, dreht sich der Leitstein Kompass zufällig, wie ein normaler Kompass außerhalb der Oberwelt. Ein Leitstein Kompass kann mit einem anderem Leitstein verknüpft werden. +Recovery Compass=Wiederherstellungskompass +Points to your last death location=Zeigt zu dem Ort, an dem Sie zuletzt verendet sind +Recovery Compasses are compasses that point to your last death location=Wiederhelstellungskompasse sind Kompasse, die zu dem Ort zeigen, an dem Sie zuletzt gestorben sind +Recovery Compasses always point to the location of your last death, in case you haven't died yet, it will just randomly spin around=Wiederherstellungskompasse zeigen immer zu dem Ort Ihres letzten Todes, falls Sie noch nicht gestorben sind drehen sie sich zufällig diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr index c09b334a0..77d249087 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr @@ -2,8 +2,9 @@ Compass=Boussole Points to the world origin=Pointe vers l'origine mondiale Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Les boussoles sont des outils qui pointent vers l'origine du monde (X@=0,Z@=0) ou le point d'apparition dans l'Overworld. -A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= -Lodestone Compass= -Points to a lodestone= -Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= -A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.=Une boussole pointe toujours vers le point d'apparition quand le joueur est dans l'overworld. Dans d'autres dimensions elle tourne au hasard. +Lodestone Compass=Boussole magnétisée +Points to a lodestone=Pointe vers une magnétite +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=Les boussoles magnétisées ressemblent à des boussoles normales, mais pointent vers une magnétite spécifique. +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.=Une boussole magnétisée peut être crée à partir d'une boussole normale en l'utilisant sur une magnétite. Après être devenue une boussole magnétisée, elle pointera toujours vers sa magnétite liée, pourvu qu'elle soit dans la même dimension. Si ce n'est pas le cas, la boussole magnétisée tourne au hasard, comme une boussole normale hors de l'overworld. Une boussole magnétisée peut être liée à une autre magnétite. +Lodestone=Magnétite \ No newline at end of file diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.ja.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.ja.tr new file mode 100644 index 000000000..00783e840 --- /dev/null +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.ja.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_compass +Compass=コンパス +Points to the world origin=ワールドの原点を指す +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=コンパスは、ワールドの原点(X@=0, Z@=0)、またはオーバーワールドのスポーン地点を示す道具です。 +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.=コンパスはプレイヤーがオーバーワールドにいるとき、常にワールドのスポーン地点を指します。 他の次元では、ランダムに回転します。 +Lodestone Compass=ロードストーンコンパス +Points to a lodestone=ロードストーンを指す +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=ロードストーンコンパスは通常のコンパスに似ていますが、それが示すのは特定のロードストーンです。 +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.=ロードストーンコンパスは、ロードストーンの上で通常のコンパスを使用することにより作成できます。 ロードストーンコンパスとなった後は、同じ次元にあるならば、常にリンクしたロードストーンを指すようになります。同じ次元にない場合、オーバーワールド外の通常コンパスと同様、ランダムに回転します。 ロードストーンコンパスは他のロードストーンとの再リンクが可能です。 +Lodestone=ロードストーン diff --git a/mods/ITEMS/mcl_compass/locale/template.txt b/mods/ITEMS/mcl_compass/locale/template.txt index 909e21a36..f41485dea 100644 --- a/mods/ITEMS/mcl_compass/locale/template.txt +++ b/mods/ITEMS/mcl_compass/locale/template.txt @@ -7,3 +7,4 @@ Lodestone Compass= Points to a lodestone= Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= +Lodestone= diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_00.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_00.png new file mode 100644 index 000000000..c72810180 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_00.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_01.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_01.png new file mode 100644 index 000000000..e5a5d82b7 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_01.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_02.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_02.png new file mode 100644 index 000000000..6488b7e3a Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_02.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_03.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_03.png new file mode 100644 index 000000000..4696c8715 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_03.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_04.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_04.png new file mode 100644 index 000000000..594092651 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_04.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_05.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_05.png new file mode 100644 index 000000000..9d0963cfb Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_05.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_06.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_06.png new file mode 100644 index 000000000..a2f675fac Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_06.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_07.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_07.png new file mode 100644 index 000000000..1356e696a Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_07.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_08.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_08.png new file mode 100644 index 000000000..8690c1b15 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_08.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_09.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_09.png new file mode 100644 index 000000000..d13c518e7 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_09.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_10.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_10.png new file mode 100644 index 000000000..48ed5bcaa Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_10.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_11.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_11.png new file mode 100644 index 000000000..edbcfdb87 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_11.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_12.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_12.png new file mode 100644 index 000000000..7d24d84f3 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_12.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_13.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_13.png new file mode 100644 index 000000000..eee649a78 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_13.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_14.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_14.png new file mode 100644 index 000000000..f584f347d Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_14.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_15.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_15.png new file mode 100644 index 000000000..ab5c6ad8c Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_15.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_16.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_16.png new file mode 100644 index 000000000..bb2cf0049 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_16.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_17.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_17.png new file mode 100644 index 000000000..a06e85185 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_17.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_18.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_18.png new file mode 100644 index 000000000..441d58488 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_18.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_19.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_19.png new file mode 100644 index 000000000..98f88ed01 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_19.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_20.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_20.png new file mode 100644 index 000000000..d46801d27 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_20.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_21.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_21.png new file mode 100644 index 000000000..cea8ade47 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_21.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_22.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_22.png new file mode 100644 index 000000000..b6e55140c Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_22.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_23.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_23.png new file mode 100644 index 000000000..0463fc704 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_23.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_24.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_24.png new file mode 100644 index 000000000..210858af1 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_24.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_25.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_25.png new file mode 100644 index 000000000..6db230bb0 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_25.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_26.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_26.png new file mode 100644 index 000000000..6d86189a7 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_26.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_27.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_27.png new file mode 100644 index 000000000..90cceda72 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_27.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_28.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_28.png new file mode 100644 index 000000000..c325929cf Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_28.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_29.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_29.png new file mode 100644 index 000000000..86bec378a Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_29.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_30.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_30.png new file mode 100644 index 000000000..5e59db873 Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_30.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_31.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_31.png new file mode 100644 index 000000000..ec95a2bdb Binary files /dev/null and b/mods/ITEMS/mcl_compass/textures/mcl_compass_recovery_compass_31.png differ diff --git a/mods/ITEMS/mcl_composters/init.lua b/mods/ITEMS/mcl_composters/init.lua index 56422d8b5..e1e39aefc 100644 --- a/mods/ITEMS/mcl_composters/init.lua +++ b/mods/ITEMS/mcl_composters/init.lua @@ -138,8 +138,8 @@ local function composter_harvest(pos, node, player, itemstack, pointed_thing) 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") + -- spawn bone meal item + add_item(pos, "mcl_bone_meal:bone_meal") -- TODO play some sounds return itemstack end diff --git a/mods/ITEMS/mcl_composters/locale/mcl_composters.fr.tr b/mods/ITEMS/mcl_composters/locale/mcl_composters.fr.tr new file mode 100644 index 000000000..66a72bf38 --- /dev/null +++ b/mods/ITEMS/mcl_composters/locale/mcl_composters.fr.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_composters +Composter=Composteur +Composters can convert various organic items into bonemeal.=Les composteurs peuvent convertir divers objets organiques en farine d'os. +Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter."=Utiliser des objets organiques sur le composteur pour le remplir de couches de compost. Chaque fois qu'un objet est mis dans le composteur, il y a une chance d'ajouter une nouvelle couche de compost au composteur. Certains objets ont une plus grande chance que d'autres d'ajouter une couche supplémentaire. Après l'avoir rempli de 7 couches de compost, le composteur est plein. Après un délai d'approximativement une seconde, le composteur est prêt et on peut récupérer la farine d'os. Cliquer droit le composteur permet de récupérer la farine d'os et de vider le composteur. +filled=rempli +ready for harvest=prêt pour la récolte +Converts organic items into bonemeal=Convertit les objets organiques en farine d'os. diff --git a/mods/ITEMS/mcl_composters/locale/mcl_composters.ja.tr b/mods/ITEMS/mcl_composters/locale/mcl_composters.ja.tr new file mode 100644 index 000000000..6d8908486 --- /dev/null +++ b/mods/ITEMS/mcl_composters/locale/mcl_composters.ja.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_composters +Composter=コンポスター +Composters can convert various organic items into bonemeal.=コンポスターは、様々な有機物を骨粉に変えられます。 +Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter."=コンポスターに有機物を入れて、堆肥の層を作りましょう。コンポスターに有機物を入れるたびに、次の堆肥の層が追加されるチャンスが起きます。 追加される確率がより高くなっているアイテムもいくつかあります。 7層分の堆肥が充填されると、コンポスターは満杯となります。その約1秒後に、骨粉を取り出せる準備が完了します。右クリックして骨粉を取り出すと、コンポスターは空になります。 +filled=充足 +ready for harvest=収穫可能 +Converts organic items into bonemeal=有機物を骨粉に変える diff --git a/mods/ITEMS/mcl_copper/crafting.lua b/mods/ITEMS/mcl_copper/crafting.lua index 7b1e183c7..ce280fcdf 100644 --- a/mods/ITEMS/mcl_copper/crafting.lua +++ b/mods/ITEMS/mcl_copper/crafting.lua @@ -47,6 +47,17 @@ minetest.register_craft({ }, }) +local waxable_blocks = { "block", "block_cut", "block_exposed", "block_exposed_cut", "block_weathered", "block_weathered_cut", "block_oxidized", "block_oxidized_cut" } + +for _, w in ipairs(waxable_blocks) do + minetest.register_craft({ + output = "mcl_copper:waxed_"..w, + recipe = { + { "mcl_copper:"..w, "mcl_honey:honeycomb" }, + }, + }) +end + minetest.register_craft({ output = "mcl_copper:copper_ingot 4", recipe = { @@ -73,4 +84,11 @@ minetest.register_craft({ output = "mcl_copper:copper_ingot", recipe = "mcl_copper:stone_with_copper", cooktime = 10, -}) \ No newline at end of file +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_copper:block", + recipe = "mcl_copper:block_raw", + cooktime = 90, +}) diff --git a/mods/ITEMS/mcl_copper/functions.lua b/mods/ITEMS/mcl_copper/functions.lua index b6e0cb7e2..81dfdb69d 100644 --- a/mods/ITEMS/mcl_copper/functions.lua +++ b/mods/ITEMS/mcl_copper/functions.lua @@ -12,6 +12,34 @@ local function register_oxidation_abm(abm_name, node_name, oxidized_variant) }) end +function waxing_copper_block(pos, node, player, itemstack, convert_to) + if itemstack:get_name() == "mcl_honey:honeycomb" then + node.name = convert_to + minetest.set_node(pos, node) + awards.unlock(player:get_player_name(), "mcl:wax_on") + if not minetest.is_creative_enabled(player:get_player_name()) then + itemstack:take_item() + end + else + return true + end +end + +function scraping_copper_block(pos, node, player, itemstack, convert_to) + if itemstack:get_name():find("axe") then + node.name = convert_to + minetest.set_node(pos, node) + awards.unlock(player:get_player_name(), "mcl:wax_off") + if not minetest.is_creative_enabled(player:get_player_name()) then + local tool = itemstack:get_name() + local wear = mcl_autogroup.get_wear(tool, "axey") + itemstack:add_wear(wear) + end + else + return true + end +end + --[[ local stairs = { {"stair", "exposed", "_inner", "cut_inner"}, diff --git a/mods/ITEMS/mcl_copper/init.lua b/mods/ITEMS/mcl_copper/init.lua index ea15e5827..a99d03f2c 100644 --- a/mods/ITEMS/mcl_copper/init.lua +++ b/mods/ITEMS/mcl_copper/init.lua @@ -1,6 +1,6 @@ local path = minetest.get_modpath("mcl_copper") +dofile(path .. "/functions.lua") dofile(path .. "/nodes.lua") dofile(path .. "/items.lua") dofile(path .. "/crafting.lua") -dofile(path .. "/functions.lua") \ No newline at end of file diff --git a/mods/ITEMS/mcl_copper/items.lua b/mods/ITEMS/mcl_copper/items.lua index 450ec8cb3..694e693dc 100644 --- a/mods/ITEMS/mcl_copper/items.lua +++ b/mods/ITEMS/mcl_copper/items.lua @@ -11,5 +11,5 @@ minetest.register_craftitem("mcl_copper:raw_copper", { description = S("Raw Copper"), _doc_items_longdesc = S("Raw Copper. Mine a Copper Ore to get it."), inventory_image = "mcl_copper_raw.png", - groups = { craftitem = 1 }, + groups = { craftitem = 1, blast_furnace_smeltable = 1 }, }) \ No newline at end of file diff --git a/mods/ITEMS/mcl_copper/locale/mcl_copper.fr.tr b/mods/ITEMS/mcl_copper/locale/mcl_copper.fr.tr new file mode 100644 index 000000000..1efae66ee --- /dev/null +++ b/mods/ITEMS/mcl_copper/locale/mcl_copper.fr.tr @@ -0,0 +1,37 @@ +# textdomain: mcl_copper +A block of copper is mostly a decorative block.=Le bloc de cuivre est surtout un bloc décoratif. +A block used for compact raw copper storage.=Un bloc utilisé pour le stockage compact de cuivre brut. +Block of Copper=Bloc de cuivre +Block of Raw Copper=Bloc de cuivre brut +Copper Ingot=Lingot de cuivre +Copper Ore=Minerai de cuivre +Cut copper is a decorative block.=Le cuivre taillé est un bloc décoratif. +Cut Copper=Cuivre taillé +Double Slab of Cut Copper=Double dalle de cuivre taillé +Double Slab of Exposed Cut Copper=Double dalle de cuivre taillé exposé +Double Slab of Oxidized Cut Copper=Double dalle de cuivre taillé oxydé +Double Slab of Weathered Cut Copper=Double dalle de cuivre taillé érodé +Exposed copper is a decorative block.=Le cuivre exposé est un bloc décoratif. +Exposed Copper=Cuivre exposé +Exposed cut copper is a decorative block.=Le cuivre taillé exposé est un bloc décoratif. +Exposed Cut Copper=Cuivre taillé exposé +Molten Raw Copper. It is used to craft blocks.=Cuivre brut fondu. Utilisé pour fabriquer des blocs. +Oxidized copper is a decorative block.=Le cuivre oxydé est un bloc décoratif. +Oxidized Copper=Cuivre oxydé +Oxidized cut copper is a decorative block.=Le cuivre taillé oxydé est un bloc décoratif. +Oxidized Cut Copper=Cuivre taillé oxydé +Raw Copper. Mine a Copper Ore to get it.=Cuivre brut. Creuser dans du minerai de cuivre pour l'obtenir. +Raw Copper=Cuivre brut +Slab of Cut Copper=Dalle de cuivre taillé +Slab of Exposed Cut Copper=Dalle de cuivre taillé exposé +Slab of Oxidized Cut Copper=Dalle de cuivre taillé oxydé +Slab of Weathered Cut Copper=Dalle de cuivre taillé érodé +Some copper contained in stone, it is pretty common and can be found below sea level.=Un peu de cuivre se trouve dans la pierre, il est plutôt répandu et peut être trouvé sous le niveau de la mer. +Stairs of Cut Copper=Escalier de cuivre taillé +Stairs of Exposed Cut Copper=Escalier de cuivre taillé exposé +Stairs of Oxidized Cut Copper=Escalier de cuivre taillé oxydé +Stairs of Weathered Cut Copper=Escalier de cuivre taillé érodé +Weathered copper is a decorative block.=Le cuivre érodé est un bloc décoratif. +Weathered Copper=Cuivre érodé +Weathered cut copper is a decorative block.=Le cuivre taillé érodé est un bloc décoratif. +Weathered Cut Copper=Cuivre taillé érodé diff --git a/mods/ITEMS/mcl_copper/locale/mcl_copper.ja.tr b/mods/ITEMS/mcl_copper/locale/mcl_copper.ja.tr new file mode 100644 index 000000000..f6f204e78 --- /dev/null +++ b/mods/ITEMS/mcl_copper/locale/mcl_copper.ja.tr @@ -0,0 +1,57 @@ +# textdomain: mcl_copper +A block of copper is mostly a decorative block.=銅ブロックは、そのほとんどが装飾ブロックです。 +A block used for compact raw copper storage.=銅の粗鉱をコンパクトに保管するのに使えるブロックです。 +Block of Copper=銅ブロック +Waxed Block of Copper=錆止め済み銅ブロック +Block of Raw Copper=銅の粗鉱ブロック +Copper Ingot=銅インゴット +Copper Ore=銅鉱石 +Cut copper is a decorative block.=溝入り銅は、装飾ブロックです。 +Cut Copper=溝入り銅 +Waxed Cut Copper=錆止め済み溝入り銅 +Double Slab of Cut Copper=溝入り銅の2重スラブ +Double Slab of Exposed Cut Copper=少し酸化した溝入り銅の2重スラブ +Double Slab of Oxidized Cut Copper=殆ど酸化した溝入り銅の2重スラブ +Double Slab of Weathered Cut Copper=半ば酸化した溝入り銅の2重スラブ +Waxed Double Slab of Cut Copper=錆止め済み溝入り銅の2重スラブ +Waxed Double Slab of Exposed Cut Copper=少し酸化した錆止め済み溝入り銅の2重スラブ +Waxed Double Slab of Oxidized Cut Copper=殆ど酸化した錆止め済み溝入り銅の2重スラブ +Waxed Double Slab of Weathered Cut Copper=半ば酸化した錆止め済み溝入り銅の2重スラブ +Exposed copper is a decorative block.=少し酸化した銅は、装飾ブロックです。 +Exposed Copper=少し酸化した銅 +Waxed Exposed Copper=少し酸化した錆止め済み銅 +Exposed cut copper is a decorative block.=少し酸化した溝入り銅は、装飾ブロックです。 +Exposed Cut Copper=少し酸化した溝入り銅 +Waxed Exposed Cut Copper=少し酸化した錆止め済み溝入り銅 +Molten Raw Copper. It is used to craft blocks.=溶けた未処理の銅。ブロックのクラフトに使われます。 +Oxidized copper is a decorative block.=殆ど酸化した銅は、装飾ブロックです。 +Oxidized Copper=殆ど酸化した銅 +Waxed Oxidized Copper=殆ど酸化した錆止め済み銅 +Oxidized cut copper is a decorative block.=殆ど酸化した溝入り銅は、装飾ブロックです。 +Oxidized Cut Copper=殆ど酸化した溝入り銅 +Waxed Oxidized Cut Copper=殆ど酸化した錆止め済み溝入り銅 +Raw Copper. Mine a Copper Ore to get it.=未処理の銅。銅鉱石を採掘すると手に入ります。 +Raw Copper=銅の粗鉱 +Slab of Cut Copper=溝入り銅のスラブ +Slab of Exposed Cut Copper=少し酸化した溝入り銅のスラブ +Slab of Oxidized Cut Copper=殆ど酸化した溝入り銅のスラブ +Slab of Weathered Cut Copper=半ば酸化した溝入り銅のスラブ +Waxed Slab of Cut Copper=錆止め済み溝入り銅のスラブ +Waxed Slab of Exposed Cut Copper=少し酸化した錆止め済み溝入り銅のスラブ +Waxed Slab of Oxidized Cut Copper=殆ど酸化した錆止め済み溝入り銅のスラブ +Waxed Slab of Weathered Cut Copper=半ば酸化した錆止め済み溝入り銅のスラブ +Some copper contained in stone, it is pretty common and can be found below sea level.=石に含まれる銅は ごく一般的で、海面下の高さで見られます。 +Stairs of Cut Copper=溝入り銅の階段 +Stairs of Exposed Cut Copper=少し酸化した溝入り銅の階段 +Stairs of Oxidized Cut Copper=殆ど酸化した溝入り銅の階段 +Stairs of Weathered Cut Copper=半ば酸化した溝入り銅の階段 +Waxed Stairs of Cut Copper=錆止め済み溝入り銅の階段 +Waxed Stairs of Exposed Cut Copper=少し酸化した錆止め済み溝入り銅の階段 +Waxed Stairs of Oxidized Cut Copper=殆ど酸化した錆止め済み溝入り銅の階段 +Waxed Stairs of Weathered Cut Copper=半ば酸化した錆止め済み溝入り銅の階段 +Weathered copper is a decorative block.=半ば酸化した銅は、装飾ブロックです。 +Weathered Copper=半ば酸化した銅 +Waxed Weathered Copper=半ば酸化した錆止め済み銅 +Weathered cut copper is a decorative block.=半ば酸化した溝入り銅は、装飾ブロックです。 +Weathered Cut Copper=半ば酸化した溝入り銅 +Waxed Weathered Cut Copper=半ば酸化した錆止め済み溝入り銅 diff --git a/mods/ITEMS/mcl_copper/locale/template.txt b/mods/ITEMS/mcl_copper/locale/template.txt index 050c099ee..7022780ff 100644 --- a/mods/ITEMS/mcl_copper/locale/template.txt +++ b/mods/ITEMS/mcl_copper/locale/template.txt @@ -2,36 +2,56 @@ A block of copper is mostly a decorative block.= A block used for compact raw copper storage.= Block of Copper= +Waxed Block of Copper= Block of Raw Copper= Copper Ingot= Copper Ore= Cut copper is a decorative block.= Cut Copper= +Waxed Cut Copper= Double Slab of Cut Copper= Double Slab of Exposed Cut Copper= Double Slab of Oxidized Cut Copper= Double Slab of Weathered Cut Copper= +Waxed Double Slab of Cut Copper= +Waxed Double Slab of Exposed Cut Copper= +Waxed Double Slab of Oxidized Cut Copper= +Waxed Double Slab of Weathered Cut Copper= Exposed copper is a decorative block.= Exposed Copper= +Waxed Exposed Copper= Exposed cut copper is a decorative block.= Exposed Cut Copper= +Waxed Exposed Cut Copper= Molten Raw Copper. It is used to craft blocks.= Oxidized copper is a decorative block.= Oxidized Copper= +Waxed Oxidized Copper= Oxidized cut copper is a decorative block.= Oxidized Cut Copper= +Waxed Oxidized Cut Copper= Raw Copper. Mine a Copper Ore to get it.= Raw Copper= Slab of Cut Copper= Slab of Exposed Cut Copper= Slab of Oxidized Cut Copper= Slab of Weathered Cut Copper= +Waxed Slab of Cut Copper= +Waxed Slab of Exposed Cut Copper= +Waxed Slab of Oxidized Cut Copper= +Waxed Slab of Weathered Cut Copper= Some copper contained in stone, it is pretty common and can be found below sea level.= Stairs of Cut Copper= Stairs of Exposed Cut Copper= Stairs of Oxidized Cut Copper= Stairs of Weathered Cut Copper= +Waxed Stairs of Cut Copper= +Waxed Stairs of Exposed Cut Copper= +Waxed Stairs of Oxidized Cut Copper= +Waxed Stairs of Weathered Cut Copper= Weathered copper is a decorative block.= Weathered Copper= +Waxed Weathered Copper= Weathered cut copper is a decorative block.= Weathered Cut Copper= +Waxed Weathered Cut Copper= diff --git a/mods/ITEMS/mcl_copper/nodes.lua b/mods/ITEMS/mcl_copper/nodes.lua index 38fbb6c3d..6c498f9f6 100644 --- a/mods/ITEMS/mcl_copper/nodes.lua +++ b/mods/ITEMS/mcl_copper/nodes.lua @@ -20,7 +20,7 @@ minetest.register_node("mcl_copper:block_raw", { _doc_items_longdesc = S("A block used for compact raw copper storage."), tiles = {"mcl_copper_block_raw.png"}, is_ground_content = false, - groups = {pickaxey = 2, building_block = 1}, + groups = {pickaxey = 2, building_block = 1, blast_furnace_smeltable = 1 }, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 6, _mcl_hardness = 5, @@ -34,7 +34,20 @@ minetest.register_node("mcl_copper:block", { groups = {pickaxey = 2, building_block = 1}, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 6, - _mcl_hardness = 5, + _mcl_hardness = 3, + on_rightclick = function(pos, node, player, itemstack) waxing_copper_block(pos, node, player, itemstack, "mcl_copper:waxed_block") end, +}) + +minetest.register_node("mcl_copper:waxed_block", { + description = S("Waxed Block of Copper"), + _doc_items_longdesc = S("A block of copper is mostly a decorative block."), + tiles = {"mcl_copper_block.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 3, + on_rightclick = function(pos, node, player, itemstack) scraping_copper_block(pos, node, player, itemstack, "mcl_copper:block") end, }) minetest.register_node("mcl_copper:block_exposed", { @@ -47,18 +60,19 @@ minetest.register_node("mcl_copper:block_exposed", { _mcl_blast_resistance = 6, _mcl_hardness = 5, _mcl_anti_oxidation_varient = "mcl_copper:block", + on_rightclick = function(pos, node, player, itemstack) waxing_copper_block(pos, node, player, itemstack, "mcl_copper:waxed_block_exposed") end, }) -minetest.register_node("mcl_copper:block_oxidized", { - description = S("Oxidized Copper"), - _doc_items_longdesc = S("Oxidized copper is a decorative block."), - tiles = {"mcl_copper_oxidized.png"}, +minetest.register_node("mcl_copper:waxed_block_exposed", { + description = S("Waxed Exposed Copper"), + _doc_items_longdesc = S("Exposed copper is a decorative block."), + tiles = {"mcl_copper_exposed.png"}, is_ground_content = false, groups = {pickaxey = 2, building_block = 1}, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 6, _mcl_hardness = 5, - _mcl_anti_oxidation_varient = "mcl_copper:block_weathered", + on_rightclick = function(pos, node, player, itemstack) scraping_copper_block(pos, node, player, itemstack, "mcl_copper:block") end, }) minetest.register_node("mcl_copper:block_weathered", { @@ -71,6 +85,44 @@ minetest.register_node("mcl_copper:block_weathered", { _mcl_blast_resistance = 6, _mcl_hardness = 5, _mcl_anti_oxidation_varient = "mcl_copper:block_exposed", + on_rightclick = function(pos, node, player, itemstack) waxing_copper_block(pos, node, player, itemstack, "mcl_copper:waxed_block_weathered") end, +}) + +minetest.register_node("mcl_copper:waxed_block_weathered", { + description = S("Waxed Weathered Copper"), + _doc_items_longdesc = S("Weathered copper is a decorative block."), + tiles = {"mcl_copper_weathered.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + on_rightclick = function(pos, node, player, itemstack) scraping_copper_block(pos, node, player, itemstack, "mcl_copper:block_exposed") end, +}) + +minetest.register_node("mcl_copper:block_oxidized", { + description = S("Oxidized Copper"), + _doc_items_longdesc = S("Oxidized copper is a decorative block."), + tiles = {"mcl_copper_oxidized.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_anti_oxidation_varient = "mcl_copper:block_weathered", + on_rightclick = function(pos, node, player, itemstack) waxing_copper_block(pos, node, player, itemstack, "mcl_copper:waxed_block_oxidized") end, +}) + +minetest.register_node("mcl_copper:waxed_block_oxidized", { + description = S("Waxed Oxidized Copper"), + _doc_items_longdesc = S("Oxidized copper is a decorative block."), + tiles = {"mcl_copper_oxidized.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + on_rightclick = function(pos, node, player, itemstack) scraping_copper_block(pos, node, player, itemstack, "mcl_copper:block_weathered") end, }) minetest.register_node("mcl_copper:block_cut", { @@ -82,6 +134,19 @@ minetest.register_node("mcl_copper:block_cut", { sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 6, _mcl_hardness = 5, + on_rightclick = function(pos, node, player, itemstack) waxing_copper_block(pos, node, player, itemstack, "mcl_copper:waxed_block_cut") end, +}) + +minetest.register_node("mcl_copper:waxed_block_cut", { + description = S("Waxed Cut Copper"), + _doc_items_longdesc = S("Cut copper is a decorative block."), + tiles = {"mcl_copper_block_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + on_rightclick = function(pos, node, player, itemstack) scraping_copper_block(pos, node, player, itemstack, "mcl_copper:block_cut") end, }) minetest.register_node("mcl_copper:block_exposed_cut", { @@ -94,18 +159,19 @@ minetest.register_node("mcl_copper:block_exposed_cut", { _mcl_blast_resistance = 6, _mcl_hardness = 5, _mcl_anti_oxidation_varient = "mcl_copper:block_cut", + on_rightclick = function(pos, node, player, itemstack) waxing_copper_block(pos, node, player, itemstack, "mcl_copper:waxed_block_exposed_cut") end, }) -minetest.register_node("mcl_copper:block_oxidized_cut", { - description = S("Oxidized Cut Copper"), - _doc_items_longdesc = S("Oxidized cut copper is a decorative block."), - tiles = {"mcl_copper_oxidized_cut.png"}, +minetest.register_node("mcl_copper:waxed_block_exposed_cut", { + description = S("Waxed Exposed Cut Copper"), + _doc_items_longdesc = S("Exposed cut copper is a decorative block."), + tiles = {"mcl_copper_exposed_cut.png"}, is_ground_content = false, groups = {pickaxey = 2, building_block = 1}, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 6, _mcl_hardness = 5, - _mcl_anti_oxidation_varient = "mcl_copper:block_weathered_cut", + on_rightclick = function(pos, node, player, itemstack) scraping_copper_block(pos, node, player, itemstack, "mcl_copper:block_cut") end, }) minetest.register_node("mcl_copper:block_weathered_cut", { @@ -118,6 +184,44 @@ minetest.register_node("mcl_copper:block_weathered_cut", { _mcl_blast_resistance = 6, _mcl_hardness = 5, _mcl_anti_oxidation_varient = "mcl_copper:block_exposed_cut", + on_rightclick = function(pos, node, player, itemstack) waxing_copper_block(pos, node, player, itemstack, "mcl_copper:waxed_block_weathered_cut") end, +}) + +minetest.register_node("mcl_copper:waxed_block_weathered_cut", { + description = S("Waxed Weathered Cut Copper"), + _doc_items_longdesc = S("Weathered cut copper is a decorative block."), + tiles = {"mcl_copper_weathered_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + on_rightclick = function(pos, node, player, itemstack) scraping_copper_block(pos, node, player, itemstack, "mcl_copper:block_exposed_cut") end, +}) + +minetest.register_node("mcl_copper:block_oxidized_cut", { + description = S("Oxidized Cut Copper"), + _doc_items_longdesc = S("Oxidized cut copper is a decorative block."), + tiles = {"mcl_copper_oxidized_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_anti_oxidation_varient = "mcl_copper:block_weathered_cut", + on_rightclick = function(pos, node, player, itemstack) waxing_copper_block(pos, node, player, itemstack, "mcl_copper:waxed_block_oxidized_cut") end, +}) + +minetest.register_node("mcl_copper:waxed_block_oxidized_cut", { + description = S("Waxed Oxidized Cut Copper"), + _doc_items_longdesc = S("Oxidized cut copper is a decorative block."), + tiles = {"mcl_copper_oxidized_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + on_rightclick = function(pos, node, player, itemstack) scraping_copper_block(pos, node, player, itemstack, "mcl_copper:block_weathered_cut") end, }) mcl_stairs.register_slab("copper_cut", "mcl_copper:block_cut", @@ -127,6 +231,13 @@ mcl_stairs.register_slab("copper_cut", "mcl_copper:block_cut", nil, nil, nil, S("Double Slab of Cut Copper")) +mcl_stairs.register_slab("waxed_copper_cut", "mcl_copper:waxed_block_cut", + {pickaxey = 2}, + {"mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png"}, + S("Waxed Slab of Cut Copper"), + nil, nil, nil, + S("Waxed Double Slab of Cut Copper")) + mcl_stairs.register_slab("copper_exposed_cut", "mcl_copper:block_exposed_cut", {pickaxey = 2}, {"mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png"}, @@ -134,12 +245,12 @@ mcl_stairs.register_slab("copper_exposed_cut", "mcl_copper:block_exposed_cut", nil, nil, nil, S("Double Slab of Exposed Cut Copper")) -mcl_stairs.register_slab("copper_oxidized_cut", "mcl_copper:block_oxidized_cut", +mcl_stairs.register_slab("waxed_copper_exposed_cut", "mcl_copper:waxed_block_exposed_cut", {pickaxey = 2}, - {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, - S("Slab of Oxidized Cut Copper"), + {"mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png"}, + S("Waxed Slab of Exposed Cut Copper"), nil, nil, nil, - S("Double Slab of Oxidized Cut Copper")) + S("Waxed Double Slab of Exposed Cut Copper")) mcl_stairs.register_slab("copper_weathered_cut", "mcl_copper:block_weathered_cut", {pickaxey = 2}, @@ -148,6 +259,27 @@ mcl_stairs.register_slab("copper_weathered_cut", "mcl_copper:block_weathered_cut nil, nil, nil, S("Double Slab of Weathered Cut Copper")) +mcl_stairs.register_slab("waxed_copper_weathered_cut", "mcl_copper:waxed_block_weathered_cut", + {pickaxey = 2}, + {"mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png"}, + S("Waxed Slab of Weathered Cut Copper"), + nil, nil, nil, + S("Waxed Double Slab of Weathered Cut Copper")) + +mcl_stairs.register_slab("copper_oxidized_cut", "mcl_copper:block_oxidized_cut", + {pickaxey = 2}, + {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, + S("Slab of Oxidized Cut Copper"), + nil, nil, nil, + S("Double Slab of Oxidized Cut Copper")) + +mcl_stairs.register_slab("waxed_copper_oxidized_cut", "mcl_copper:waxed_block_oxidized_cut", + {pickaxey = 2}, + {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, + S("Waxed Slab of Oxidized Cut Copper"), + nil, nil, nil, + S("Waxed Double Slab of Oxidized Cut Copper")) + mcl_stairs.register_stair("copper_cut", "mcl_copper:block_cut", {pickaxey = 2}, {"mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png"}, @@ -155,6 +287,13 @@ mcl_stairs.register_stair("copper_cut", "mcl_copper:block_cut", nil, 6, nil, "woodlike") +mcl_stairs.register_stair("waxed_copper_cut", "mcl_copper:waxed_block_cut", + {pickaxey = 2}, + {"mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png"}, + S("Waxed Stairs of Cut Copper"), + nil, 6, nil, + "woodlike") + mcl_stairs.register_stair("copper_exposed_cut", "mcl_copper:block_exposed_cut", {pickaxey = 2}, {"mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png"}, @@ -162,10 +301,10 @@ mcl_stairs.register_stair("copper_exposed_cut", "mcl_copper:block_exposed_cut", nil, 6, nil, "woodlike") -mcl_stairs.register_stair("copper_oxidized_cut", "mcl_copper:block_oxidized_cut", +mcl_stairs.register_stair("waxed_copper_exposed_cut", "mcl_copper:waxed_block_exposed_cut", {pickaxey = 2}, - {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, - S("Stairs of Oxidized Cut Copper"), + {"mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png"}, + S("Waxed Stairs of Exposed Cut Copper"), nil, 6, nil, "woodlike") @@ -174,4 +313,25 @@ mcl_stairs.register_stair("copper_weathered_cut", "mcl_copper:block_weathered_cu {"mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png"}, S("Stairs of Weathered Cut Copper"), nil, 6, nil, - "woodlike") \ No newline at end of file + "woodlike") + +mcl_stairs.register_stair("waxed_copper_weathered_cut", "mcl_copper:waxed_block_weathered_cut", + {pickaxey = 2}, + {"mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png"}, + S("Waxed Stairs of Weathered Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("copper_oxidized_cut", "mcl_copper:block_oxidized_cut", + {pickaxey = 2}, + {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, + S("Stairs of Oxidized Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("waxed_copper_oxidized_cut", "mcl_copper:waxed_block_oxidized_cut", + {pickaxey = 2}, + {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, + S("Waxed Stairs of Oxidized Cut Copper"), + nil, 6, nil, + "woodlike") diff --git a/mods/ITEMS/mcl_copper/screenshot.png b/mods/ITEMS/mcl_copper/screenshot.png deleted file mode 100644 index 032d45fb1..000000000 Binary files a/mods/ITEMS/mcl_copper/screenshot.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/crafting.lua b/mods/ITEMS/mcl_core/crafting.lua index df456cbdc..ffba04a7b 100644 --- a/mods/ITEMS/mcl_core/crafting.lua +++ b/mods/ITEMS/mcl_core/crafting.lua @@ -126,14 +126,14 @@ minetest.register_craft({ minetest.register_craft({ output = "mcl_core:bone_block", recipe = { - { "mcl_dye:white", "mcl_dye:white", "mcl_dye:white" }, - { "mcl_dye:white", "mcl_dye:white", "mcl_dye:white" }, - { "mcl_dye:white", "mcl_dye:white", "mcl_dye:white" }, + { "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal" }, + { "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal" }, + { "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal" }, }, }) minetest.register_craft({ - output = "mcl_dye:white 9", + output = "mcl_bone_meal:bone_meal 9", recipe = { { "mcl_core:bone_block" }, }, @@ -298,14 +298,14 @@ minetest.register_craft({ minetest.register_craft({ output = "mcl_core:lapisblock", recipe = { - {"mcl_dye:blue", "mcl_dye:blue", "mcl_dye:blue"}, - {"mcl_dye:blue", "mcl_dye:blue", "mcl_dye:blue"}, - {"mcl_dye:blue", "mcl_dye:blue", "mcl_dye:blue"}, + {"mcl_core:lapis", "mcl_core:lapis", "mcl_core:lapis"}, + {"mcl_core:lapis", "mcl_core:lapis", "mcl_core:lapis"}, + {"mcl_core:lapis", "mcl_core:lapis", "mcl_core:lapis"}, } }) minetest.register_craft({ - output = "mcl_dye:blue 9", + output = "mcl_core:lapis 9", recipe = { {"mcl_core:lapisblock"}, } @@ -482,7 +482,7 @@ minetest.register_craft({ minetest.register_craft({ type = "cooking", - output = "mcl_dye:blue", + output = "mcl_core:lapis", recipe = "mcl_core:stone_with_lapis", cooktime = 10, }) diff --git a/mods/ITEMS/mcl_core/craftitems.lua b/mods/ITEMS/mcl_core/craftitems.lua index fc84c50f5..32a5f7cbc 100644 --- a/mods/ITEMS/mcl_core/craftitems.lua +++ b/mods/ITEMS/mcl_core/craftitems.lua @@ -2,6 +2,8 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local enable_fapples = minetest.settings:get_bool("mcl_enable_fapples",true) + -- -- Crafting items -- @@ -99,6 +101,14 @@ minetest.register_craftitem("mcl_core:emerald", { groups = { craftitem=1 }, }) +minetest.register_craftitem("mcl_core:lapis", { + description = S("Lapis Lazuli"), + _doc_items_longdesc = S("Lapis Lazuli are required for enchanting items on an enchanting table."), + inventory_image = "mcl_core_lapis.png", + stack_max = 64, + groups = { craftitem=1 }, +}) + minetest.register_craftitem("mcl_core:brick", { description = S("Brick"), _doc_items_longdesc = S("Bricks are used to craft brick blocks."), @@ -162,8 +172,11 @@ local function eat_gapple(itemstack, placer, pointed_thing) regen_duration, absorbtion_factor = 20, 4 mcl_potions.fire_resistance_func(placer, 1, 300) mcl_potions.leaping_func(placer, 1, 300) + if enable_fapples then + mcl_potions.swiftness_func(placer, absorbtion_factor, 120) + end end - mcl_potions.swiftness_func(placer, absorbtion_factor, 120) -- TODO: Absorbtion + -- TODO: Absorbtion mcl_potions.regeneration_func(placer, 2, regen_duration) return gapple_hunger_restore(itemstack, placer, pointed_thing) end diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index fc08a0957..6ef9a86f9 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -22,6 +22,7 @@ minetest.register_abm({ neighbors = {"group:water"}, interval = 1, chance = 1, + min_y = mcl_vars.mg_end_min, action = function(pos, node, active_object_count, active_object_count_wider) local water = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, "group:water") @@ -174,7 +175,7 @@ minetest.register_abm({ nodenames = {"group:destroy_by_lava_flow"}, neighbors = {"group:lava"}, interval = 1, - chance = 1, + chance = 5, action = function(pos, node, active_object_count, active_object_count_wider) liquid_flow_action(pos, "lava", function(pos) minetest.remove_node(pos) @@ -215,8 +216,8 @@ minetest.register_abm({ 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") + minetest.dig_node(pos) + -- minetest.add_item(vector.offset(pos, math.random(-0.5, 0.5), 0, math.random(-0.5, 0.5)), "mcl_core:cactus") posy = posy + 1 end break @@ -312,6 +313,7 @@ local function check_growth_width(pos, width, height) end return true end +mcl_core.check_growth_width = check_growth_width -- Check if a tree with id can grow at a position. Options is a table of flags -- for varieties of trees. The 'two_by_two' option is used to check if there is @@ -1365,108 +1367,46 @@ function mcl_core.supports_vines(nodename) end -- Leaf Decay - --- To enable leaf decay for a node, add it to the "leafdecay" group. -- --- The rating of the group determines how far from a node in the group "tree" --- the node can be without decaying. +-- Whenever a tree trunk node is removed, all `group:leaves` nodes in a radius +-- of 6 blocks are checked from the trunk node's `after_destruct` handler. +-- Any such nodes within that radius that has no trunk node present within a +-- distance of 6 blocks is replaced with a `group:orphan_leaves` node. -- --- If param2 of the node is ~= 0, the node will always be preserved. Thus, if --- the player places a node of that kind, you will want to set param2=1 or so. --- - -mcl_core.leafdecay_trunk_cache = {} -mcl_core.leafdecay_enable_cache = true --- Spread the load of finding trunks -mcl_core.leafdecay_trunk_find_allow_accumulator = 0 - -minetest.register_globalstep(function(dtime) - --local finds_per_second = 5000 - mcl_core.leafdecay_trunk_find_allow_accumulator = math.floor(dtime * 5000) -end) - +-- The `group:orphan_leaves` nodes are gradually decayed in this ABM. minetest.register_abm({ label = "Leaf decay", - nodenames = {"group:leafdecay"}, - neighbors = {"air", "group:liquid"}, - -- A low interval and a high inverse chance spreads the load - interval = 2, - chance = 5, + nodenames = {"group:orphan_leaves"}, + interval = 5, + chance = 10, + action = function(pos, node) + -- Spawn item entities for any of the leaf's drops + local itemstacks = minetest.get_node_drops(node.name) + for _, itemname in pairs(itemstacks) do + local p_drop = vector.offset(pos, math.random() - 0.5, math.random() - 0.5, math.random() - 0.5) + minetest.add_item(p_drop, itemname) + end + -- Remove the decayed node + minetest.remove_node(pos) + leafdecay_particles(pos, node) + minetest.check_for_falling(pos) - action = function(p0, node, _, _) - local do_preserve = false - local d = minetest.registered_nodes[node.name].groups.leafdecay - if not d or d == 0 then - return - end - local n0 = minetest.get_node(p0) - if n0.param2 ~= 0 then - -- Prevent leafdecay for player-placed leaves. - -- param2 is set to 1 after it was placed by the player - return - end - local p0_hash = nil - if mcl_core.leafdecay_enable_cache then - p0_hash = minetest.hash_node_position(p0) - local trunkp = mcl_core.leafdecay_trunk_cache[p0_hash] - if trunkp then - local n = minetest.get_node(trunkp) - local reg = minetest.registered_nodes[n.name] - -- Assume ignore is a trunk, to make the thing work at the border of the active area - if n.name == "ignore" or (reg and reg.groups.tree and reg.groups.tree ~= 0) then - return - end - -- Cache is invalid - table.remove(mcl_core.leafdecay_trunk_cache, p0_hash) - end - end - if mcl_core.leafdecay_trunk_find_allow_accumulator <= 0 then - return - end - mcl_core.leafdecay_trunk_find_allow_accumulator = - mcl_core.leafdecay_trunk_find_allow_accumulator - 1 - -- Assume ignore is a trunk, to make the thing work at the border of the active area - local p1 = minetest.find_node_near(p0, d, {"ignore", "group:tree"}) - if p1 then - do_preserve = true - if mcl_core.leafdecay_enable_cache then - -- Cache the trunk - mcl_core.leafdecay_trunk_cache[p0_hash] = p1 - end - end - if not do_preserve then - -- Drop stuff other than the node itself - local itemstacks = minetest.get_node_drops(n0.name) - for _, itemname in pairs(itemstacks) do - local p_drop = { - x = p0.x - 0.5 + math.random(), - y = p0.y - 0.5 + math.random(), - z = p0.z - 0.5 + math.random(), - } - minetest.add_item(p_drop, itemname) - end - -- Remove node - minetest.remove_node(p0) - leafdecay_particles(p0, n0) - minetest.check_for_falling(p0) - - -- Kill depending vines immediately to skip the vines decay delay - local surround = { - { x = 0, y = 0, z = -1 }, - { x = 0, y = 0, z = 1 }, - { x = -1, y = 0, z = 0 }, - { x = 1, y = 0, z = 0 }, - { x = 0, y = -1, z = -1 }, - } - for s=1, #surround do - local spos = vector.add(p0, surround[s]) - local maybe_vine = minetest.get_node(spos) - --local surround_inverse = vector.multiply(surround[s], -1) - if maybe_vine.name == "mcl_core:vine" and (not mcl_core.check_vines_supported(spos, maybe_vine)) then - minetest.remove_node(spos) - vinedecay_particles(spos, maybe_vine) - minetest.check_for_falling(spos) - end + -- Kill depending vines immediately to skip the vines decay delay + local surround = { + { x = 0, y = 0, z = -1 }, + { x = 0, y = 0, z = 1 }, + { x = -1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + { x = 0, y = -1, z = -1 }, + } + for s=1, #surround do + local spos = vector.add(pos, surround[s]) + local maybe_vine = minetest.get_node(spos) + --local surround_inverse = vector.multiply(surround[s], -1) + if maybe_vine.name == "mcl_core:vine" and (not mcl_core.check_vines_supported(spos, maybe_vine)) then + minetest.remove_node(spos) + vinedecay_particles(spos, maybe_vine) + minetest.check_for_falling(spos) end end end @@ -1619,7 +1559,7 @@ function mcl_core.register_snowed_node(itemstring_snowed, itemstring_clear, tile end if not sounds then def.sounds = mcl_sounds.node_sound_dirt_defaults({ - footstep = { name = "pedology_snow_soft_footstep", gain = 0.5 } + footstep = mcl_sounds.node_sound_snow_defaults().footstep, }) else def.sounds = sounds @@ -1698,3 +1638,37 @@ function mcl_core.after_snow_destruct(pos) local node = minetest.get_node(npos) mcl_core.clear_snow_dirt(npos, node) end + + +-- Obsidian crying + +local crobby_particle = { + velocity = vector.new(0,0,0), + size = math.random(1.3,2.5), + texture = "mcl_core_crying_obsidian_tear.png", + collision_removal = false, +} + + +minetest.register_abm({ + label = "Obsidian cries", + nodenames = {"mcl_core:crying_obsidian"}, + interval = 5, + chance = 10, + action = function(pos, node) + minetest.after(math.random(0.1,1.5),function() + local pt = table.copy(crobby_particle) + pt.acceleration = vector.new(0,0,0) + pt.collisiondetection = false + pt.expirationtime = math.random(0.5,1.5) + pt.pos = vector.offset(pos,math.random(-0.5,0.5),-0.51,math.random(-0.5,0.5)) + minetest.add_particle(pt) + minetest.after(pt.expirationtime,function() + pt.acceleration = vector.new(0,-9,0) + pt.collisiondetection = true + pt.expirationtime = math.random(1.2,4.5) + minetest.add_particle(pt) + end) + end) + end +}) diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr index b064cebbe..f8a441fdc 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr @@ -130,6 +130,8 @@ Jungle Wood=Dschungelholz Jungle Wood Planks=Dschungelholzplanken Jungle leaves are grown from jungle trees.=Dschungelblätter wachsen an Dschungelbäumen. Ladder=Leiter +Lapis Lazuli=Lapislazuli +Lapis Lazuli are required for enchanting items on an enchanting table.=Lapislazuli werden zum Verzaubern von Gegenständen auf einem Zaubertisch benötigt. Lapis Lazuli Block=Lapislazuliblock Lapis Lazuli Ore=Lapislazulierz Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Lapislazulierz ist das Erz von Lapislazuli. Es kann relativ selten in Ansammlungen in der Nähe des Weltbodens gefunden werden. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr index 1937babd3..0f8656520 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr @@ -130,6 +130,8 @@ Jungle Wood=Tronco de jungla Jungle Wood Planks=Madera de jungla Jungle leaves are grown from jungle trees.=Las hojas de jungla se cultivan de los árboles de jungla. Ladder=Escalera +Lapis Lazuli=Lapislázuli +Lapis Lazuli are required for enchanting items on an enchanting table.=Los lapislázuli son necesarios para encantar objetos en una mesa de encantamiento. Lapis Lazuli Block=Bloque de lapislázuli Lapis Lazuli Ore=Mena de lapislázuli Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=El mineral de lapislázuli es el mineral de lapislázuli. Rara vez se puede encontrar en grupos, se encuentra cerca del fondo del mundo. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index 64aadd6db..ad6c09b08 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -13,10 +13,10 @@ A grass block is dirt with a grass cover. Grass blocks are resourceful blocks wh A lapis lazuli block is mostly a decorative block but also useful as a compact storage of lapis lazuli.=Un bloc de lapis-lazuli est principalement un bloc décoratif mais également utile comme stockage compact de lapis-lazuli. A lava source sets fire to a couple of air blocks above when they're next to a flammable block.=Une source de lave met le feu à quelques blocs d'air au-dessus lorsqu'ils sont à côté d'un bloc inflammable. A piece of ladder which allows you to climb vertically. Ladders can only be placed on the side of solid blocks and not on glass, leaves, ice, slabs, glowstone, nor sea lanterns.=Un morceau d'échelle qui vous permet de grimper verticalement. Les échelles ne peuvent être placées que sur le côté de blocs solides et non sur du verre, des feuilles, de la glace, des dalles, des pierres incandescentes ou des lanternes marines. -Acacia Bark=Écorce d'Acacia +Acacia Bark=Bois d'Acacia Acacia Leaves=Feuilles d'Acacia Acacia Sapling=Pousse d'Acacia -Acacia Wood=Bois d'Acacia +Acacia Wood=Bûche d'Acacia Acacia Wood Planks=Planches d'Acacia Acacia leaves are grown from acacia trees.=Les feuilles d'acacia sont cultivées à partir d'acacias. Andesite=Andésite @@ -27,10 +27,10 @@ Barrier=Barrière invisible Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Les barrières sont des blocs accessibles à pied. Ils sont utilisés pour créer des limites de cartes d'aventure et similaires. Les monstres et les animaux n'apparaissent pas sur les barrières, et les clôtures ne se connectent pas aux barrières. D'autres blocs peuvent être construits sur des barrières comme sur n'importe quel autre bloc. Bedrock=Bedrock Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Le bedrock est un type de roche très dur. Il ne peut pas être brisé, détruit, collecté ou déplacé par des moyens normaux, sauf en mode créatif. -Birch Bark=Écorce de Bouleau +Birch Bark=Bois de Bouleau Birch Leaves=Feuilles de Bouleau Birch Sapling=Pousse de Bouleau -Birch Wood=Bois de Bouleau +Birch Wood=Bûche de Bouleau Birch Wood Planks=Planches de Bouleau Birch leaves are grown from birch trees.=Les feuilles de bouleau sont cultivées à partir de bouleaux. Black Stained Glass=Verre Noir @@ -75,10 +75,10 @@ Cut Sandstone=Grès Taillé Cut red sandstone is a decorative building block.=Le grès rouge taillé est un bloc de construction décoratif. Cut sandstone is a decorative building block.=Le grès taillé est un bloc de construction décoratif. Cyan Stained Glass=Vitre Cyan -Dark Oak Bark=Écorce de Chêne Noir +Dark Oak Bark=Bois de Chêne Noir Dark Oak Leaves=Feuilles de Chêne Noir Dark Oak Sapling=Pousse de Chêne Noir -Dark Oak Wood=Bois de Chêne Noir +Dark Oak Wood=Bûche de Chêne Noir Dark Oak Wood Planks=Planche de Chêne Noir Dark oak leaves are grown from dark oak trees.=Les feuilles de chêne noir sont issues de chênes noirs. Dark oak saplings can grow into dark oaks, but only in groups. A lonely dark oak sapling won't grow. A group of four dark oak saplings grows into a dark oak after some time when they are placed on soil (such as dirt) in a 2×2 square and exposed to light.=Les pousses de chêne noir peuvent devenir des chênes noirs, mais seulement en groupes. Une pousse de chêne noir solitaire ne poussera pas. Un groupe de quatre pousses de chêne noir se transforme en chêne noir après un certain temps lorsqu'ils sont placés sur le sol (comme la terre) dans un carré 2×2 et exposés à la lumière. @@ -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=Granit +Granite=Granite 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. @@ -123,13 +123,15 @@ Iron Ingot=Lingot de Fer Iron Nugget=Pépite de Fer Iron Ore=Minerai de Fer Iron nuggets are very small pieces of molten iron; the main purpose is to create iron ingots.=Les pépites de fer sont de très petits morceaux de fer fondu; le but principal est de créer des lingots de fer. -Jungle Bark=Écorce d'Acajou +Jungle Bark=Bois d'Acajou Jungle Leaves=Feuilles d'Acajou Jungle Sapling=Pousse d'Acajou -Jungle Wood=Bois d'Acajou +Jungle Wood=Bûche d'Acajou Jungle Wood Planks=Planches d'Acajou Jungle leaves are grown from jungle trees.=Les feuilles d'Acajou sont cultivées à partir d'arbres d'Acajou. Ladder=Échelle +Lapis Lazuli=Lapis Lazuli +Lapis Lazuli are required for enchanting items on an enchanting table.=Les lapis-lazuli sont nécessaires pour enchanter des objets sur une table d'enchantement. Lapis Lazuli Block=Bloc de Lapis-Lazuli Lapis Lazuli Ore=Minerai de Lapis-Lazuli Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Le minerai de lapis-lazuli produit du lapis-lazuli. Il peut être rarement trouvé dans des filons près du fond du monde. @@ -146,10 +148,10 @@ Mossy Cobblestone=Pierre Moussue Mossy Stone Bricks=Pierre Taillée Moussue Mycelium=Mycélium Mycelium is a type of dirt and the ideal soil for mushrooms. Unlike other dirt-type blocks, it can not be turned into farmland with a hoe. In light, mycelium slowly spreads over nearby dirt. Under an opaque block or a liquid, it eventually turns back into dirt.=Le mycélium est un type de terre et le sol idéal pour les champignons. Contrairement à d'autres blocs de terre, il ne peut pas être transformé en terres agricoles avec une houe. À la lumière, le mycélium se répand lentement sur la terre voisine. Sous un bloc opaque ou un liquide, il finit par redevenir de la terre. -Oak Bark=Écorce de Chêne +Oak Bark=Bois de Chêne Oak Leaves=Feuilles de Chêne Oak Sapling=Pousse de Chêne -Oak Wood=Bois de Chêne +Oak Wood=Bûche de Chêne Oak Wood Planks=Planches de Chêne Oak leaves are grown from oak trees.=Les feuilles de chêne sont cultivées à partir de chênes. Obsidian=Obsidienne @@ -163,13 +165,13 @@ Paper is used to craft books and maps.=Le papier est utilisé pour créer des li Pink Stained Glass=Verre Rose Podzol=Podzol Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it.=Le podzol est un type de terre trouvé dans les forêts de la taïga. Seules quelques plantes peuvent y survivre. -Polished Andesite=Andrésite Polie +Polished Andesite=Andésite Polie Polished Diorite=Diorite Polie -Polished Granite=Granit Poli +Polished Granite=Granite Poli Polished Stone=Roche Polie Polished andesite is a decorative building block made from andesite.=L'andésite polie est un bloc de construction décoratif en andésite. Polished diorite is a decorative building block made from diorite.=La diorite polie est un bloc de construction décoratif en diorite. -Polished granite is a decorative building block made from granite.=Le granit poli est un bloc de construction décoratif en granit. +Polished granite is a decorative building block made from granite.=Le granite poli est un bloc de construction décoratif en granit. Purple Stained Glass=Verre Violet Realm Barrier=Barrière du royaume Red Sand=Sable Rouge @@ -192,30 +194,55 @@ Smooth sandstone is compressed sand and is a rather soft kind of stone.=Le grès Snow=Neige Some coal contained in stone, it is very common and can be found inside stone in medium to large clusters at nearly every height.=Du charbon contenu dans la pierre, il est très commun et peut être trouvé à l'intérieur de la pierre en grappes moyennes à grandes à presque toutes les hauteurs. Some iron contained in stone, it is prety common and can be found below sea level.=Du fer contenu dans la pierre, il est assez courant et se trouve sous le niveau de la mer. -Spruce Bark=Écorce de Sapin +Spruce Bark=Bois de Sapin Spruce Leaves=Feuilles de Sapin Spruce Sapling=Pousse de Sapin -Spruce Wood=Bois de Sapin +Spruce Wood=Bûche de Sapin Spruce Wood Planks=Planches de Sapin Spruce leaves are grown from spruce trees.=Les feuilles de sapin sont cultivées à partir de sapin. Stained glass is a decorative and mostly transparent block which comes in various different colors.=Le verre est un bloc décoratif et principalement transparent qui se décline en différentes couleurs. Stick=Bâton Sticks are a very versatile crafting material; used in countless crafting recipes.=Les bâtons sont un matériau d'artisanat très polyvalent; utilisé dans d'innombrables recettes d'artisanat. Stone=Roche +Stripped Acacia Log=Bûche d'Acacia Ecorcée +Stripped Acacia Wood=Bois d'Acacia Ecorcé +Stripped Birch Log=Bûche de Bouleau Ecorcée +Stripped Birch Wood=Bois de Bouleau Ecorcé +Stripped Dark Oak Log=Bûche de Chêne Noir +Stripped Dark Oak Wood=Bois de Chêne Noir +Stripped Jungle Log=Bûche d'Acajou Ecorcée +Stripped Jungle Wood=Bois d'Acajou Ecorcé +Stripped Oak Log=Bûche de Chêne Ecorcée +Stripped Oak Wood=Bois de Chêne Ecorcé +Stripped Spruce Log=Bûche de Sapin Ecorcée +Stripped Spruce Wood=Bois de Sapin Ecorcé Stone Bricks=Pierre Taillée Sugar=Sucre Sugar Canes=Canne à Sucre Sugar canes are a plant which has some uses in crafting. Sugar canes will slowly grow up to 3 blocks when they are next to water and are placed on a grass block, dirt, sand, red sand, podzol or coarse dirt. When a sugar cane is broken, all sugar canes connected above will break as well.=Les cannes à sucre sont une plante qui a certaines utilisations dans l'artisanat. Les cannes à sucre poussent lentement jusqu'à 3 blocs lorsqu'elles sont à côté de l'eau et sont placées sur un bloc d'herbe, de saleté, de sable, de sable rouge, de podzol ou de saleté grossière. Lorsqu'une canne à sucre est cassée, toutes les cannes à sucre connectées ci-dessus se brisent également. Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow.=Les cannes à sucre ne peuvent être placées que sur d'autres cannes à sucre et sur des blocs sur lesquels elles poussent. Sugar comes from sugar canes and is used to make sweet foods.=Le sucre provient des cannes à sucre et est utilisé pour fabriquer des aliments sucrés. +The stripped trunk of an acacia tree.=Le tronc écorcé d'un acacia. +The stripped trunk of a birch tree.=Le tronc écorcé d'un bouleau. +The stripped trunk of a dark oak tree.=Le tronc écorcé d'un chêne noir. +The stripped trunk of a jungle tree.=Le tronc écorcé d'un acajou. +The stripped trunk of an oak tree.=Le tronc écorcé d'un chêne. +The stripped trunk of a spruce tree.=Le tronc écorcé d'un sapin. The trunk of a birch tree.=Le tronc d'un bouleau. The trunk of a dark oak tree.=Le tronc d'un chêne noir. The trunk of a jungle tree.=Le tronc d'un acajou. The trunk of a spruce tree.=Le tronc d'un sapin. The trunk of an acacia.=Le tronc d'un acacia The trunk of an oak tree.=Le tronc d'un chêne. +The stripped wood of an acacia tree.=Le bois écorcé d'un acacia. +The stripped wood of a birch tree.=Le bois écorcé d'un bouleau. +The stripped wood of a dark oak tree.=Le bois écorcé d'un chêne noir. +The stripped wood of a jungle tree.=Le bois écorcé d'un acajou. +The stripped wood of an oak tree.=Le bois écorcé d'un chêne. +The stripped wood of a spruce tree.=Le bois écorcé d'un sapin. This block consists of a couple of loose stones and can't support itself.=Ce bloc se compose de quelques pierres lâches et ne peut pas se soutenir. This is a decorative block surrounded by the bark of a tree trunk.=Il s'agit d'un bloc décoratif entouré par l'écorce d'un tronc d'arbre. +This is a decorative block.=Il s'agit d'un bloc décoratif. This is a full block of snow. Snow of this thickness is usually found in areas of extreme cold.=Ceci est un bloc de neige complet. La neige de cette épaisseur se trouve généralement dans les zones de froid extrême. This is a piece of cactus commonly found in dry areas, especially deserts. Over time, cacti will grow up to 3 blocks high on sand or red sand. A cactus hurts living beings touching it with a damage of 1 HP every half second. When a cactus block is broken, all cactus blocks connected above it will break as well.=Il s'agit d'un morceau de cactus que l'on trouve couramment dans les zones sèches, en particulier dans les déserts. Au fil du temps, les cactus pousseront jusqu'à 3 blocs de haut sur le sable ou le sable rouge. Un cactus blesse les êtres vivants qui le touchent avec des dégâts de 1 HP toutes les demi-secondes. Lorsqu'un bloc de cactus est brisé, tous les blocs de cactus connectés au-dessus se brisent également. This stone contains pure gold, a rare metal.=Cette pierre contient de l'or pur, un métal rare. @@ -244,7 +271,7 @@ Lava interacts with water various ways:=La lave interagit avec l'eau de différe • When a lava source is directly below or horizontally next to water, the lava turns into obsidian.=• Lorsqu'une source de lave se trouve directement sous ou horizontalement à côté de l'eau, la lave se transforme en obsidienne. • When lava is directly above water, the water turns into stone.=• Lorsque la lave est directement au-dessus de l'eau, l'eau se transforme en pierre. Stained Glass=Verre teinté -Granite is an igneous rock.=Le granit est une roche ignée. +Granite is an igneous rock.=Le granite est une roche ignée. Top snow can be stacked and has one of 8 different height levels. At levels 2-8, top snow is collidable. Top snow drops 2-9 snowballs, depending on its height.=La neige peut être empilée et a l'un des 8 niveaux de hauteur différents. Aux niveaux 2 à 8, la neige provoque des collisions. La neige laisse tomber 2-9 boules de neige, selon sa hauteur. This block can only be placed on full solid blocks and on another top snow (which increases its height).=Ce bloc ne peut être placé que sur des blocs pleins et sur une autre neige (ce qui augmente sa hauteur). Needs soil and water to grow=A besoin de terre et d'eau pour se développer @@ -256,3 +283,6 @@ Slows down movement=Ralentit le mouvement 2×2 saplings @= large tree=2×2 pousses @= grand arbre Grows on sand or dirt next to water=Pousse sur le sable ou la terre près de l'eau Stackable=Empilable +Crying Obsidian=Obsidienne pleureuse +Crying obsidian is a luminous obsidian that can generate as part of ruined portals.=L'obsidienne pleureuse est une obsidienne luminause qui peut être générée dans les portails en ruine. +Enchanted Golden Apple=Pomme dorée enchantée diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ja.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ja.tr new file mode 100644 index 000000000..401b02700 --- /dev/null +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ja.tr @@ -0,0 +1,286 @@ +# textdomain: mcl_core +@1 could not survive in lava.=@1は溶岩の中で生き残ることができなかった。 +@1 died in lava.=@1は溶岩の中で息絶えた。 +@1 melted in lava.=@1は溶岩の中で溶解した。 +@1 took a bath in a hot lava tub.=@1は溶岩の浴槽に入浴した。 +A block of diamond is mostly a shiny decorative block but also useful as a compact storage of diamonds.=ダイヤモンドブロックは、主に装飾用の輝くブロックですが、ダイヤモンドをコンパクトに保管するのにも便利です。 +A block of emerald is mostly a shiny decorative block but also useful as a compact storage of emeralds.=エメラルドブロックは、主に装飾用の輝くブロックですが、エメラルドをコンパクトに保管するのにも便利です。 +A block of gold is mostly a shiny decorative block but also useful as a compact storage of gold ingots.=金ブロックは、主に装飾用の輝くブロックですが、金インゴットをコンパクトに保管するのにも便利です。 +A block of iron is mostly a decorative block but also useful as a compact storage of iron ingots.=鉄ブロックは、主に装飾用のブロックですが、鉄インゴットをコンパクトに保管するのにも便利です。 +A cactus can only be placed on top of another cactus or any sand.=サボテンは、他のサボテンや砂の上にしか置けません。 +A decorative and mostly transparent block.=装飾用の、ほとんどが透明なブロックです。 +A grass block is dirt with a grass cover. Grass blocks are resourceful blocks which allow the growth of all sorts of plants. They can be turned into farmland with a hoe and turned into grass paths with a shovel. In light, the grass slowly spreads onto dirt nearby. Under an opaque block or a liquid, a grass block may turn back to dirt.=草原とは、土に草を被せたものです。草原は、さまざまな植物を育てることができる、資源的なブロックです。クワで農地にしたり、シャベルでオフロードにしたりできます。光に当たると、近くの土の上に草がゆっくりと広がっていきます。不透明なブロックや液体の下では、草原は土に戻ることがあります。 +A lapis lazuli block is mostly a decorative block but also useful as a compact storage of lapis lazuli.=ラピスラズリブロックは、主に装飾用のブロックですが、ラピスラズリをコンパクトに保管するのにも便利です。 +A lava source sets fire to a couple of air blocks above when they're next to a flammable block.=溶岩源は、可燃性ブロックの隣にあると、その上の空気ブロック数個に火をつけます。 +A piece of ladder which allows you to climb vertically. Ladders can only be placed on the side of solid blocks and not on glass, leaves, ice, slabs, glowstone, nor sea lanterns.=垂直によじ登ることができるハシゴの一部です。ハシゴは固いブロックの側面にのみ設置でき、ガラス、葉、氷、スラブ、グローストーン、シーランタンの上には設置できません。 +Acacia Bark=アカシアの樹皮 +Acacia Leaves=アカシアの葉 +Acacia Sapling=アカシアの苗木 +Acacia Wood=アカシアの木 +Acacia Wood Planks=アカシアの板材 +Acacia leaves are grown from acacia trees.=アカシアの葉は、アカシアの木から育ちます。 +Andesite=安山岩 +Andesite is an igneous rock.=安山岩とは、火成岩の一種です。 +Apple=リンゴ +Apples are food items which can be eaten.=リンゴは食べられるアイテムです。 +Barrier=バリア +Barriers are invisble walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=バリアとは、不可視の歩行可能なブロックのことです。アドベンチャーマップの境界線などに使われます。モンスターや動物はバリアの上には現れませんし、フェンスもバリアには接続されません。バリアには、これまでのブロックと同様、他のブロックを建てられます。 +Bedrock=岩盤 +Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=岩盤は非常に硬い岩石の一種です。(クリエイティブモードでない限り)通常の手段では壊したり、破壊したり、集めたり、移動させることはできません。 +Birch Bark=シラカバの樹皮 +Birch Leaves=シラカバの葉 +Birch Sapling=シラカバの苗木 +Birch Wood=シラカバの木 +Birch Wood Planks=シラカバの板材 +Birch leaves are grown from birch trees.=シラカバの葉は、シラカバの木から育ちます。 +Black Stained Glass=黒色ガラス +Block of Coal=石炭ブロック +Block of Diamond=ダイヤモンドブロック +Block of Emerald=エメラルドブロック +Block of Gold=金ブロック +Block of Iron=鉄ブロック +Blocks of coal are useful as a compact storage of coal and very useful as a furnace fuel. A block of coal is as efficient as 10 coal.=石炭ブロックは、石炭をコンパクトに保管でき、炉の燃料として非常に便利です。1個の石炭ブロックは、10個の石炭と同じ効率です。 +Blue Stained Glass=青色ガラス +Bone Block=骨ブロック +Bone blocks are decorative blocks and a compact storage of bone meal.=骨ブロックは装飾用ブロックで、骨粉をコンパクトに保管できます。 +Bowl=ボウル +Bowls are mainly used to hold tasty soups.=ボウルは、主に美味しいスープを入れるために使われます。 +Brick=レンガ +Brick Block=レンガブロック +Brick blocks are a good building material for building solid houses and can take quite a punch.=レンガブロックは、頑丈な家を建てるのに適した建材で、かなりの衝撃にも耐えられます。 +Bricks are used to craft brick blocks.=レンガは、レンガブロックのクラフトに使います。 +Brown Stained Glass=茶色ガラス +Cactus=サボテン +Charcoal=木炭 +Charcoal is an alternative furnace fuel created by cooking wood in a furnace. It has the same burning time as coal and also shares many of its crafting recipes, but it can not be used to create coal blocks.=木炭はかまど用の代替燃料で、木をかまどで燃やすと作れます。石炭と同じ燃焼時間を持ち、クラフトのレシピも共通ですが、石炭ブロックの作成には使えません。 +Chiseled Stone Bricks=模様入り石レンガ +Chiseled Red Sandstone=模様入り赤い砂岩 +Chiseled Sandstone=模様入り砂岩 +Chiseled red sandstone is a decorative building block.=模様入り赤い砂岩は、装飾用ブロックです。 +Chiseled sandstone is a decorative building block.=模様入り砂岩は、装飾用ブロックです。 +Clay=粘土 +Clay Ball=粘土玉 +Clay balls are a raw material, mainly used to create bricks in the furnace.=粘土玉は原料で、主にかまどに入れてレンガを作るのに使われます。 +Clay is a versatile kind of earth commonly found at beaches underwater.=粘土は海水浴中によく見つかる、汎用性の高い土の一種です。 +Coal=石炭 +Coal Ore=石炭鉱石 +Coarse Dirt=粗い土 +Coarse dirt acts as a soil for some plants and is similar to dirt, but it will never grow a cover.=粗い土は、一部の植物の土として機能し、土と類似してはいますが、表層を何かが覆うことがありません。 +Cobblestone=丸石 +Cobweb=クモの巣 +Cobwebs can be walked through, but significantly slow you down.=クモの巣は歩いて通過できますが、大幅にノロくなります。 +Cracked Stone Bricks=ひび割れた石レンガ +Cut Red Sandstone=溝入り赤い砂岩 +Cut Sandstone=溝入り砂岩 +Cut red sandstone is a decorative building block.=溝入り赤い砂岩は、装飾用ブロックです。 +Cut sandstone is a decorative building block.=溝入り砂岩は、装飾用ブロックです。 +Cyan Stained Glass=青緑色ガラス +Dark Oak Bark=ダークオークの樹皮 +Dark Oak Leaves=ダークオークの葉 +Dark Oak Sapling=ダークオークの苗木 +Dark Oak Wood=ダークオークの木 +Dark Oak Wood Planks=ダークオークの板材 +Dark oak leaves are grown from dark oak trees.=ダークオークの葉は、ダークオークの木から育ちます。 +Dark oak saplings can grow into dark oaks, but only in groups. A lonely dark oak sapling won't grow. A group of four dark oak saplings grows into a dark oak after some time when they are placed on soil (such as dirt) in a 2×2 square and exposed to light.=ダークオークの苗木はダークオークに成長できますが、複数植えなければなりません。孤立したダークオークの苗木は成長しないのです。ダークオークの苗木を4本、正方形(2×2)の土壌(土など)の上に置き、光の下に晒しておくと、しばらくしたのちにダークオークへ成長します。 +Dead Bush=枯れ木 +Dead bushes are unremarkable plants often found in dry areas. They can be harvested for sticks.=枯れ木は、乾燥した場所によく見られる、路傍の植物です。棒として採取できます。 +Diamond=ダイヤモンド +Diamond Ore=ダイヤモンド鉱石 +Diamond ore is rare and can be found in clusters near the bottom of the world.=ダイヤモンド鉱石は希少で、ワールドの深層近くでまとまって見つかります。 +Diamonds are precious minerals and useful to create the highest tier of armor and tools.=ダイヤモンドは貴重な鉱物で、最上位の防具や道具のクラフトに役立ちます。 +Diorite=閃緑岩 +Diorite is an igneous rock.=閃緑岩とは、火成岩の一種です。 +Dirt=土 +Dirt acts as a soil for a few plants. When in light, this block may grow a grass or mycelium cover if such blocks are nearby.=土はいくつかの植物のための土壌として機能します。明るいところで近くに草や菌糸で覆われたブロックがあれば、このブロックの表層にもそれら成長させることがあります。 +Emerald=エメラルド +Emerald Ore=エメラルド鉱石 +Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=エメラルド鉱石は非常に希少で、群生しておらず、単独で見つけられます。 +Emeralds are used in villager trades as currency.=エメラルドは、村人との取引で通貨として使われます。 +Flint=火打石 +Flint is a raw material.=火打石は原料です。 +Flowing Lava=流れる溶岩 +Flowing Water=流れる水 +Frosted Ice=薄氷 +Frosted ice is a short-lived solid block. It melts into a water source within a few seconds.=薄氷は短命の固形ブロックです。水源の中では数秒で融けてしまいます。 +Glass=ガラス +Gold Ingot=金インゴット +Gold Nugget=金の小塊 +Gold Ore=金鉱石 +Gold nuggets are very small pieces of molten gold; the main purpose is to create gold ingots.=金の小塊は、溶けた金のごく小さな断片で、主に金インゴットを作るために使われます。 +Golden Apple=金のリンゴ +Golden apples are precious food items which can be eaten.=金のリンゴは貴重な食材で、食べられます。 +Granite=花崗岩 +Grass Block=草原 +Grass Path=オフロード +Grass paths are a decorative variant of grass blocks. Their top has a different color and they are a bit lower than grass blocks, making them useful to build footpaths. Grass paths can be created with a shovel. A grass path turns into dirt when it is below a solid block.=オフロードは、草原の装飾的なバリエーションです。上部の色が異なり、草原より少し低いので、道にうってつけです。シャベルで作れます。オフロードは、固いブロックの下にあると土になります。 +Gravel=砂利 +Green Stained Glass=緑色ガラス +Grey Stained Glass=灰色ガラス +Ice=氷 +Ice is a solid block usually found in cold areas. It melts near block light sources at a light level of 12 or higher. When it melts or is broken while resting on top of another block, it will turn into a water source.=氷は、通常寒い地域にある固体ブロックです。明るさ12以上の光源ブロック付近では溶けます。他のブロックの上に乗っているときに溶けたり割れたりすると、水源に変わります。 +In the End dimension, starting a fire on this block will create an eternal fire.=エンドの次元では、このブロック上で火を起こすと、永続的な炎が生まれます。 +Iron Ingot=鉄インゴット +Iron Nugget=鉄の小塊 +Iron Ore=鉄鉱石 +Iron nuggets are very small pieces of molten iron; the main purpose is to create iron ingots.=鉄の小塊は、溶けた鉄のごく小さな断片で、主に鉄インゴットを作るために使われます。 +Jungle Bark=ジャングルの樹皮 +Jungle Leaves=ジャングルの葉 +Jungle Sapling=ジャングルの苗木 +Jungle Wood=ジャングルの木 +Jungle Wood Planks=ジャングルの板材 +Jungle leaves are grown from jungle trees.=ジャングルの葉は、ジャングルの木から育ちます。 +Ladder=ハシゴ +Lapis Lazuli Block=ラピスラズリブロック +Lapis Lazuli Ore=ラピスラズリ鉱石 +Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=ラピスラズリ鉱石は、ワールドの深層あたりで群生しているのが稀に見つかります。 +Lava Source=溶岩源 +Lava is hot and rather dangerous. Don't touch it, it will hurt you a lot and it is hard to get out.=溶岩は熱くてだいぶ危険です。触れてはいけません、とても痛いし、出るのも大変です。 +Light Blue Stained Glass=空色ガラス +Light Grey Stained Glass=薄灰色ガラス +Lime Stained Glass=黄緑色ガラス +Lit Redstone Ore=発光したレッドストーン鉱石 +Magenta Stained Glass=赤紫色ガラス +Molten gold. It is used to craft armor, tools, and whatnot.=溶かした金。防具や道具、その他のクラフトに使われます。 +Molten iron. It is used to craft armor, tools, and whatnot.=溶かした鉄。防具や道具、その他のクラフトに使われます。 +Mossy Cobblestone=苔むした丸石 +Mossy Stone Bricks=苔むした石レンガ +Mycelium=菌糸 +Mycelium is a type of dirt and the ideal soil for mushrooms. Unlike other dirt-type blocks, it can not be turned into farmland with a hoe. In light, mycelium slowly spreads over nearby dirt. Under an opaque block or a liquid, it eventually turns back into dirt.=菌糸は土の一種であり、キノコに最適な土壌です。他の土系ブロックと違い、クワで農地に変えられません。光に当たると、菌糸は近くの土の上にゆっくりと広がっていきます。不透明なブロックや液体の下では、それはやがて土に戻ります。 +Oak Bark=オークの樹皮 +Oak Leaves=オークの葉 +Oak Sapling=オークの苗木 +Oak Wood=オークの木 +Oak Wood Planks=オークの板材 +Oak leaves are grown from oak trees.=オークの葉は、オークの木から育ちます。 +Obsidian=黒曜石 +Obsidian is an extremely hard mineral with an enourmous blast-resistance. Obsidian is formed when water meets lava.=黒曜石は、とてつもなく硬い鉱物で耐爆性が抜群です。黒曜石は、水と溶岩が出会って形成されたものです。 +One of the most common blocks in the world, almost the entire underground consists of stone. It sometimes contains ores. Stone may be created when water meets lava.=世界で最も一般的なブロックの一つで、地下のほぼ全体が石で構成されています。時には鉱石を含むこともあります。水と溶岩が出会って石ができる場合もあります。 +Orange Stained Glass=橙色ガラス +Packed Ice=氷塊 +Packed ice is a compressed form of ice. It is opaque and solid.=氷塊は、氷が圧縮した形態です。不透明で固形です。 +Paper=紙 +Paper is used to craft books and maps.=紙は、本や地図などのクラフトに使われます。 +Pink Stained Glass=桃色ガラス +Podzol=ポドゾル +Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it.=ポドゾルとは、タイガの森で見つかる土の一種です。その上で生きられる植物はごくわずかです。 +Polished Andesite=磨かれた安山岩 +Polished Diorite=磨かれた閃緑岩 +Polished Granite=磨かれた花崗岩 +Polished Stone=磨かれた石 +Polished andesite is a decorative building block made from andesite.=磨かれた安山岩は装飾的な建築用ブロックで、安山岩から作られます。 +Polished diorite is a decorative building block made from diorite.=磨かれた閃緑岩は装飾的な建築用ブロックで、閃緑岩から作られます。 +Polished granite is a decorative building block made from granite.=磨かれた花崗岩は装飾的な建築用ブロックで、花崗岩から作られます。 +Purple Stained Glass=紫色ガラス +Realm Barrier=領域障壁 +Red Sand=赤い砂 +Red Sandstone=赤い砂岩 +Red Stained Glass=赤色ガラス +Red sand is found in large quantities in mesa biomes.=赤い砂は、メサバイオームで大量に見つかります。 +Red sandstone is compressed red sand and is a rather soft kind of stone.=赤い砂岩は赤い砂を圧縮したもので、やや軟らかい種類の石です。 +Redstone Ore=レッドストーン鉱石 +Redstone ore is commonly found near the bottom of the world. It glows when it is punched or walked upon.=レッドストーン鉱石は、ワールドの低層に多く見られます。それをパンチしたり、踏んだりすると光ります。 +Sand=砂 +Sand is found in large quantities at beaches and deserts.=砂は、海岸や砂漠で大量に見つかります。 +Sandstone=砂岩 +Sandstone is compressed sand and is a rather soft kind of stone.=砂岩は砂を圧縮したもので、やや軟らかい種類の石です。 +Slime Block=スライムブロック +Slime blocks are very bouncy and prevent fall damage.=スライムブロックは非常に弾力性があり、落下ダメージを防ぐことができます。 +Smooth Red Sandstone=滑らかな赤い砂岩 +Smooth Sandstone=滑らかな砂岩 +Smooth red sandstone is a decorative building block.=滑らかな赤い砂岩は、装飾的な建築ブロックです。 +Smooth sandstone is compressed sand and is a rather soft kind of stone.=滑らかな砂岩は、装飾的な建築ブロックです。 +Snow=雪 +Some coal contained in stone, it is very common and can be found inside stone in medium to large clusters at nearly every height.=石に含まれる石炭はとても一般的で、ほぼすべての高さにおいて、中~大規模なまとまりで見つけることができます。 +Some iron contained in stone, it is prety common and can be found below sea level.=石に含まれる鉄はかなり一般的で、海面下の高さで見つけられます。 +Spruce Bark=トウヒの樹皮 +Spruce Leaves=トウヒの葉 +Spruce Sapling=トウヒの苗木 +Spruce Wood=トウヒの木 +Spruce Wood Planks=トウヒの板材 +Spruce leaves are grown from spruce trees.=トウヒの葉は、トウヒの木から育ちます。 +Stained glass is a decorative and mostly transparent block which comes in various different colors.=色ガラスは、そのほとんどが透明な装飾ブロックで、さまざまなカラーバリエーションがあります。 +Stick=棒 +Sticks are a very versatile crafting material; used in countless crafting recipes.=棒は、数え切れないほどのクラフトレシピに使用されている、非常に汎用性の高いクラフト素材です。 +Stone=石 +Stripped Acacia Log=樹皮を剥いだアカシアの原木 +Stripped Acacia Wood=樹皮を剥いだアカシアの木 +Stripped Birch Log=樹皮を剥いだシラカバの原木 +Stripped Birch Wood=樹皮を剥いだシラカバの木 +Stripped Dark Oak Log=樹皮を剥いだダークオークの原木 +Stripped Dark Oak Wood=樹皮を剥いだダークオークの木 +Stripped Jungle Log=樹皮を剥いだジャングルの原木 +Stripped Jungle Wood=樹皮を剥いだジャングルの木 +Stripped Oak Log=樹皮を剥いだオークの原木 +Stripped Oak Wood=樹皮を剥いだオークの木 +Stripped Spruce Log=樹皮を剥いだトウヒの原木 +Stripped Spruce Wood=樹皮を剥いだトウヒの木 +Stone Bricks=石レンガ +Sugar=砂糖 +Sugar Canes=サトウキビ +Sugar canes are a plant which has some uses in crafting. Sugar canes will slowly grow up to 3 blocks when they are next to water and are placed on a grass block, dirt, sand, red sand, podzol or coarse dirt. When a sugar cane is broken, all sugar canes connected above will break as well.=サトウキビはクラフトに使える植物です。水のある場所で、草原、土、砂、赤い砂、ポドゾル、粗い土の上にサトウキビを置くと、ゆっくりと3ブロックまで成長します。サトウキビが折れるときは、上につながっているすべてのサトウキビも折れます。 +Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow.=サトウキビは、他のサトウキビの上や、サトウキビが成長するブロックの上にしか置けません。 +Sugar comes from sugar canes and is used to make sweet foods.=砂糖はサトウキビから採れ、甘いものを作るのに使われます。 +The stripped trunk of an acacia tree.=樹皮が剥がれたアカシアの樹幹です。 +The stripped trunk of a birch tree.=樹皮が剥がれたシラカバの樹幹です。 +The stripped trunk of a dark oak tree.=樹皮が剥がれたダークオークの樹幹です。 +The stripped trunk of a jungle tree.=樹皮が剥がれたジャングルの樹幹です。 +The stripped trunk of an oak tree.=樹皮が剥がれたオークの樹幹です。 +The stripped trunk of a spruce tree.=樹皮が剥がれたトウヒの樹幹です。 +The trunk of a birch tree.=シラカバの樹幹です。 +The trunk of a dark oak tree.=ダークオークの樹幹です。 +The trunk of a jungle tree.=ジャングルの樹幹です。 +The trunk of a spruce tree.=トウヒの樹幹です。 +The trunk of an acacia.=アカシアの樹幹です。 +The trunk of an oak tree.=オークの樹幹です。 +The stripped wood of an acacia tree.=樹皮が剥がれたアカシアの木です。 +The stripped wood of a birch tree.=樹皮が剥がれたシラカバの木です。 +The stripped wood of a dark oak tree.=樹皮が剥がれたダークオークの木です。 +The stripped wood of a jungle tree.=樹皮が剥がれたジャングルの木です。 +The stripped wood of an oak tree.=樹皮が剥がれたオークの木です。 +The stripped wood of a spruce tree.=樹皮が剥がれたトウヒの木です。 +This block consists of a couple of loose stones and can't support itself.=このブロックは緩い石の組み合わせで構成されており、自身を支えられません。 +This is a decorative block surrounded by the bark of a tree trunk.=これは、木の幹の皮に覆われた装飾ブロックです。 +This is a decorative block.=これは装飾ブロックです。 +This is a full block of snow. Snow of this thickness is usually found in areas of extreme cold.=これは1ブロックサイズの雪です。この厚さの雪は、おおむね極寒の地で見られます。 +This is a piece of cactus commonly found in dry areas, especially deserts. Over time, cacti will grow up to 3 blocks high on sand or red sand. A cactus hurts living beings touching it with a damage of 1 HP every half second. When a cactus block is broken, all cactus blocks connected above it will break as well.=これは乾燥した地域、特に砂漠によく見られるサボテンの一種です。サボテンは砂や赤い砂の上で時間が経つと、3ブロックの高さまで成長します。サボテンはそれに触れた生物を傷つけます(1HP/0.5秒のダメージ)。サボテンのブロックが壊れると、その上につながっているすべてのサボテンのブロックも壊れます。 +This stone contains pure gold, a rare metal.=この石には、希少金属である純金が含まれています。 +Top Snow=積雪 +Top snow is a layer of snow. It melts near light sources other than the sun with a light level of 12 or higher.=積雪とは、雪の層です。太陽を除く明るさ12以上の光源付近で融けます。 +Vines=ツタ +Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread.=ツタは、フルサイズのブロックの側面に配置できる、よじ登り可能なブロックです。ツタはゆっくりと成長し、広がっていきます。 +Void=奈落 +Water=水 +Water Source=水源 +Water is abundant in oceans and also appears in a few springs in the ground. You can swim easily in water, but you need to catch your breath from time to time.=水は海に豊富にあり、また地中のわずかな湧水にも現れます。水中では簡単に泳ぐことができますが、時々息を整える必要があります。 +When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.=シラカバの苗木は、土壌(土など)の上に置いて光を当てると、しばらくしたのちシラカバの木に成長します。 +When placed on soil (such as dirt) and exposed to light, a jungle sapling will grow into a jungle tree after some time. When there are 4 jungle saplings in a 2×2 square, they will grow to a huge jungle tree.=ジャングルの苗木は、土壌(土など)の上に置いて光を当てると、しばらくしたのちジャングルの木に成長します。正方形(2×2)に4本の苗木があると、巨大なジャングルの木に成長します。 +When placed on soil (such as dirt) and exposed to light, a spruce sapling will grow into a spruce after some time. When there are 4 spruce saplings in a 2×2 square, they will grow to a huge spruce.=トウヒの苗木は、土壌(土など)の上に置いて光を当てると、しばらくしたのちトウヒの木に成長します。正方形(2×2)に4本の苗木があると、巨大なトウヒの木に成長します。 +When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.=アカシアの苗木は、土壌(土など)の上に置いて光を当てると、しばらくしたのちアカシアの木に成長します。 +When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.=オークの苗木は、土壌(土など)の上に置いて光を当てると、しばらくしたのちオークの木に成長します。 +When you hold a barrier in hand, you reveal all placed barriers in a short distance around you.=バリアを手にすると、周囲の近距離に配置されたバリアがすべて表示されます。 +White Stained Glass=白色ガラス +Yellow Stained Glass=黄色ガラス +“Coal” refers to coal lumps obtained by digging coal ore which can be found underground. Coal is your standard furnace fuel, but it can also be used to make torches, coal blocks and a few other things.=「石炭」とは、地中の石炭鉱石を掘って得られる石炭の塊のことを指します。石炭はかまどの燃料として一般的ですが、松明や石炭ブロックなどにも利用されます。 +Water interacts with lava in various ways:=水は溶岩とさまざまな形で相互作用します: +• When water is directly above or horizontally next to a lava source, the lava turns into obsidian.=・溶岩源の上や横に水が隣接すると、溶岩源は黒曜石に変化します。 +• When flowing water touches flowing lava either from above or horizontally, the lava turns into cobblestone.=・流れる溶岩の上や横に流れる水が触れると、溶岩は丸石に変化します。 +• When water is directly below lava, the water turns into stone.=・水が溶岩の真下にあると、水は石に変化します。 +Lava interacts with water various ways:=溶岩は水とさまざまな相互作用をします: +• When a lava source is directly below or horizontally next to water, the lava turns into obsidian.=・溶岩源が水の下や横に隣接している場合、溶岩源は黒曜石に変化します。 +• When lava is directly above water, the water turns into stone.=・溶岩が水の真上にあると、水は石に変化します。 +Stained Glass=色ガラス +Granite is an igneous rock.=花崗岩とは、火成岩の一種です。 +Top snow can be stacked and has one of 8 different height levels. At levels 2-8, top snow is collidable. Top snow drops 2-9 snowballs, depending on its height.=積雪は積み重ねることができ、8段階の高さが選べます。2~8段では、積雪に衝突性があります。積雪は高さに応じて2~9個の雪玉を落とします。 +This block can only be placed on full solid blocks and on another top snow (which increases its height).=このブロックは、完全な固体ブロックの上と、別の積雪の上にしか置けません(高さが増えます)。 +Needs soil and water to grow=生育に必要なのは、土壌と水 +Needs soil and light to grow=生育に必要なのは、土壌と光 +Grows on sand=砂の上に生育 +Contact damage: @1 per half second=接触ダメージ:@1/0.5秒 +Slows down movement=動きが遅くなる +2×2 saplings required=2×2本の苗木が必要 +2×2 saplings @= large tree=2×2本の苗木で @=は大木となる +Grows on sand or dirt next to water=水辺の砂や土の上に生育 +Stackable=スタック可能 +Crying Obsidian=泣く黒曜石 +Crying obsidian is a luminous obsidian that can generate as part of ruined portals.=泣く黒曜石は、廃墟のポータルの一部として生成可能な、発光する黒曜石です。 +Enchanted Golden Apple=エンチャントされた金のリンゴ \ No newline at end of file diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr index 68dfbd3d0..8e9d7cf8f 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr @@ -130,6 +130,8 @@ Jungle Wood=Tropikalne drewno Jungle Wood Planks=Tropikalne deski Jungle leaves are grown from jungle trees.=Tropikalne liście rosną na tropikalnych drzewach. Ladder=Drabina +Lapis Lazuli=Lazuryt +Lapis Lazuli are required for enchanting items on an enchanting table.=Lapis Lazuli są wymagane do zaklinania przedmiotów na zaklinającym stole. Lapis Lazuli Block=Blok lazurytu Lapis Lazuli Ore=Ruda lazurytu Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Ruda lazurytu jest rzadko występującym blokiem, który można znaleźć w grupach przy dnie świata. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index 2d5b5462c..831795792 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -130,6 +130,8 @@ Jungle Wood=Дерево джунглей Jungle Wood Planks=Доски из дерева джунглей Jungle leaves are grown from jungle trees.=Листва дерева джунглей произрастает на деревьях джунглей. Ladder=Лестница +Lapis Lazuli=Ляпис-лазурь +Lapis Lazuli are required for enchanting items on an enchanting table.=Лазурит требуется для зачарования предметов на столе зачаровывания. Lapis Lazuli Block=Ляпис-лазурный блок Lapis Lazuli Ore=Ляпис-лазурная руда Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Ляпис-лазурная руда это руда ляпис-лазури. Она изредка встречается в виде скоплений вблизи дна мира. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr b/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr index 177341846..0e8280c6e 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr @@ -129,6 +129,8 @@ Jungle Wood=叢林原木 Jungle Wood Planks=叢林木材 Jungle leaves are grown from jungle trees.=叢林樹葉是由叢林樹生長出來的。 Ladder=梯子 +Lapis Lazuli=青金石 +Lapis Lazuli are required for enchanting items on an enchanting table.=为附魔台上的物品附魔需要青金石。 Lapis Lazuli Block=青金石磚 Lapis Lazuli Ore=青金石礦 Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=青金石礦是青金石的礦石。在世界底部附近能發現成群的和稀有的青金石礦。 diff --git a/mods/ITEMS/mcl_core/locale/template.txt b/mods/ITEMS/mcl_core/locale/template.txt index 19d156711..a7798b9cd 100644 --- a/mods/ITEMS/mcl_core/locale/template.txt +++ b/mods/ITEMS/mcl_core/locale/template.txt @@ -130,6 +130,8 @@ Jungle Wood= Jungle Wood Planks= Jungle leaves are grown from jungle trees.= Ladder= +Lapis Lazuli= +Lapis Lazuli are required for enchanting items on an enchanting table.= Lapis Lazuli Block= Lapis Lazuli Ore= Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.= @@ -281,3 +283,6 @@ Slows down movement= 2×2 saplings @= large tree= Grows on sand or dirt next to water= Stackable= +Crying Obsidian= +Crying obsidian is a luminous obsidian that can generate as part of ruined portals.= +Enchanted Golden Apple= diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index 0e9b53d04..476bdf9ce 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -63,11 +63,12 @@ minetest.register_node("mcl_core:stone_with_iron", { is_ground_content = true, stack_max = 64, groups = {pickaxey=3, building_block=1, material_stone=1, blast_furnace_smeltable=1}, - drop = "mcl_core:stone_with_iron", + drop = "mcl_raw_ores:raw_iron", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) @@ -78,18 +79,22 @@ minetest.register_node("mcl_core:stone_with_gold", { is_ground_content = true, stack_max = 64, groups = {pickaxey=4, building_block=1, material_stone=1, blast_furnace_smeltable=1}, - drop = "mcl_core:stone_with_gold", + drop = "mcl_raw_ores:raw_gold", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) local redstone_timer = 68.28 -local function redstone_ore_activate(pos) +local function redstone_ore_activate(pos, node, puncher, pointed_thing) minetest.swap_node(pos, {name="mcl_core:stone_with_redstone_lit"}) local t = minetest.get_node_timer(pos) t:start(redstone_timer) + if puncher and pointed_thing then + return minetest.node_punch(pos, node, puncher, pointed_thing) + end end minetest.register_node("mcl_core:stone_with_redstone", { description = S("Redstone Ore"), @@ -124,9 +129,12 @@ minetest.register_node("mcl_core:stone_with_redstone", { } }) -local function redstone_ore_reactivate(pos) +local function redstone_ore_reactivate(pos, node, puncher, pointed_thing) local t = minetest.get_node_timer(pos) t:start(redstone_timer) + if puncher and pointed_thing then + return minetest.node_punch(pos, node, puncher, pointed_thing) + end end -- Light the redstone ore up when it has been touched minetest.register_node("mcl_core:stone_with_redstone_lit", { @@ -179,11 +187,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_core:lapis 8"},rarity = 5}, + {items = {"mcl_core:lapis 7"},rarity = 5}, + {items = {"mcl_core:lapis 6"},rarity = 5}, + {items = {"mcl_core:lapis 5"},rarity = 5}, + {items = {"mcl_core:lapis 4"}}, } }, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -361,7 +369,7 @@ minetest.register_node("mcl_core:dirt_with_grass", { _doc_items_longdesc = S("A grass block is dirt with a grass cover. Grass blocks are resourceful blocks which allow the growth of all sorts of plants. They can be turned into farmland with a hoe and turned into grass paths with a shovel. In light, the grass slowly spreads onto dirt nearby. Under an opaque block or a liquid, a grass block may turn back to dirt."), _doc_items_hidden = false, paramtype2 = "color", - tiles = {"mcl_core_grass_block_top.png", { name="default_dirt.png", color="white" }}, + tiles = {"mcl_core_grass_block_top.png", { name="default_dirt.png", color="white" }, { name="default_dirt.png^mcl_dirt_grass_shadow.png", color="white" }}, overlay_tiles = {"mcl_core_grass_block_top.png", "", {name="mcl_core_grass_block_side_overlay.png", tileable_vertical=false}}, palette = "mcl_core_palette_grass.png", palette_index = 0, @@ -389,7 +397,7 @@ minetest.register_node("mcl_core:dirt_with_grass", { return mcl_core.on_snowable_construct(pos) end, _mcl_snowed = "mcl_core:dirt_with_grass_snow", - _mcl_blast_resistance = 0.5, + _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, _mcl_silk_touch_drop = true, }) @@ -426,7 +434,7 @@ minetest.register_node("mcl_core:mycelium", { tiles = {"mcl_core_mycelium_top.png", "default_dirt.png", {name="mcl_core_mycelium_side.png", tileable_vertical=false}}, is_ground_content = true, stack_max = 64, - groups = { handy = 1, shovely = 1, dirt = 2, spreading_dirt_type = 1, enderman_takable = 1, building_block = 1, soil_sapling = 2, path_creation_possible=1}, + groups = { handy = 1, shovely = 1, dirt = 2, spreading_dirt_type = 1, enderman_takable = 1, building_block = 1, soil_sapling = 2, path_creation_possible=1, mycelium=1}, drop = "mcl_core:dirt", sounds = mcl_sounds.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.1}, @@ -434,12 +442,50 @@ minetest.register_node("mcl_core:mycelium", { on_construct = mcl_core.on_snowable_construct, _mcl_snowed = "mcl_core:mycelium_snow", - _mcl_blast_resistance = 0.5, + _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, _mcl_silk_touch_drop = true, }) mcl_core.register_snowed_node("mcl_core:mycelium_snow", "mcl_core:mycelium", nil, nil, false, S("Mycelium with Snow")) +local PARTICLE_ABM_DISTANCE = 16 + +--if minetest.settings:get("mcl_node_particles") == "full" then +minetest.register_abm({ + label = "Townaura particles", + nodenames = {"group:mycelium"}, + interval = 2, + chance = 30, + action = function(pos, node) + local player_near = false + for _,player in pairs(minetest.get_connected_players()) do + if vector.distance(player:get_pos(), pos) < PARTICLE_ABM_DISTANCE then + player_near = true + end + end + if player_near then + local apos = {x=pos.x-2, y=pos.y+0.51, z=pos.z-2} + local apos2 = {x=pos.x+2, y=pos.y+0.51, z=pos.z+2} + local acc = { x = 0, y = 0, z = 0 } + minetest.add_particlespawner({ + time = 2, + amount = 5, + minpos = apos, + maxpos = apos2, + minvel = vector.new(-3/10, 0, -3/10), + maxvel = vector.new(3/10, 10/60, 3/10), + minacc = acc, + expirationtime = 4, + collisiondetection = true, + collision_removal = true, + size = 1, + texture = "mcl_core_mycelium_particle.png", + }) + end + end, +}) +--end + minetest.register_node("mcl_core:podzol", { description = S("Podzol"), _doc_items_longdesc = S("Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it."), @@ -451,8 +497,8 @@ minetest.register_node("mcl_core:podzol", { sounds = mcl_sounds.node_sound_dirt_defaults(), on_construct = mcl_core.on_snowable_construct, _mcl_snowed = "mcl_core:podzol_snow", - _mcl_blast_resistance = 0.5, - _mcl_hardness = 0.6, + _mcl_blast_resistance = 0.8, + _mcl_hardness = 0.8, _mcl_silk_touch_drop = true, }) mcl_core.register_snowed_node("mcl_core:podzol_snow", "mcl_core:podzol", nil, nil, false, S("Podzol with Snow")) @@ -496,9 +542,7 @@ minetest.register_node("mcl_core:gravel", { {items = {"mcl_core:gravel"}} } }, - sounds = mcl_sounds.node_sound_dirt_defaults({ - footstep = {name="default_gravel_footstep", gain=0.45}, - }), + sounds = mcl_sounds.node_sound_gravel_defaults(), _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, _mcl_silk_touch_drop = true, @@ -556,8 +600,8 @@ minetest.register_node("mcl_core:sandstonesmooth", { stack_max = 64, groups = {pickaxey=1, sandstone=1, normal_sandstone=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 0.8, - _mcl_hardness = 0.8, + _mcl_blast_resistance = 6, + _mcl_hardness = 2, }) minetest.register_node("mcl_core:sandstonecarved", { @@ -581,8 +625,8 @@ minetest.register_node("mcl_core:sandstonesmooth2", { stack_max = 64, groups = {pickaxey=1, sandstone=1, normal_sandstone=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 0.8, - _mcl_hardness = 0.8, + _mcl_blast_resistance = 6, + _mcl_hardness = 2, }) -- red sandstone -- @@ -775,7 +819,7 @@ minetest.register_node("mcl_core:goldblock", { groups = {pickaxey=4, building_block=1}, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 6, - _mcl_hardness = 5, + _mcl_hardness = 3, }) minetest.register_node("mcl_core:diamondblock", { @@ -831,6 +875,19 @@ minetest.register_node("mcl_core:obsidian", { end, }) +minetest.register_node("mcl_core:crying_obsidian", { + description = S("Crying Obsidian"), + _doc_items_longdesc = S("Crying obsidian is a luminous obsidian that can generate as part of ruined portals."), + tiles = {"default_obsidian.png^mcl_core_crying_obsidian.png"}, + is_ground_content = false, + light_source = 10, + sounds = mcl_sounds.node_sound_stone_defaults(), + stack_max = 64, + groups = {pickaxey=5, building_block=1, material_stone=1}, + _mcl_blast_resistance = 1200, + _mcl_hardness = 50, +}) + minetest.register_node("mcl_core:ice", { description = S("Ice"), _doc_items_longdesc = S("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."), @@ -842,7 +899,7 @@ minetest.register_node("mcl_core:ice", { stack_max = 64, groups = {handy=1,pickaxey=1, slippery=3, building_block=1, ice=1}, drop = "", - sounds = mcl_sounds.node_sound_glass_defaults(), + sounds = mcl_sounds.node_sound_ice_defaults(), node_dig_prediction = "mcl_core:water_source", after_dig_node = function(pos, oldnode) mcl_core.melt_ice(pos) @@ -860,7 +917,7 @@ minetest.register_node("mcl_core:packed_ice", { stack_max = 64, groups = {handy=1,pickaxey=1, slippery=3, building_block=1, ice=1}, drop = "", - sounds = mcl_sounds.node_sound_glass_defaults(), + sounds = mcl_sounds.node_sound_ice_defaults(), _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, _mcl_silk_touch_drop = true, @@ -908,7 +965,7 @@ for i=0,3 do stack_max = 64, groups = {handy=1, frosted_ice=1, slippery=3, not_in_creative_inventory=1, ice=1}, drop = "", - sounds = mcl_sounds.node_sound_glass_defaults(), + sounds = mcl_sounds.node_sound_ice_defaults(), on_construct = function(pos) local timer = minetest.get_node_timer(pos) timer:start(1.5) @@ -1038,7 +1095,7 @@ for i=1,8 do mcl_core.clear_snow_dirt(npos, node) end, node_box = node_box, - groups = {shovely=1, attached_node=1,deco_block=1, dig_by_piston=1, snow_cover=1, top_snow=i}, + groups = {shovely=2, attached_node=1,deco_block=1, dig_by_piston=1, snow_cover=1, top_snow=i}, sounds = mcl_sounds.node_sound_snow_defaults(), on_construct = mcl_core.on_snow_construct, on_place = on_place, @@ -1057,13 +1114,13 @@ minetest.register_node("mcl_core:snowblock", { tiles = {"default_snow.png"}, is_ground_content = true, stack_max = 64, - groups = {shovely=1, building_block=1, snow_cover=1}, + groups = {shovely=2, building_block=1, snow_cover=1}, sounds = mcl_sounds.node_sound_snow_defaults(), on_construct = mcl_core.on_snow_construct, after_destruct = mcl_core.after_snow_destruct, drop = "mcl_throwing:snowball 4", - _mcl_blast_resistance = 0.2, - _mcl_hardness = 0.2, + _mcl_blast_resistance = 0.1, + _mcl_hardness = 0.1, _mcl_silk_touch_drop = true, }) diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index 0e0f71a11..081f1978a 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -49,7 +49,8 @@ minetest.register_node("mcl_core:water_flowing", { liquid_alternative_source = "mcl_core:water_source", liquid_viscosity = WATER_VISC, liquid_range = 7, - post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, + waving = 3, + post_effect_color = {a=20, r=0x03, g=0x3C, b=0x5C}, groups = { water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1, dig_by_piston=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode @@ -67,6 +68,7 @@ S("• When flowing water touches flowing lava either from above or horizontally S("• When water is directly below lava, the water turns into stone."), _doc_items_hidden = false, drawtype = "liquid", + waving = 3, tiles = { {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} }, @@ -93,7 +95,7 @@ S("• When water is directly below lava, the water turns into stone."), liquid_alternative_source = "mcl_core:water_source", liquid_viscosity = WATER_VISC, liquid_range = 7, - post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, + post_effect_color = {a=60, r=0x03, g=0x3C, b=0x5C}, stack_max = 64, groups = { water=3, liquid=3, puts_out_fire=1, freezes=1, not_in_creative_inventory=1, dig_by_piston=1}, _mcl_blast_resistance = 100, diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 54a43d6bf..787faa6d7 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -8,6 +8,40 @@ if mod_screwdriver then on_rotate = screwdriver.rotate_3way end +-- Check dug/destroyed tree trunks for orphaned leaves. +-- +-- This function is meant to be called by the `after_destruct` handler of +-- treetrunk nodes. +-- +-- Whenever a trunk node is removed, all `group:leaves` nodes in a sphere +-- with radius 6 are checked. Every such node that does not have a trunk +-- node within a distance of 6 blocks is converted into a orphan leaf node. +-- An ABM will gradually decay these nodes. +-- +-- If param2 of the node is set to a nonzero value, the node will always +-- be preserved. This is set automatically when leaves are placed manually. +-- +-- @param pos the position of the removed trunk node. +-- @param oldnode the node table of the removed trunk node. +function mcl_core.update_leaves(pos, oldnode) + local pos1, pos2 = vector.offset(pos, -6, -6, -6), vector.offset(pos, 6, 6, 6) + local lnode + local leaves = minetest.find_nodes_in_area(pos1, pos2, "group:leaves") + for _, lpos in pairs(leaves) do + lnode = minetest.get_node(lpos) + -- skip already decaying leaf nodes + if minetest.get_item_group(lnode.name, "orphan_leaves") ~= 1 then + if not minetest.find_node_near(lpos, 6, "group:tree") then + -- manually placed leaf nodes have param2 + -- set and will never decay automatically + if lnode.param2 == 0 then + minetest.swap_node(lpos, {name = lnode.name .. "_orphan"}) + end + end + end + end +end + -- Register tree trunk (wood) and bark local function register_tree_trunk(subname, description_trunk, description_bark, longdesc, tile_inner, tile_bark, stripped_variant) minetest.register_node("mcl_core:"..subname, { @@ -17,6 +51,7 @@ local function register_tree_trunk(subname, description_trunk, description_bark, tiles = {tile_inner, tile_inner, tile_bark}, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, + after_destruct = mcl_core.update_leaves, stack_max = 64, groups = {handy=1,axey=1, tree=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, sounds = mcl_sounds.node_sound_wood_defaults(), @@ -107,10 +142,7 @@ local function register_wooden_planks(subname, description, tiles) }) end -local function register_leaves(subname, description, longdesc, tiles, sapling, drop_apples, sapling_chances, leafdecay_distance) - if leafdecay_distance == nil then - leafdecay_distance = 4 - end +local function register_leaves(subname, description, longdesc, tiles, sapling, drop_apples, sapling_chances) local apple_chances = {200, 180, 160, 120, 40} local stick_chances = {50, 45, 30, 35, 10} @@ -141,7 +173,7 @@ local function register_leaves(subname, description, longdesc, tiles, sapling, d return drop end - minetest.register_node("mcl_core:"..subname, { + local l_def = { description = description, _doc_items_longdesc = longdesc, _doc_items_hidden = false, @@ -153,9 +185,8 @@ local function register_leaves(subname, description, longdesc, tiles, sapling, d stack_max = 64, groups = { 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 + leaves = 1, deco_block = 1, compostability = 30 }, drop = get_drops(0), _mcl_shears_drop = true, @@ -164,7 +195,19 @@ local function register_leaves(subname, description, longdesc, tiles, sapling, d _mcl_hardness = 0.2, _mcl_silk_touch_drop = true, _mcl_fortune_drop = { get_drops(1), get_drops(2), get_drops(3), get_drops(4) }, - }) + } + + minetest.register_node("mcl_core:" .. subname, l_def) + + local o_def = table.copy(l_def) + o_def._doc_items_create_entry = false + o_def.place_param2 = nil + o_def.groups.not_in_creative_inventory = 1 + o_def.groups.orphan_leaves = 1 + o_def._mcl_shears_drop = {"mcl_core:" .. subname} + o_def._mcl_silk_touch_drop = {"mcl_core:" .. subname} + + minetest.register_node("mcl_core:" .. subname .. "_orphan", o_def) end local function register_sapling(subname, description, longdesc, tt_help, texture, selbox) diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_birch_bee_nest.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_birch_bee_nest.mts new file mode 100644 index 000000000..fff8fddc4 Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_birch_bee_nest.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_bush_oak_leaves_2.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_bush_oak_leaves_2.mts new file mode 100644 index 000000000..55b8dca0f Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_bush_oak_leaves_2.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree.mts index c015d242d..44ac2b538 100644 Binary files a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree.mts and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_2.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_2.mts new file mode 100644 index 000000000..4564048d2 Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_2.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_3.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_3.mts new file mode 100644 index 000000000..c604a2d9c Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_3.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_4.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_4.mts new file mode 100644 index 000000000..7ce8af2fd Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_4.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_1.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_1.mts index ba4f9fa26..eefbeb4fe 100644 Binary files a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_1.mts and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_1.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_2.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_2.mts index df0114f6b..817ca023e 100644 Binary files a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_2.mts and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_2.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_3.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_3.mts new file mode 100644 index 000000000..c22f49334 Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_3.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_4.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_4.mts new file mode 100644 index 000000000..fa3d74567 Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_4.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_oak_classic_bee_nest.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_oak_classic_bee_nest.mts new file mode 100644 index 000000000..1f793f47c Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_oak_classic_bee_nest.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_oak_swamp.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_oak_swamp.mts index 3308dba4a..955f70eb5 100644 Binary files a/mods/ITEMS/mcl_core/schematics/mcl_core_oak_swamp.mts and b/mods/ITEMS/mcl_core/schematics/mcl_core_oak_swamp.mts differ diff --git a/mods/ITEMS/mcl_core/textures/default_dry_grass.png b/mods/ITEMS/mcl_core/textures/default_dry_grass.png deleted file mode 100644 index e610678a6..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_dry_grass.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_dry_grass_side.png b/mods/ITEMS/mcl_core/textures/default_dry_grass_side.png deleted file mode 100644 index b12d06e7b..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_dry_grass_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian.png b/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian.png new file mode 100644 index 000000000..6229fe08a Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear.png b/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear.png new file mode 100644 index 000000000..eb3fc2cb5 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear2.png b/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear2.png new file mode 100644 index 000000000..07d1978ba Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear2.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear3.png b/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear3.png new file mode 100644 index 000000000..ea0f58393 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_crying_obsidian_tear3.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_side.png index 0d89941ff..4f0bf5fe9 100644 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_side.png and b/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_side.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_grass_side_snowed.png b/mods/ITEMS/mcl_core/textures/mcl_core_grass_side_snowed.png index 9830db7eb..b38bf0e4f 100644 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_grass_side_snowed.png and b/mods/ITEMS/mcl_core/textures/mcl_core_grass_side_snowed.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_lapis.png b/mods/ITEMS/mcl_core/textures/mcl_core_lapis.png new file mode 100644 index 000000000..e0e302307 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_lapis.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_particle.png b/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_particle.png new file mode 100644 index 000000000..abf43e33a Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_particle.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_dirt_grass_shadow.png b/mods/ITEMS/mcl_core/textures/mcl_dirt_grass_shadow.png new file mode 100644 index 000000000..5a1fa6197 Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_dirt_grass_shadow.png differ diff --git a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ja.tr b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ja.tr new file mode 100644 index 000000000..03bd702b1 --- /dev/null +++ b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_crafting_table +Crafting Table=作業台 +A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts.=作業台とは、3×3のクラフトグリッドを提供し、高度なクラフトが行えるようになるブロックです。 +Rightclick the crafting table to access the 3×3 crafting grid.=作業台を右クリックすると、3×3のクラフトグリッドが表示されます。 +Recipe book=レシピ本 +Crafting=クラフト +Inventory=インベントリ +3×3 crafting grid=3×3のクラフトグリッド diff --git a/mods/ITEMS/mcl_crimson/init.lua b/mods/ITEMS/mcl_crimson/init.lua new file mode 100644 index 000000000..ba680cff5 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/init.lua @@ -0,0 +1,753 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +-- Warped and Crimson fungus +-- by debiankaios +-- adapted for mcl2 by cora + +local function generate_warped_tree(pos) + minetest.place_schematic(pos,modpath.."/schematics/warped_fungus_1.mts","random",nil,false,"place_center_x,place_center_z") +end + +function generate_crimson_tree(pos) + minetest.place_schematic(pos,modpath.."/schematics/crimson_fungus_1.mts","random",nil,false,"place_center_x,place_center_z") +end + +function grow_vines(pos, moreontop ,vine, dir) + if dir == nil then dir = 1 end + local n + repeat + pos = vector.offset(pos,0,dir,0) + n = minetest.get_node(pos) + if n.name == "air" then + for i=0,math.max(moreontop,1) do + if minetest.get_node(pos).name == "air" then + minetest.set_node(vector.offset(pos,0,i*dir,0),{name=vine}) + end + end + break + end + until n.name ~= "air" and n.name ~= vine +end + +local nether_plants = { + ["mcl_crimson:crimson_nylium"] = { + "mcl_crimson:crimson_roots", + "mcl_crimson:crimson_fungus", + "mcl_crimson:warped_fungus", + }, + ["mcl_crimson:warped_nylium"] = { + "mcl_crimson:warped_roots", + "mcl_crimson:warped_fungus", + "mcl_crimson:twisting_vines", + "mcl_crimson:nether_sprouts", + }, +} + +local function has_nylium_neighbor(pos) + local p = minetest.find_node_near(pos,1,{"mcl_crimson:warped_nylium","mcl_crimson:crimson_nylium"}) + if p then + return minetest.get_node(p) + end +end + +local function spread_nether_plants(pos,node) + local n = node.name + local nn = minetest.find_nodes_in_area_under_air(vector.offset(pos,-5,-3,-5),vector.offset(pos,5,3,5),{n}) + table.shuffle(nn) + nn[1] = pos + for i=1,math.random(1,math.min(#nn,12)) do + local p = vector.offset(nn[i],0,1,0) + if minetest.get_node(p).name == "air" then + minetest.set_node(p,{name=nether_plants[n][math.random(#nether_plants[n])]}) + mcl_dye.add_bone_meal_particle(vector.offset(nn[i],0,1,0)) + end + end +end + +minetest.register_node("mcl_crimson:warped_fungus", { + description = S("Warped Fungus Mushroom"), + drawtype = "plantlike", + tiles = { "farming_warped_fungus.png" }, + inventory_image = "farming_warped_fungus.png", + wield_image = "farming_warped_fungus.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + groups = {dig_immediate=3,mushroom=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,enderman_takable=1,deco_block=1}, + light_source = 1, + selection_box = { + type = "fixed", + fixed = { -3/16, -0.5, -3/16, 3/16, -2/16, 3/16 }, + }, + node_placement_prediction = "", + on_rightclick = function(pos, node, pointed_thing, player, itemstack) + if pointed_thing:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + local nodepos = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}) + if nodepos.name == "mcl_crimson:warped_nylium" or nodepos.name == "mcl_nether:netherrack" then + local random = math.random(1, 5) + if random == 1 then + minetest.remove_node(pos) + generate_warped_tree(pos) + end + end + end + end, + _mcl_blast_resistance = 0, +}) + +mcl_flowerpots.register_potted_flower("mcl_crimson:warped_fungus", { + name = "warped fungus", + desc = S("Warped Fungus Mushroom"), + image = "farming_warped_fungus.png", +}) + +minetest.register_node("mcl_crimson:twisting_vines", { + description = S("Twisting Vines"), + drawtype = "plantlike", + tiles = { "twisting_vines_plant.png" }, + inventory_image = "twisting_vines.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + climbable = true, + buildable_to = true, + groups = {dig_immediate=3,vines=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,deco_block=1, shearsy = 1}, + selection_box = { + type = "fixed", + fixed = { -3/16, -0.5, -3/16, 3/16, 0.5, 3/16 }, + }, + node_placement_prediction = "", + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local pn = clicker:get_player_name() + if clicker:is_player() and minetest.is_protected(vector.offset(pos,0,1,0), pn or "") then + minetest.record_protection_violation(vector.offset(pos,0,1,0), pn) + return itemstack + end + if clicker:get_wielded_item():get_name() == "mcl_crimson:twisting_vines" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + grow_vines(pos, 1, "mcl_crimson:twisting_vines") + elseif clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + grow_vines(pos, math.random(1, 3),"mcl_crimson:twisting_vines") + end + return itemstack + end, + drop = { + max_items = 1, + items = { + {items = {"mcl_crimson:twisting_vines"}, rarity = 3}, + }, + }, + _mcl_shears_drop = true, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + items = { + {items = {"mcl_crimson:twisting_vines"}, rarity = 3}, + }, + items = { + {items = {"mcl_crimson:twisting_vines"}, rarity = 1.8181818181818181}, + }, + "mcl_crimson:twisting_vines", + "mcl_crimson:twisting_vines", + }, + _mcl_blast_resistance = 0, +}) + +minetest.register_node("mcl_crimson:weeping_vines", { + description = S("Weeping Vines"), + drawtype = "plantlike", + tiles = { "mcl_crimson_weeping_vines.png" }, + inventory_image = "mcl_crimson_weeping_vines.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + climbable = true, + buildable_to = true, + groups = {dig_immediate=3,vines=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,deco_block=1, shearsy = 1}, + selection_box = { + type = "fixed", + fixed = { -3/16, -0.5, -3/16, 3/16, 0.5, 3/16 }, + }, + node_placement_prediction = "", + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local pn = clicker:get_player_name() + if clicker:is_player() and minetest.is_protected(vector.offset(pos,0,1,0), pn or "") then + minetest.record_protection_violation(vector.offset(pos,0,1,0), pn) + return itemstack + end + if clicker:get_wielded_item():get_name() == "mcl_crimson:weeping_vines" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + grow_vines(pos, 1, "mcl_crimson:weeping_vines", -1) + elseif clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + grow_vines(pos, math.random(1, 3),"mcl_crimson:weeping_vines", -1) + end + return itemstack + end, + drop = { + max_items = 1, + items = { + {items = {"mcl_crimson:weeping_vines"}, rarity = 3}, + }, + }, + _mcl_shears_drop = true, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + items = { + {items = {"mcl_crimson:weeping_vines"}, rarity = 3}, + }, + items = { + {items = {"mcl_crimson:weeping_vines"}, rarity = 1.8181818181818181}, + }, + "mcl_crimson:weeping_vines", + "mcl_crimson:weeping_vines", + }, + _mcl_blast_resistance = 0, +}) + +minetest.register_node("mcl_crimson:nether_sprouts", { + description = S("Nether Sprouts"), + drawtype = "plantlike", + tiles = { "nether_sprouts.png" }, + inventory_image = "nether_sprouts.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + groups = {dig_immediate=3,vines=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,deco_block=1, shearsy = 1}, + selection_box = { + type = "fixed", + fixed = { -4/16, -0.5, -4/16, 4/16, 0, 4/16 }, + }, + node_placement_prediction = "", + drop = "", + _mcl_shears_drop = true, + _mcl_silk_touch_drop = false, + _mcl_blast_resistance = 0, +}) + +minetest.register_node("mcl_crimson:warped_roots", { + description = S("Warped Roots"), + drawtype = "plantlike", + tiles = { "warped_roots.png" }, + inventory_image = "warped_roots.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + groups = {dig_immediate=3,vines=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,deco_block=1, shearsy = 1}, + selection_box = { + type = "fixed", + fixed = { -6/16, -0.5, -6/16, 6/16, -4/16, 6/16 }, + }, + node_placement_prediction = "", + _mcl_silk_touch_drop = false, + _mcl_blast_resistance = 0, +}) + +mcl_flowerpots.register_potted_flower("mcl_crimson:warped_roots", { + name = "warped roots", + desc = S("Warped Roots"), + image = "warped_roots.png", +}) + + +minetest.register_node("mcl_crimson:warped_wart_block", { + description = S("Warped Wart Block"), + tiles = {"warped_wart_block.png"}, + groups = {handy = 1, hoe = 7, swordy = 1, deco_block = 1}, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_crimson:shroomlight", { + description = S("Shroomlight"), + tiles = {"shroomlight.png"}, + groups = {handy = 1, hoe = 7, swordy = 1, deco_block = 1}, + light_source = minetest.LIGHT_MAX, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_crimson:warped_hyphae", { + description = S("Warped Hyphae"), + _doc_items_longdesc = S("The stem of a warped hyphae"), + _doc_items_hidden = false, + tiles = { + "warped_hyphae.png", + "warped_hyphae.png", + { + image="warped_hyphae_side.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + }, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, tree = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_crimson:stripped_warped_hyphae", +}) + +minetest.register_node("mcl_crimson:warped_nylium", { + description = S("Warped Nylium"), + tiles = { + "warped_nylium.png", + "mcl_nether_netherrack.png", + "mcl_nether_netherrack.png^warped_nylium_side.png", + "mcl_nether_netherrack.png^warped_nylium_side.png", + "mcl_nether_netherrack.png^warped_nylium_side.png", + "mcl_nether_netherrack.png^warped_nylium_side.png", + }, + is_ground_content = true, + drop = "mcl_nether:netherrack", + groups = {pickaxey=1, building_block=1, material_stone=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_hardness = 0.4, + _mcl_blast_resistance = 0.4, + _mcl_silk_touch_drop = true, +}) + +--Stem bark, stripped stem and bark + +minetest.register_node("mcl_crimson:warped_hyphae_bark", { + description = S("Warped Hyphae Bark"), + _doc_items_longdesc = S("This is a decorative block surrounded by the bark of an hyphae."), + tiles = { + { + image="warped_hyphae_side.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + }, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, bark = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_crimson:stripped_warped_hyphae_bark", +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_hyphae_bark 3", + recipe = { + { "mcl_crimson:warped_hyphae", "mcl_crimson:warped_hyphae" }, + { "mcl_crimson:warped_hyphae", "mcl_crimson:warped_hyphae" }, + }, +}) + +minetest.register_node("mcl_crimson:stripped_warped_hyphae", { + description = S("Stripped Warped Hyphae"), + _doc_items_longdesc = S("The stripped hyphae of a warped fungus"), + _doc_items_hidden = false, + tiles = {"warped_stem_stripped_top.png", "warped_stem_stripped_top.png", "warped_stem_stripped_side.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, tree = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_crimson:stripped_warped_hyphae_bark", { + description = S("Stripped Warped Hyphae Bark"), + _doc_items_longdesc = S("The stripped hyphae bark of a warped fungus"), + tiles = {"warped_stem_stripped_side.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, bark = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_craft({ + output = "mcl_crimson:stripped_warped_hyphae_bark 3", + recipe = { + { "mcl_crimson:stripped_warped_hyphae", "mcl_crimson:stripped_warped_hyphae" }, + { "mcl_crimson:stripped_warped_hyphae", "mcl_crimson:stripped_warped_hyphae" }, + }, +}) + +minetest.register_node("mcl_crimson:warped_hyphae_wood", { + description = S("Warped Hyphae Wood"), + tiles = {"warped_hyphae_wood.png"}, + groups = {handy = 5,axey = 1, flammable = 3, wood=1,building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_hardness = 2, +}) + +mcl_stairs.register_stair_and_slab_simple("warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", S("Warped Stair"), S("Warped Slab"), S("Double Warped Slab")) + +minetest.register_craft({ + output = "mcl_crimson:warped_hyphae_wood 4", + recipe = { + {"mcl_crimson:warped_hyphae"}, + }, +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_nylium 2", + recipe = { + {"mcl_crimson:warped_wart_block"}, + {"mcl_nether:netherrack"}, + }, +}) + +minetest.register_node("mcl_crimson:crimson_fungus", { + description = S("Crimson Fungus Mushroom"), + drawtype = "plantlike", + tiles = { "farming_crimson_fungus.png" }, + inventory_image = "farming_crimson_fungus.png", + wield_image = "farming_crimson_fungus.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + groups = {dig_immediate=3,mushroom=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,enderman_takable=1,deco_block=1}, + light_source = 1, + selection_box = { + type = "fixed", + fixed = { -3/16, -0.5, -3/16, 3/16, -2/16, 3/16 }, + }, + node_placement_prediction = "", + on_rightclick = function(pos, node, pointed_thing, player) + if pointed_thing:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + local nodepos = minetest.get_node(vector.offset(pos, 0, -1, 0)) + if nodepos.name == "mcl_crimson:crimson_nylium" or nodepos.name == "mcl_nether:netherrack" then + local random = math.random(1, 5) + if random == 1 then + minetest.remove_node(pos) + generate_crimson_tree(pos) + end + end + end + end, + _mcl_blast_resistance = 0, +}) + +mcl_flowerpots.register_potted_flower("mcl_crimson:crimson_fungus", { + name = "crimson fungus", + desc = S("Crimson Fungus Mushroom"), + image = "farming_crimson_fungus.png", +}) + +minetest.register_node("mcl_crimson:crimson_roots", { + description = S("Crimson Roots"), + drawtype = "plantlike", + tiles = { "crimson_roots.png" }, + inventory_image = "crimson_roots.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + groups = {dig_immediate=3,vines=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,deco_block=1, shearsy = 1}, + selection_box = { + type = "fixed", + fixed = { -6/16, -0.5, -6/16, 6/16, -4/16, 6/16 }, + }, + node_placement_prediction = "", + _mcl_silk_touch_drop = false, + _mcl_blast_resistance = 0, +}) + +mcl_flowerpots.register_potted_flower("mcl_crimson:crimson_roots", { + name = "crimson roots", + desc = S("Crimson Roots"), + image = "crimson_roots.png", +}) + +minetest.register_node("mcl_crimson:crimson_hyphae", { + description = S("Crimson Hyphae"), + _doc_items_longdesc = S("The stem of a crimson hyphae"), + _doc_items_hidden = false, + tiles = { + "crimson_hyphae.png", + "crimson_hyphae.png", + { + image="crimson_hyphae_side.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + }, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, tree = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_crimson:stripped_crimson_hyphae", +}) + +--Stem bark, stripped stem and bark + +minetest.register_node("mcl_crimson:crimson_hyphae_bark", { + description = S("Crimson Hyphae Bark"), + _doc_items_longdesc = S("This is a decorative block surrounded by the bark of an hyphae."), + tiles = { + { + image="crimson_hyphae_side.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + }, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, bark = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_crimson:stripped_crimson_hyphae_bark", +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_hyphae_bark 3", + recipe = { + { "mcl_crimson:crimson_hyphae", "mcl_crimson:crimson_hyphae" }, + { "mcl_crimson:crimson_hyphae", "mcl_crimson:crimson_hyphae" }, + }, +}) + +minetest.register_node("mcl_crimson:stripped_crimson_hyphae", { + description = S("Stripped Crimson Hyphae"), + _doc_items_longdesc = S("The stripped stem of a crimson hyphae"), + _doc_items_hidden = false, + tiles = {"crimson_stem_stripped_top.png", "crimson_stem_stripped_top.png", "crimson_stem_stripped_side.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, tree = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_crimson:stripped_crimson_hyphae_bark", { + description = S("Stripped Crimson Hyphae Bark"), + _doc_items_longdesc = S("The stripped wood of a crimson hyphae"), + tiles = {"crimson_stem_stripped_side.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, bark = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_craft({ + output = "mcl_crimson:stripped_crimson_hyphae_bark 3", + recipe = { + { "mcl_crimson:stripped_crimson_hyphae", "mcl_crimson:stripped_crimson_hyphae" }, + { "mcl_crimson:stripped_crimson_hyphae", "mcl_crimson:stripped_crimson_hyphae" }, + }, +}) + +minetest.register_node("mcl_crimson:crimson_hyphae_wood", { + description = S("Crimson Hyphae Wood"), + tiles = {"crimson_hyphae_wood.png"}, + groups = {handy = 5, axey = 1, wood = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_crimson:crimson_nylium", { + description = S("Crimson Nylium"), + tiles = { + "crimson_nylium.png", + "mcl_nether_netherrack.png", + "mcl_nether_netherrack.png^crimson_nylium_side.png", + "mcl_nether_netherrack.png^crimson_nylium_side.png", + "mcl_nether_netherrack.png^crimson_nylium_side.png", + "mcl_nether_netherrack.png^crimson_nylium_side.png", + }, + groups = {pickaxey = 1, building_block = 1, material_stone = 1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = true, + drop = "mcl_nether:netherrack", + _mcl_hardness = 0.4, + _mcl_blast_resistance = 0.4, + _mcl_silk_touch_drop = true, +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_hyphae_wood 4", + recipe = { + {"mcl_crimson:crimson_hyphae"}, + }, +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_nylium 2", + recipe = { + {"mcl_nether:nether_wart"}, + {"mcl_nether:netherrack"}, + }, +}) + +mcl_stairs.register_stair_and_slab_simple("crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", S("Crimson Stair"), S("Crimson Slab"), S("Double Crimson Slab")) + +mcl_dye.register_on_bone_meal_apply(function(pt,user) + if not pt.type == "node" then return end + local node = minetest.get_node(pt.under) + if node.name == "mcl_nether:netherrack" then + local n = has_nylium_neighbor(pt.under) + if n then + minetest.set_node(pt.under,n) + end + elseif node.name == "mcl_crimson:warped_nylium" or node.name == "mcl_crimson:crimson_nylium" then + spread_nether_plants(pt.under,node) + end +end) + +mcl_doors:register_door("mcl_crimson:crimson_door", { + description = S("Crimson Door"), + _doc_items_longdesc = S("Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal."), + _doc_items_usagehelp = S("To open or close a wooden door, rightclick it or supply its lower half with a redstone signal."), + inventory_image = "mcl_crimson_crimson_door.png", + groups = {handy=1,axey=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = {"mcl_crimson_crimson_door_bottom.png", "mcl_doors_door_crimson_side_lower.png"}, + tiles_top = {"mcl_crimson_crimson_door_top.png", "mcl_doors_door_crimson_side_upper.png"}, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_doors:register_trapdoor("mcl_crimson:crimson_trapdoor", { + description = S("Crimson Trapdoor"), + _doc_items_longdesc = S("Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder."), + _doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."), + tile_front = "mcl_crimson_crimson_trapdoor.png", + tile_side = "crimson_hyphae_wood.png", + wield_image = "mcl_crimson_crimson_trapdoor.png", + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_fences.register_fence_and_fence_gate( + "crimson_fence", + S("Crimson Fence"), + S("Crimson Fence Gate"), + "mcl_crimson_crimson_fence.png", + {handy=1,axey=1, flammable=2,fence_wood=1, fire_encouragement=5, fire_flammability=20}, + minetest.registered_nodes["mcl_crimson:crimson_hyphae"]._mcl_hardness, + minetest.registered_nodes["mcl_crimson:crimson_hyphae"]._mcl_blast_resistance, + {"group:fence_wood"}, + mcl_sounds.node_sound_wood_defaults()) + + +mcl_doors:register_door("mcl_crimson:warped_door", { + description = S("Warped Door"), + _doc_items_longdesc = S("Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal."), + _doc_items_usagehelp = S("To open or close a wooden door, rightclick it or supply its lower half with a redstone signal."), + inventory_image = "mcl_crimson_warped_door.png", + groups = {handy=1,axey=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = {"mcl_crimson_warped_door_bottom.png", "mcl_doors_door_warped_side_lower.png"}, + tiles_top = {"mcl_crimson_warped_door_top.png", "mcl_doors_door_warped_side_upper.png"}, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_doors:register_trapdoor("mcl_crimson:warped_trapdoor", { + description = S("Warped Trapdoor"), + _doc_items_longdesc = S("Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder."), + _doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."), + tile_front = "mcl_crimson_warped_trapdoor.png", + tile_side = "warped_hyphae_wood.png", + wield_image = "mcl_crimson_warped_trapdoor.png", + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_fences.register_fence_and_fence_gate( + "warped_fence", + S("Warped Fence"), + S("Warped Fence Gate"), + "mcl_crimson_warped_fence.png", + {handy=1,axey=1, flammable=2,fence_wood=1, fire_encouragement=5, fire_flammability=20}, + minetest.registered_nodes["mcl_crimson:warped_hyphae"]._mcl_hardness, + minetest.registered_nodes["mcl_crimson:warped_hyphae"]._mcl_blast_resistance, + {"group:fence_wood"}, + mcl_sounds.node_sound_wood_defaults()) + +-- Door, Trapdoor, and Fence/Gate Crafting +local crimson_wood = "mcl_crimson:crimson_hyphae_wood" +local warped_wood = "mcl_crimson:warped_hyphae_wood" + +minetest.register_craft({ + output = "mcl_crimson:crimson_door 3", + recipe = { + {crimson_wood, crimson_wood}, + {crimson_wood, crimson_wood}, + {crimson_wood, crimson_wood} + } +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_door 3", + recipe = { + {warped_wood, warped_wood}, + {warped_wood, warped_wood}, + {warped_wood, warped_wood} + } +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_trapdoor 2", + recipe = { + {crimson_wood, crimson_wood, crimson_wood}, + {crimson_wood, crimson_wood, crimson_wood}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_trapdoor 2", + recipe = { + {warped_wood, warped_wood, warped_wood}, + {warped_wood, warped_wood, warped_wood}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_fence 3", + recipe = { + {crimson_wood, "mcl_core:stick", crimson_wood}, + {crimson_wood, "mcl_core:stick", crimson_wood}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_fence 3", + recipe = { + {warped_wood, "mcl_core:stick", warped_wood}, + {warped_wood, "mcl_core:stick", warped_wood}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_fence_gate", + recipe = { + {"mcl_core:stick", crimson_wood, "mcl_core:stick"}, + {"mcl_core:stick", crimson_wood, "mcl_core:stick"}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_fence_gate", + recipe = { + {"mcl_core:stick", warped_wood, "mcl_core:stick"}, + {"mcl_core:stick", warped_wood, "mcl_core:stick"}, + } +}) diff --git a/mods/ITEMS/mcl_crimson/locale/mcl_crimson.de.tr b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.de.tr new file mode 100644 index 000000000..480094dbd --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.de.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_crimson + +Warped Fungus Mushroom=Wirrpilz +Twisting Vines=Zwirbelranken +Nether Sprouts=Nethersprossen +Warped Roots=Wirrwurzeln +Warped Wart Block=Wirrwarzenblock +Shroomlight=Pilzlicht +Warped Hyphae=Wirrhyphe +Warped Nylium=Wirr-Nezel +Warped Checknode - only to check!=Wirr Checkblock - Nur zum checken! +Warped Hyphae Wood=Wirrhyphen Holz +Warped Stair=Wirrtreppe +Warped Slab=Wirrstufe +Double Warped Slab=Doppelte Wirrstufe +Crimson Fungus Mushroom=Karmesinpilz +Crimson Roots=Karmesinwurzeln +Crimson Hyphae=Karmesinhyphe +Crimson Hyphae Wood=Karmesinhyphenholz +Crimson Stair=Karmesintreppe +Crimson Slab=Karmesinstufe +Double Crimson Slab=Doppelte Karmesinstufe +Crimson Nylium=Karmesin-Nezel +Crimson Checknode - only to check!=Karmesin Checkblock - Nur zum checken! diff --git a/mods/ITEMS/mcl_crimson/locale/mcl_crimson.fr.tr b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.fr.tr new file mode 100644 index 000000000..8ebdb6720 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.fr.tr @@ -0,0 +1,29 @@ +# textdomain: mcl_crimson + +Warped Fungus Mushroom=Champignon tordu +Twisting Vines=Liane tordue +Nether Sprouts=Racines du nether +Warped Roots=Racines tordues +Warped Wart Block=Bloc de verrues tordu +Shroomlight=Champilampe +Warped Hyphae=Tige tordue +Warped Hyphae Bark=Hyphe tordue +Stripped warped hyphae=Tige tordue dénudée +Stripped warped hyphae bark=Hyphe tordue dénudée +Warped Nylium=Nylium tordu +Warped Checknode - only to check!=Bloc de vérification tordu - seulement pour vérifier ! +Warped Hyphae Wood=Planches tordues +Warped Stair=Escalier tordu +Warped Slab=Dalle tordue +Crimson Fungus Mushroom=Champignon écarlate +Crimson Roots=Racines écarlates +Crimson Hyphae=Tige écarlate +Crimson Hyphae Bark=Hyphe écarlate +Stripped Crimson Hyphae=Tige écarlate dénudée +Stripped Crimson Hyphae Bark=Hyphe écarlate dénudée +Crimson Hyphae Wood=Planches écarlates +Crimson Stair=Escalier écarlate +Crimson Slab=Dalle écarlate +Double Crimson Slab=Dalle double écarlate +Crimson Nylium=Nylium écarlate +Crimson Checknode - only to check!=Bloc de vérification écarlate - seulement pour vérifier ! \ No newline at end of file diff --git a/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ja.tr b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ja.tr new file mode 100644 index 000000000..47251fd27 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ja.tr @@ -0,0 +1,29 @@ +# textdomain: mcl_crimson + +Warped Fungus Mushroom=歪なキノコ +Twisting Vines=ねじれツタ +Nether Sprouts=ネザースプラウト +Warped Roots=歪な根 +Warped Wart Block=歪なウォートブロック +Shroomlight=シュルームライト +Warped Hyphae=歪な菌糸 +Warped Hyphae Bark=歪な菌糸の表皮 +Stripped warped hyphae=表皮を剥いだ歪な菌糸 +Stripped warped hyphae bark=剥がされた歪な菌糸の表皮 +Warped Nylium=歪なナイリウム +Warped Checknode - only to check!=歪なチェックノード - チェックのみ! +Warped Hyphae Wood=歪な菌糸の樹 +Warped Stair=歪な階段 +Warped Slab=歪なスラブ +Crimson Fungus Mushroom=真紅のキノコ +Crimson Roots=真紅の根 +Crimson Hyphae=真紅の菌糸 +Crimson Hyphae Bark=真紅の菌糸の表皮 +Stripped Crimson Hyphae=表皮を剥いだ真紅の菌糸 +Stripped Crimson Hyphae Bark=剥がされた真紅の菌糸の表皮 +Crimson Hyphae Wood=真紅の菌糸の樹 +Crimson Stair=真紅の階段 +Crimson Slab=真紅のスラブ +Double Crimson Slab=真紅の2重スラブ +Crimson Nylium=真紅のナイリウム +Crimson Checknode - only to check!=真紅のチェックノード - チェックのみ! diff --git a/mods/ITEMS/mcl_crimson/locale/template.txt b/mods/ITEMS/mcl_crimson/locale/template.txt new file mode 100644 index 000000000..022a9a6dc --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/template.txt @@ -0,0 +1,29 @@ +# textdomain: mcl_crimson + +Warped Fungus Mushroom= +Twisting Vines= +Nether Sprouts= +Warped Roots= +Warped Wart Block= +Shroomlight= +Warped Hyphae= +Warped Hyphae Bark= +Stripped warped hyphae= +Stripped warped hyphae bark= +Warped Nylium= +Warped Checknode - only to check!= +Warped Hyphae Wood= +Warped Stair= +Warped Slab= +Crimson Fungus Mushroom= +Crimson Roots= +Crimson Hyphae= +Crimson Hyphae Bark= +Stripped Crimson Hyphae= +Stripped Crimson Hyphae Bark= +Crimson Hyphae Wood= +Crimson Stair= +Crimson Slab= +Double Crimson Slab= +Crimson Nylium= +Crimson Checknode - only to check!= diff --git a/mods/ITEMS/mcl_crimson/mod.conf b/mods/ITEMS/mcl_crimson/mod.conf new file mode 100644 index 000000000..89c60cd1e --- /dev/null +++ b/mods/ITEMS/mcl_crimson/mod.conf @@ -0,0 +1,3 @@ +name = mcl_crimson +author = debiankaios +depends = mcl_core, mcl_stairs, mobs_mc, mcl_util, mcl_dye, mcl_flowerpots diff --git a/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_1.mts b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_1.mts new file mode 100644 index 000000000..a61712fef Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_1.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_2.mts b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_2.mts new file mode 100644 index 000000000..b509fae50 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_2.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_3.mts b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_3.mts new file mode 100644 index 000000000..84f8fa791 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_3.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/warped_fungus_1.mts b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_1.mts new file mode 100644 index 000000000..487e39f1a Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_1.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/warped_fungus_2.mts b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_2.mts new file mode 100644 index 000000000..564731158 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_2.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/warped_fungus_3.mts b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_3.mts new file mode 100644 index 000000000..079631a20 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_3.mts differ diff --git a/mods/ITEMS/mcl_crimson/textures/crimson_hyphae.png b/mods/ITEMS/mcl_crimson/textures/crimson_hyphae.png new file mode 100644 index 000000000..5df05e3ae Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/crimson_hyphae.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/crimson_hyphae_side.png b/mods/ITEMS/mcl_crimson/textures/crimson_hyphae_side.png new file mode 100644 index 000000000..a1d5302c7 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/crimson_hyphae_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/crimson_hyphae_wood.png b/mods/ITEMS/mcl_crimson/textures/crimson_hyphae_wood.png new file mode 100644 index 000000000..0f91c9681 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/crimson_hyphae_wood.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/crimson_nylium.png b/mods/ITEMS/mcl_crimson/textures/crimson_nylium.png new file mode 100644 index 000000000..faa3ba973 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/crimson_nylium.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/crimson_nylium_side.png b/mods/ITEMS/mcl_crimson/textures/crimson_nylium_side.png new file mode 100644 index 000000000..def8c73d4 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/crimson_nylium_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/crimson_roots.png b/mods/ITEMS/mcl_crimson/textures/crimson_roots.png new file mode 100644 index 000000000..19d648058 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/crimson_roots.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/crimson_stem_stripped_side.png b/mods/ITEMS/mcl_crimson/textures/crimson_stem_stripped_side.png new file mode 100644 index 000000000..1f9ca2dda Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/crimson_stem_stripped_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/crimson_stem_stripped_top.png b/mods/ITEMS/mcl_crimson/textures/crimson_stem_stripped_top.png new file mode 100644 index 000000000..03d9c17b9 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/crimson_stem_stripped_top.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/farming_crimson_fungus.png b/mods/ITEMS/mcl_crimson/textures/farming_crimson_fungus.png new file mode 100644 index 000000000..7a547ca79 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/farming_crimson_fungus.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/farming_warped_fungus.png b/mods/ITEMS/mcl_crimson/textures/farming_warped_fungus.png new file mode 100644 index 000000000..4ac08fad6 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/farming_warped_fungus.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door.png new file mode 100644 index 000000000..dc325a00f Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door_bottom.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door_bottom.png new file mode 100644 index 000000000..8da6915f2 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door_bottom.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door_top.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door_top.png new file mode 100644 index 000000000..c55f28ec7 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_door_top.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence.png new file mode 100644 index 000000000..df71d56a9 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence_side.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence_side.png new file mode 100644 index 000000000..4941ce6d4 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence_top.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence_top.png new file mode 100644 index 000000000..485633b75 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_fence_top.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_trapdoor.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_trapdoor.png new file mode 100644 index 000000000..615b6b4b6 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_crimson_trapdoor.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door.png new file mode 100644 index 000000000..66639b4c2 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_alt.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_alt.png new file mode 100644 index 000000000..f946e6f94 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_alt.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_bottom.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_bottom.png new file mode 100644 index 000000000..942eff928 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_bottom.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_bottom_alt.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_bottom_alt.png new file mode 100644 index 000000000..2da69c716 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_bottom_alt.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_top.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_top.png new file mode 100644 index 000000000..9ad9e2c60 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_top.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_top_alt.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_top_alt.png new file mode 100644 index 000000000..9f922ee4e Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_door_top_alt.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence.png new file mode 100644 index 000000000..7e25c14c0 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence_side.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence_side.png new file mode 100644 index 000000000..61eda6d7c Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence_top.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence_top.png new file mode 100644 index 000000000..d5ce4b2b3 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_fence_top.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_trapdoor.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_trapdoor.png new file mode 100644 index 000000000..efbae0711 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_trapdoor.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_trapdoor_alt.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_trapdoor_alt.png new file mode 100644 index 000000000..12d972971 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_warped_trapdoor_alt.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_crimson_weeping_vines.png b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_weeping_vines.png new file mode 100644 index 000000000..701688073 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_crimson_weeping_vines.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_crimson_side_lower.png b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_crimson_side_lower.png new file mode 100644 index 000000000..b7a6a8777 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_crimson_side_lower.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_crimson_side_upper.png b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_crimson_side_upper.png new file mode 100644 index 000000000..bb042109b Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_crimson_side_upper.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_lower.png b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_lower.png new file mode 100644 index 000000000..b93dc629e Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_lower.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_lower_alt.png b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_lower_alt.png new file mode 100644 index 000000000..7ba0bcff6 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_lower_alt.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_upper.png b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_upper.png new file mode 100644 index 000000000..e0bfa8581 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_upper.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_upper_alt.png b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_upper_alt.png new file mode 100644 index 000000000..e70bfb055 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/mcl_doors_door_warped_side_upper_alt.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/nether_sprouts.png b/mods/ITEMS/mcl_crimson/textures/nether_sprouts.png new file mode 100644 index 000000000..469c9db69 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/nether_sprouts.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/nether_wart_block.png b/mods/ITEMS/mcl_crimson/textures/nether_wart_block.png new file mode 100644 index 000000000..b9c4e447e Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/nether_wart_block.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/shroomlight.png b/mods/ITEMS/mcl_crimson/textures/shroomlight.png new file mode 100644 index 000000000..a7ce84e48 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/shroomlight.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem.png b/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem.png new file mode 100644 index 000000000..1f9ca2dda Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem_side.png b/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem_side.png new file mode 100644 index 000000000..1f9ca2dda Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem_top.png b/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem_top.png new file mode 100644 index 000000000..71c6f501d Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/stripped_crimson_stem_top.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem.png b/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem.png new file mode 100644 index 000000000..c5cd37b46 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem_side.png b/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem_side.png new file mode 100644 index 000000000..17e98fa6c Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem_top.png b/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem_top.png new file mode 100644 index 000000000..868b0d8a8 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/stripped_warped_stem_top.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/twisting_vines.png b/mods/ITEMS/mcl_crimson/textures/twisting_vines.png new file mode 100644 index 000000000..2837496db Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/twisting_vines.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/twisting_vines_plant.png b/mods/ITEMS/mcl_crimson/textures/twisting_vines_plant.png new file mode 100644 index 000000000..690098adf Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/twisting_vines_plant.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_hyphae.png b/mods/ITEMS/mcl_crimson/textures/warped_hyphae.png new file mode 100644 index 000000000..163d7dcf0 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_hyphae.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_hyphae_side.png b/mods/ITEMS/mcl_crimson/textures/warped_hyphae_side.png new file mode 100644 index 000000000..225198756 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_hyphae_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_hyphae_wood.png b/mods/ITEMS/mcl_crimson/textures/warped_hyphae_wood.png new file mode 100644 index 000000000..f25d2ad98 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_hyphae_wood.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_hyphae_wood_2nd.png b/mods/ITEMS/mcl_crimson/textures/warped_hyphae_wood_2nd.png new file mode 100644 index 000000000..9adca3dd0 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_hyphae_wood_2nd.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_nylium.png b/mods/ITEMS/mcl_crimson/textures/warped_nylium.png new file mode 100644 index 000000000..a9b65768f Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_nylium.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_nylium_side.png b/mods/ITEMS/mcl_crimson/textures/warped_nylium_side.png new file mode 100644 index 000000000..26b10cf0f Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_nylium_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_roots.png b/mods/ITEMS/mcl_crimson/textures/warped_roots.png new file mode 100644 index 000000000..97f1e1ec5 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_roots.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_stem_stripped_side.png b/mods/ITEMS/mcl_crimson/textures/warped_stem_stripped_side.png new file mode 100644 index 000000000..17e98fa6c Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_stem_stripped_side.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_stem_stripped_top.png b/mods/ITEMS/mcl_crimson/textures/warped_stem_stripped_top.png new file mode 100644 index 000000000..fc722556b Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_stem_stripped_top.png differ diff --git a/mods/ITEMS/mcl_crimson/textures/warped_wart_block.png b/mods/ITEMS/mcl_crimson/textures/warped_wart_block.png new file mode 100644 index 000000000..236f26ea6 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/textures/warped_wart_block.png differ diff --git a/mods/ITEMS/mcl_deepslate/init.lua b/mods/ITEMS/mcl_deepslate/init.lua index 6b03358e2..a1182246a 100644 --- a/mods/ITEMS/mcl_deepslate/init.lua +++ b/mods/ITEMS/mcl_deepslate/init.lua @@ -1,21 +1,15 @@ local modname = minetest.get_current_modname() local S = minetest.get_translator(modname) ---local layer_max = mcl_worlds.layer_to_y(16) ---local layer_min = mcl_vars.mg_overworld_min - local copper_mod = minetest.get_modpath("mcl_copper") - local cobble = "mcl_deepslate:deepslate_cobbled" local stick = "mcl_core:stick" ---[[ -local mountains = { - "ExtremeHills", "ExtremeHills_beach", "ExtremeHills_ocean", "ExtremeHills_deep_ocean", "ExtremeHills_underground", - "ExtremeHills+", "ExtremeHills+_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills+_underground", - "ExtremeHillsM", "ExtremeHillsM_ocean", "ExtremeHillsM_deep_ocean", "ExtremeHillsM_underground", -} -]] +local function spawn_silverfish(pos, oldnode, oldmetadata, digger) + if not minetest.is_creative_enabled("") then + minetest.add_entity(pos, "mobs_mc:silverfish") + end +end minetest.register_node("mcl_deepslate:deepslate", { description = S("Deepslate"), @@ -34,12 +28,6 @@ minetest.register_node("mcl_deepslate:deepslate", { _mcl_silk_touch_drop = true, }) -local function spawn_silverfish(pos, oldnode, oldmetadata, digger) - if not minetest.is_creative_enabled("") then - minetest.add_entity(pos, "mobs_mc:silverfish") - end -end - minetest.register_node("mcl_deepslate:infested_deepslate", { description = S("Infested Deepslate"), _doc_items_longdesc = S("An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart."), @@ -101,11 +89,11 @@ end local lapis_drops = { max_items = 1, items = { - { items = { "mcl_dye:blue 8" }, rarity = 5 }, - { items = { "mcl_dye:blue 7" }, rarity = 5 }, - { items = { "mcl_dye:blue 6" }, rarity = 5 }, - { items = { "mcl_dye:blue 5" }, rarity = 5 }, - { items = { "mcl_dye:blue 4" } } + { items = { "mcl_core:lapis 8" }, rarity = 5 }, + { items = { "mcl_core:lapis 7" }, rarity = 5 }, + { items = { "mcl_core:lapis 6" }, rarity = 5 }, + { items = { "mcl_core:lapis 5" }, rarity = 5 }, + { items = { "mcl_core:lapis 4" } } } } @@ -115,7 +103,7 @@ local deepslate_ores = { { "Gold", "mcl_raw_ores:raw_gold", "mcl_core:gold_ingot", 4, 0 }, { "Emerald", "mcl_core:emerald", "mcl_core:emerald", 4, 6 }, { "Diamond", "mcl_core:diamond", "mcl_core:diamond", 4, 4 }, - { "Lapis Lazuli", lapis_drops, "mcl_dye:blue", 3, 6 }, + { "Lapis Lazuli", lapis_drops, "mcl_core:lapis", 3, 6 }, } for _, p in pairs(deepslate_ores) do @@ -128,15 +116,21 @@ end local redstone_timer = 68.28 -local function redstone_ore_activate(pos) +local function redstone_ore_activate(pos, node, puncher, pointed_thing) minetest.swap_node(pos, { name = "mcl_deepslate:deepslate_with_redstone_lit" }) local t = minetest.get_node_timer(pos) t:start(redstone_timer) + if puncher and pointed_thing then + return minetest.node_punch(pos, node, puncher, pointed_thing) + end end -local function redstone_ore_reactivate(pos) +local function redstone_ore_reactivate(pos, node, puncher, pointed_thing) local t = minetest.get_node_timer(pos) t:start(redstone_timer) + if puncher and pointed_thing then + return minetest.node_punch(pos, node, puncher, pointed_thing) + end end minetest.register_node("mcl_deepslate:deepslate_with_redstone", { @@ -198,173 +192,6 @@ minetest.register_node("mcl_deepslate:deepslate_with_redstone_lit", { }, }) -minetest.register_craft({ - type = "cooking", - output = "mesecons:redstone", - recipe = "mcl_deepslate:deepslate_with_redstone", - cooktime = 10, -}) - ---[[ Commented out for now because there the discussion how to handle this is ongoing -minetest.register_ore({ - ore_type = "blob", - ore = "mcl_deepslate:deepslate", - wherein = { "mcl_core:stone" }, - clust_scarcity = 200, - clust_num_ores = 100, - clust_size = 10, - y_min = layer_min, - y_max = layer_max, - noise_params = { - offset = 0, - scale = 1, - spread = { x = 250, y = 250, z = 250 }, - seed = 12345, - octaves = 3, - persist = 0.6, - lacunarity = 2, - flags = "defaults", - } -}) - -minetest.register_ore({ - ore_type = "blob", - ore = "mcl_deepslate:tuff", - wherein = { "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_deepslate:deepslate" }, - clust_scarcity = 10*10*10, - clust_num_ores = 58, - clust_size = 7, - y_min = layer_min, - y_max = layer_max, - noise_params = { - offset = 0, - scale = 1, - spread = {x=250, y=250, z=250}, - seed = 12345, - octaves = 3, - persist = 0.6, - lacunarity = 2, - flags = "defaults", - } -}) - -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_deepslate:infested_deepslate", - wherein = "mcl_deepslate:deepslate", - clust_scarcity = 26 * 26 * 26, - clust_num_ores = 3, - clust_size = 2, - y_min = layer_min, - y_max = layer_max, - biomes = mountains, -}) - -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:water_source", - wherein = "mcl_deepslate:deepslate", - clust_scarcity = 9000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(5), - y_max = layer_max, -}) - -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = "mcl_deepslate:deepslate", - clust_scarcity = 2000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(1), - y_max = mcl_worlds.layer_to_y(10), -}) - -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = "mcl_deepslate:deepslate", - clust_scarcity = 9000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(11), - y_max = layer_max, -}) - - -if minetest.settings:get_bool("mcl_generate_ores", true) then - local stonelike = { "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" } - local function register_ore_mg(ore, scarcity, num, size, y_min, y_max, biomes) - biomes = biomes or "" - minetest.register_ore({ - ore_type = "scatter", - ore = ore, - wherein = { "mcl_deepslate:deepslate", "mcl_deepslate:tuff" }, - clust_scarcity = scarcity, - clust_num_ores = num, - clust_size = size, - y_min = y_min, - y_max = y_max, - biomes = biomes, - }) - end - local ore_mapgen = { - { "coal", 1575, 5, 3, layer_min, layer_max }, - { "coal", 1530, 8, 3, layer_min, layer_max }, - { "coal", 1500, 12, 3, layer_min, layer_max }, - { "iron", 830, 5, 3, layer_min, layer_max }, - { "gold", 4775, 5, 3, layer_min, layer_max }, - { "gold", 6560, 7, 3, layer_min, layer_max }, - { "diamond", 10000, 4, 3, layer_min, mcl_worlds.layer_to_y(12) }, - { "diamond", 5000, 2, 3, layer_min, mcl_worlds.layer_to_y(12) }, - { "diamond", 10000, 8, 3, layer_min, mcl_worlds.layer_to_y(12) }, - { "diamond", 20000, 1, 1, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, - { "diamond", 20000, 2, 2, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, - { "redstone", 500, 4, 3, layer_min, mcl_worlds.layer_to_y(13) }, - { "redstone", 800, 7, 4, layer_min, mcl_worlds.layer_to_y(13) }, - { "redstone", 1000, 4, 3, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, - { "redstone", 1600, 7, 4, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, - { "lapis", 10000, 7, 4, mcl_worlds.layer_to_y(14), layer_max }, - { "lapis", 12000, 6, 3, mcl_worlds.layer_to_y(10), mcl_worlds.layer_to_y(13) }, - { "lapis", 14000, 5, 3, mcl_worlds.layer_to_y(6), mcl_worlds.layer_to_y(9) }, - { "lapis", 16000, 4, 3, mcl_worlds.layer_to_y(2), mcl_worlds.layer_to_y(5) }, - { "lapis", 18000, 3, 2, mcl_worlds.layer_to_y(0), mcl_worlds.layer_to_y(2) }, - } - for _, o in pairs(ore_mapgen) do - register_ore_mg("mcl_deepslate:deepslate_with_"..o[1], o[2], o[3], o[4], o[5], o[6]) - end - if minetest.get_mapgen_setting("mg_name") == "v6" then - register_ore_mg("mcl_deepslate:deepslate_with_emerald", 14340, 1, 1, layer_min, layer_max) - else - register_ore_mg("mcl_deepslate:deepslate_with_emerald", 16384, 1, 1, mcl_worlds.layer_to_y(4), layer_max, mountains) - end - if copper_mod then - register_ore_mg("mcl_deepslate:deepslate_with_copper", 830, 5, 3, layer_min, layer_max) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_copper:stone_with_copper", - wherein = stonelike, - clust_scarcity = 830, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(39), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_copper:stone_with_copper", - wherein = stonelike, - clust_scarcity = 1660, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(40), - y_max = mcl_worlds.layer_to_y(63), - }) - end -end ---]] local function register_deepslate_variant(item, desc, longdesc) local texture = desc:lower():gsub("% ", "_") local def = { @@ -424,6 +251,13 @@ for _, p in pairs({ "bricks", "tiles" }) do }) end +minetest.register_craft({ + type = "cooking", + output = "mesecons:redstone", + recipe = "mcl_deepslate:deepslate_with_redstone", + cooktime = 10, +}) + minetest.register_craft({ type = "cooking", output = "mcl_deepslate:deepslate", diff --git a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr new file mode 100644 index 000000000..d79146701 --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr @@ -0,0 +1,53 @@ +# textdomain: mcl_deepslate +An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart.=Un bloc infesté est un bloc dont va sortir un poisson d'argent lorsqu'il sera cassé. Il a la même apparence que son équivalent normal. +Chiseled deepslate is the chiseled version of deepslate.=l'ardoise des abîmes sculptée est la version sculptée de l'ardoise des abîmes. +Chiseled Deepslate=Ardoise des abîmes sculptée +Cobbled deepslate is a stone variant that functions similar to cobblestone or blackstone.=La pierre des abîmes est une variante de roche similaire à la pierre ou la pierre noire. +Cobbled Deepslate Slab=Dalle de pierre des abîmes +Cobbled Deepslate Stairs=Escalier de pierre des abîmes +Cobbled Deepslate Wall=Muret de pierre des abîmes +Cobbled Deepslate=Pierre des abîmes +Cracked Deepslate Bricks=Ardoise des abîmes taillée craquelée +Cracked Deepslate Tiles=Ardoise des abîmes carrelée craquelée +Deepslate bricks are the brick version of deepslate.=L'ardoise des abîmes taillée est la version brique de l'ardoise des abîmes. +Deepslate Bricks Slab=Dalle d'ardoise des abîmes taillée +Deepslate Bricks Stairs=Escalier d'ardoise des abîmes taillée +Deepslate Bricks Wall=Muret d'ardoise des abîmes taillée +Deepslate Bricks=Ardoise des abîmes taillée +Deepslate coal ore is a variant of coal ore that can generate in deepslate and tuff blobs.=Le minerai de charbon de l'ardoise des abîmes est une variante de minerai de charbon qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Coal Ore=Minerai de charbon de l'ardoise des abîmes +Deepslate copper ore is a variant of copper ore that can generate in deepslate and tuff blobs.=Le minerai de cuivre de l'ardoise des abîmes est une variante de minerai de cuivre qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Copper Ore=Minerai de cuivre de l'ardoise des abîmes +Deepslate diamond ore is a variant of diamond ore that can generate in deepslate and tuff blobs.=Le minerai de diamand de l'ardoise des abîmes est une variante de minerai de diamand qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Diamond Ore=Minerai de diamand de l'ardoise des abîmes +Deepslate emerald ore is a variant of emerald ore that can generate in deepslate and tuff blobs.=Le minerai d'émeraude de l'ardoise des abîmes est une variante de minerai d'émeraude qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Emerald Ore=Minerai d'émeraude de l'ardoise des abîmes +Deepslate gold ore is a variant of gold ore that can generate in deepslate and tuff blobs.=Le minerai d'or de l'ardoise des abîmes est une variante de minerai d'or qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Gold Ore=Minerai d'or de l'ardoise des abîmes +Deepslate iron ore is a variant of iron ore that can generate in deepslate and tuff blobs.=Le minerai de fer de l'ardoise des abîmes est une variante de minerai de fer qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Iron Ore=Minerai de fer de l'ardoise des abîmes +Deepslate is a stone type found deep underground in the Overworld that functions similar to regular stone but is harder than the stone.=L'ardoise des abîmes est un type de roche présente dans les profondeurs de l'Overworld qui fonctionne de manière similaire à la roche classique mais en plus dur. +Deepslate Lapis Lazuli Ore=Minerai de lapis-lazuli de l'ardoise des abîmes +Deepslate lapis ore is a variant of lapis ore that can generate in deepslate and tuff blobs.=Le minerai de lapis de l'ardoise des abîmes est une variante de minerai de lapis-lazuli qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate redstone ore is a variant of redstone ore that can generate in deepslate and tuff blobs.=Le minerai de redstone de l'ardoise des abîmes est une variante de minerai de redstone qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Redstone Ore=Minerai de Redstone de l'ardoise des abîmes +Deepslate tiles are a decorative variant of deepslate.=L'ardoise des abîmes carrelée est une variante décorative de l'ardoise des abîmes. +Deepslate Tiles Slab=Dalle d'ardoise des abîmes carrelée +Deepslate Tiles Stairs=Escalier d'ardoise des abîmes carrelée +Deepslate Tiles Wall=Muret d'ardoise des abîmes carrelée +Deepslate Tiles=Ardoise des abîmes carrelée +Deepslate=Ardoise des abîmes +Double Cobbled Deepslate Slab=Dalle double de pierre des abîmes +Double Deepslate Bricks Slab=Dalle double d'ardoise des abîmes taillée +Double Deepslate Tiles Slab=Dalle double d'ardoise des abîmes carrelée +Double Polished Deepslate Slab=Dalle double d'ardoise des abîmes polie +Hides a silverfish=Cache un poisson d'argent +Infested Deepslate=Ardoise des abîmes infestée +Lit Deepslate Redstone Ore=Minerai de Redstone de l'ardoise des abîmes éclairé +Polished deepslate is the stone-like polished version of deepslate.=l'ardoise des abîmes polie est la version polie de l'ardoise des abîmes, de manière similaire à la pierre. +Polished Deepslate Slab=Dalle d'ardoise des abîmes +Polished Deepslate Stairs=Escalier d'ardoise des abîmes +Polished Deepslate Wall=Muret d'ardoise des abîmes +Polished Deepslate=Ardoise des abîmes polie +Tuff=Tuf +Tuff is an ornamental rock formed from volcanic ash, occurring in underground blobs below Y=16.=Le tuf est une roche ornementale formée de roche volcanique, apparraissant dans des blobs souterrains sous Y=16. diff --git a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ja.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ja.tr new file mode 100644 index 000000000..bbd25ee5c --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ja.tr @@ -0,0 +1,53 @@ +# textdomain: mcl_deepslate +An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart.=虫喰いブロックは、壊すとシルバーフィッシュが飛び出してくるブロックです。見た目は通常のブロックと同じです。 +Chiseled deepslate is the chiseled version of deepslate.=模様入り深層岩は、深層岩の模様入りバージョンです。 +Chiseled Deepslate=模様入り深層岩 +Cobbled deepslate is a stone variant that functions similar to cobblestone or blackstone.=深層岩の丸石は、丸石やブラックストーンと同様の機能を持つ石の変種です。 +Cobbled Deepslate Slab=深層岩の丸石のスラブ +Cobbled Deepslate Stairs=深層岩の丸石の階段 +Cobbled Deepslate Wall=深層岩の丸石の塀 +Cobbled Deepslate=深層岩の丸石 +Cracked Deepslate Bricks=ひび割れた深層岩レンガ +Cracked Deepslate Tiles=ひび割れた深層岩タイル +Deepslate bricks are the brick version of deepslate.=深層岩レンガは、深層岩のレンガバージョンです。 +Deepslate Bricks Slab=深層岩レンガのスラブ +Deepslate Bricks Stairs=深層岩レンガの階段 +Deepslate Bricks Wall=深層岩レンガの塀 +Deepslate Bricks=深層岩レンガ +Deepslate coal ore is a variant of coal ore that can generate in deepslate and tuff blobs.=深層石炭鉱石は、深層岩や凝灰岩にひとかたまりで生成される、石炭鉱石の変種です。 +Deepslate Coal Ore=深層石炭鉱石 +Deepslate copper ore is a variant of copper ore that can generate in deepslate and tuff blobs.=深層石炭鉱石は、深層岩や凝灰岩にひとかたまりで生成される、石炭鉱石の変種です。 +Deepslate Copper Ore=深層銅鉱石 +Deepslate diamond ore is a variant of diamond ore that can generate in deepslate and tuff blobs.=深層銅鉱石は、深層岩や凝灰岩にひとかたまりで生成される、銅鉱石の変種です。 +Deepslate Diamond Ore=深層ダイヤモンド鉱石 +Deepslate emerald ore is a variant of emerald ore that can generate in deepslate and tuff blobs.=深層ダイヤモンド鉱石は、深層岩や凝灰岩にひとかたまりで生成される、ダイヤモンド鉱石の変種です。 +Deepslate Emerald Ore=深層エメラルド鉱石 +Deepslate gold ore is a variant of gold ore that can generate in deepslate and tuff blobs.=深層エメラルド鉱石は、深層岩や凝灰岩にひとかたまりで生成される、エメラルド鉱石の変種です。 +Deepslate Gold Ore=深層金鉱石 +Deepslate iron ore is a variant of iron ore that can generate in deepslate and tuff blobs.=深層金鉱石は、深層岩や凝灰岩にひとかたまりで生成される、金鉱石の変種です。 +Deepslate Iron Ore=深層鉄鉱石 +Deepslate is a stone type found deep underground in the Overworld that functions similar to regular stone but is harder than the stone.=深層岩は、オーバーワールドの地中深くで見られる石種で、機能的には通常の石と同様ながら、石よりも硬いのが特徴です。 +Deepslate Lapis Lazuli Ore=深層ラピスラズリ鉱石 +Deepslate lapis ore is a variant of lapis ore that can generate in deepslate and tuff blobs.=深層ラピスラズリ鉱石は、深層岩や凝灰岩にひとかたまりで生成される、ラピスラズリ鉱石の変種です。 +Deepslate redstone ore is a variant of redstone ore that can generate in deepslate and tuff blobs.=深層レッドストーン鉱石は、深層岩や凝灰岩にひとかたまりで生成される、レッドストーン鉱石の変種です。 +Deepslate Redstone Ore=深層レッドストーン鉱石 +Deepslate tiles are a decorative variant of deepslate.=深層岩タイルは、深層岩の装飾バージョンです。 +Deepslate Tiles Slab=深層岩タイルのスラブ +Deepslate Tiles Stairs=深層岩タイルの階段 +Deepslate Tiles Wall=深層岩タイルの塀 +Deepslate Tiles=深層岩タイル +Deepslate=深層岩 +Double Cobbled Deepslate Slab=深層岩の丸石の2重スラブ +Double Deepslate Bricks Slab=深層岩レンガの2重スラブ +Double Deepslate Tiles Slab=深層岩タイルの2重スラブ +Double Polished Deepslate Slab=磨かれた深層岩の2重スラブ +Hides a silverfish=シルバーフィッシュが潜む +Infested Deepslate=虫喰い深層岩 +Lit Deepslate Redstone Ore=発光した深層レッドストーン鉱石 +Polished deepslate is the stone-like polished version of deepslate.=磨かれた深層岩は、深層岩を石のように磨いたバージョンです。 +Polished Deepslate Slab=磨かれた深層岩のスラブ +Polished Deepslate Stairs=磨かれた深層岩の階段 +Polished Deepslate Wall=磨かれた深層岩の塀 +Polished Deepslate=磨かれた深層岩 +Tuff=凝灰岩 +Tuff is an ornamental rock formed from volcanic ash, occurring in underground blobs below Y=16.=凝灰岩とは、火山灰から形成される装飾用の岩石で、Y=16以下の深部にかたまって分布しています。 diff --git a/mods/ITEMS/mcl_doors/api_doors.lua b/mods/ITEMS/mcl_doors/api_doors.lua index c2fc7c377..e6eef4e0d 100644 --- a/mods/ITEMS/mcl_doors/api_doors.lua +++ b/mods/ITEMS/mcl_doors/api_doors.lua @@ -155,10 +155,17 @@ function mcl_doors:register_door(name, def) end local left_node = minetest.get_node(pt_left) + local mirrored = false + local door_dir = 1 + if left_node.name:sub(1, #name) == name then + mirrored = true + door_dir = 2 + p2 = left_node.param2 + end -- Set door nodes - minetest.set_node(pt, {name=name.."_b_1", param2=p2}) - minetest.set_node(pt2, {name=name.."_t_1", param2=p2}) + minetest.set_node(pt, {name=name.."_b_"..door_dir, param2=p2}) + minetest.set_node(pt2, {name=name.."_t_"..door_dir, param2=p2}) if def.sounds and def.sounds.place then minetest.sound_play(def.sounds.place, {pos=pt}, true) @@ -174,7 +181,7 @@ function mcl_doors:register_door(name, def) local meta1 = minetest_get_meta(pt) local meta2 = minetest_get_meta(pt2) -- save mirror state for the correct door - if left_node.name:sub(1, #name) == name then + if mirrored then meta1:set_int("is_mirrored", 1) meta2:set_int("is_mirrored", 1) end diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.ja.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.ja.tr new file mode 100644 index 000000000..3dbdb7e5d --- /dev/null +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.ja.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_doors +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=木製のドアは高さ2ブロックの遮蔽物で、手とレッドストーン信号で開閉できます。 +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=木製のドアを開閉するには右クリックするか、下半分にレッドストーン信号を供給してください。 +Oak Door=オークのドア +Acacia Door=アカシアのドア +Birch Door=シラカバのドア +Dark Oak Door=ダークオークのドア +Jungle Door=ジャングルのドア +Spruce Door=トウヒのドア +Iron Door=鉄のドア +Iron doors are 2-block high barriers which can only be opened or closed by a redstone signal, but not by hand.=鉄のドアは高さ2ブロックの遮蔽物で、レッドストーン信号によってのみ開閉でき、手では開けられません。 +To open or close an iron door, supply its lower half with a redstone signal.=鉄のドアを開閉するには、その下半分にレッドストーン信号を供給します。 +Oak Trapdoor=オークのトラップドア +Acacia Trapdoor=アカシアのトラップドア +Birch Trapdoor=シラカバのトラップドア +Spruce Trapdoor=トウヒのトラップドア +Dark Oak Trapdoor=ダークオークのトラップドア +Jungle Trapdoor=ジャングルのトラップドア +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=木製のトラップドアは、手やレッドストーン信号で開閉できる水平の遮蔽物です。配置の仕方によって、ブロックの上部または下部を占めます。開いているときは、ハシゴのように登れます。 +To open or close the trapdoor, rightclick it or send a redstone signal to it.=トラップドアを開閉するには、それを右クリックするか、それにレッドストーン信号を送信してください。 +Iron Trapdoor=鉄のトラップドア +Iron trapdoors are horizontal barriers which can only be opened and closed by redstone signals, but not by hand. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=鉄のトラップドアは、レッドストーン信号によってのみ開閉でき、手では開けられません。配置の仕方によって、ブロックの上部または下部を占めます。開いているときは、ハシゴのようによじ登れます。 +Openable by players and redstone power=プレイヤーとレッドストーン動力によって開閉可能 +Openable by redstone power=レッドストーン動力によって開閉可能 diff --git a/mods/ITEMS/mcl_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index 727a78460..16672b554 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -18,10 +18,6 @@ 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"} -mcl_dye.excolors = {"white", "lightgrey", "grey", "darkgrey", "black", "red", "orange", "yellow", "lime", "green", "aqua", "cyan", "sky_blue", "blue", "violet", "magenta", "red_violet"} - -- Base color groups: -- - basecolor_white -- - basecolor_grey @@ -62,43 +58,43 @@ mcl_dye.excolors = {"white", "lightgrey", "grey", "darkgrey", "black", "red", "o -- - unicolor_medium__s50 -- - unicolor_dark__s50 --- Local stuff -local dyelocal = {} - -- This collection of colors is partly a historic thing, partly something else. -dyelocal.dyes = { - {"white", "mcl_dye_white", S("Bone Meal"), {dye=1, craftitem=1, basecolor_white=1, excolor_white=1, unicolor_white=1}}, - {"grey", "dye_grey", S("Light Grey Dye"), {dye=1, craftitem=1, basecolor_grey=1, excolor_grey=1, unicolor_grey=1}}, - {"dark_grey", "dye_dark_grey", S("Grey Dye"), {dye=1, craftitem=1, basecolor_grey=1, excolor_darkgrey=1, unicolor_darkgrey=1}}, - {"black", "mcl_dye_black", S("Ink Sac"), {dye=1, craftitem=1, basecolor_black=1, excolor_black=1, unicolor_black=1}}, - {"violet", "dye_violet", S("Purple Dye"), {dye=1, craftitem=1, basecolor_magenta=1, excolor_violet=1, unicolor_violet=1}}, - {"blue", "mcl_dye_blue", S("Lapis Lazuli"), {dye=1, craftitem=1, basecolor_blue=1, excolor_blue=1, unicolor_blue=1}}, - {"lightblue", "mcl_dye_light_blue", S("Light Blue Dye"), {dye=1, craftitem=1, basecolor_blue=1, excolor_blue=1, unicolor_light_blue=1}}, - {"cyan", "dye_cyan", S("Cyan Dye"), {dye=1, craftitem=1, basecolor_cyan=1, excolor_cyan=1, unicolor_cyan=1}}, - {"dark_green", "dye_dark_green", S("Cactus Green"),{dye=1, craftitem=1, basecolor_green=1, excolor_green=1, unicolor_dark_green=1}}, - {"green", "mcl_dye_lime", S("Lime Dye"), {dye=1, craftitem=1, basecolor_green=1, excolor_green=1, unicolor_green=1}}, - {"yellow", "dye_yellow", S("Dandelion Yellow"), {dye=1, craftitem=1, basecolor_yellow=1, excolor_yellow=1, unicolor_yellow=1}}, - {"brown", "mcl_dye_brown", S("Cocoa Beans"), {dye=1, craftitem=1, basecolor_brown=1, excolor_orange=1, unicolor_dark_orange=1, 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}}, - {"pink", "dye_pink", S("Pink Dye"), {dye=1, craftitem=1, basecolor_red=1, excolor_red=1, unicolor_light_red=1}}, +local dyes = { + {"white", S("White Dye"), {basecolor_white=1, excolor_white=1, unicolor_white=1}}, + {"grey", S("Light Grey Dye"), {basecolor_grey=1, excolor_grey=1, unicolor_grey=1}}, + {"dark_grey", S("Grey Dye"), {basecolor_grey=1, excolor_darkgrey=1, unicolor_darkgrey=1}}, + {"black", S("Black Dye"), {basecolor_black=1, excolor_black=1, unicolor_black=1}}, + {"violet", S("Purple Dye"), {basecolor_magenta=1, excolor_violet=1, unicolor_violet=1}}, + {"blue", S("Blue Dye"), {basecolor_blue=1, excolor_blue=1, unicolor_blue=1}}, + {"lightblue", S("Light Blue Dye"), {basecolor_blue=1, excolor_blue=1, unicolor_light_blue=1}}, + {"cyan", S("Cyan Dye"), {basecolor_cyan=1, excolor_cyan=1, unicolor_cyan=1}}, + {"dark_green", S("Cactus Green"), {basecolor_green=1, excolor_green=1, unicolor_dark_green=1}}, + {"green", S("Lime Dye"), {basecolor_green=1, excolor_green=1, unicolor_green=1}}, + {"yellow", S("Dandelion Yellow"), {basecolor_yellow=1, excolor_yellow=1, unicolor_yellow=1}}, + {"brown", S("Brown Dye"), {basecolor_brown=1, excolor_orange=1, unicolor_dark_orange=1}}, + {"orange", S("Orange Dye"), {basecolor_orange=1, excolor_orange=1, unicolor_orange=1}}, + {"red", S("Rose Red"), {basecolor_red=1, excolor_red=1, unicolor_red=1}}, + {"magenta", S("Magenta Dye"), {basecolor_magenta=1, excolor_red_violet=1,unicolor_red_violet=1}}, + {"pink", S("Pink Dye"), {basecolor_red=1, excolor_red=1, unicolor_light_red=1}}, } -local mg_name = minetest.get_mapgen_setting("mg_name") +-- Other mods can use these for looping through available colors +mcl_dye.basecolors = {"white", "grey", "black", "magenta", "blue", "cyan", "green", "yellow", "orange", "red", "brown"} +mcl_dye.excolors = {"white", "grey", "darkgrey", "black", "violet", "blue", "cyan", "green", "yellow", "orange", "red", "red_violet"} -dyelocal.unicolor_to_dye_id = {} -for d=1, #dyelocal.dyes do - for k, _ in pairs(dyelocal.dyes[d][4]) do +local unicolor_to_dye_id = {} +for d = 1, #dyes do + for k, _ in pairs(dyes[d][3]) do if string.sub(k, 1, 9) == "unicolor_" then - dyelocal.unicolor_to_dye_id[k] = dyelocal.dyes[d][1] + unicolor_to_dye_id[k] = dyes[d][1] end end end --- Takes an unicolor group name (e.g. “unicolor_white”) and returns a corresponding dye name (if it exists), nil otherwise. +-- Takes an unicolor group name (e.g. “unicolor_white”) and returns a +-- corresponding dye name (if it exists), nil otherwise. function mcl_dye.unicolor_to_dye(unicolor_group) - local color = dyelocal.unicolor_to_dye_id[unicolor_group] + local color = unicolor_to_dye_id[unicolor_group] if color then return "mcl_dye:" .. color else @@ -106,28 +102,21 @@ function mcl_dye.unicolor_to_dye(unicolor_group) end end --- Define items -for _, row in ipairs(dyelocal.dyes) do - local name = row[1] - -- White and brown dyes are defined explicitly below - if name ~= "white" and name ~= "brown" then - local img = row[2] - local description = row[3] - local groups = row[4] - local item_name = "mcl_dye:"..name - local item_image = img..".png" - minetest.register_craftitem(item_name, { - inventory_image = item_image, - description = description, - _doc_items_longdesc = S("This item is a dye which is used for dyeing and crafting."), - _doc_items_usagehelp = S("Rightclick on a sheep to dye its wool. Other things are dyed by crafting."), - groups = groups, - stack_max = 64, - }) - end +-- Define dye items. +-- +for _, row in pairs(dyes) do + local name, desc, grps = unpack(row) + minetest.register_craftitem("mcl_dye:" .. name, { + inventory_image = "mcl_dye_" .. name .. ".png", + description = desc, + _doc_items_longdesc = S("This item is a dye which is used for dyeing and crafting."), + _doc_items_usagehelp = S("Rightclick on a sheep to dye its wool. Other things are dyed by crafting."), + groups = table.update({craftitem = 1, dye = 1}, grps) + }) end --- Bone Meal +-- Bone meal code to be moved into its own mod. +-- function mcl_dye.add_bone_meal_particle(pos, def) if not def then def = {} @@ -156,7 +145,7 @@ 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) +local function apply_bone_meal(pointed_thing,user) -- Bone meal currently spawns all flowers found in the plains. local flowers_table_plains = { "mcl_flowers:dandelion", @@ -281,6 +270,13 @@ local function apply_bone_meal(pointed_thing) if math.random(1, 100) <= 75 then return mcl_farming:grow_plant("plant_beetroot", pos, n, 1, true) end + elseif string.find(n.name, "mcl_farming:sweet_berry_bush_") then + mcl_dye.add_bone_meal_particle(pos) + if n.name == "mcl_farming:sweet_berry_bush_3" then + return minetest.add_item(vector.offset(pos,math.random()-0.5,math.random()-0.5,math.random()-0.5),"mcl_farming:sweet_berry") + else + return mcl_farming:grow_plant("plant_sweet_berry_bush", pos, n, 0, true) + end elseif n.name == "mcl_cocoas:cocoa_1" or n.name == "mcl_cocoas:cocoa_2" then mcl_dye.add_bone_meal_particle(pos) -- Cocoa: Advance by 1 stage @@ -372,14 +368,19 @@ local function apply_bone_meal(pointed_thing) return false end -minetest.register_craftitem("mcl_dye:white", { - inventory_image = "mcl_dye_white.png", +mcl_dye.apply_bone_meal = apply_bone_meal + +-- Bone meal item registration. +-- +-- To be moved into its own mod. +-- +minetest.register_craftitem(":mcl_bone_meal:bone_meal", { + inventory_image = "mcl_bone_meal_bone_meal.png", description = S("Bone Meal"), _tt_help = S("Speeds up plant growth"), _doc_items_longdesc = S("Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants."), _doc_items_usagehelp = S("Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place."), stack_max = 64, - groups = dyelocal.dyes[1][4], on_place = function(itemstack, user, pointed_thing) -- Use pointed node's on_rightclick function first, if present local node = minetest.get_node(pointed_thing.under) @@ -412,55 +413,160 @@ minetest.register_craftitem("mcl_dye:white", { _dispense_into_walkable = true }) -minetest.register_craftitem("mcl_dye:brown", { - inventory_image = "mcl_dye_brown.png", - _tt_help = S("Grows at the side of jungle trees"), - _doc_items_longdesc = S("Cocoa beans are a brown dye and can be used to plant cocoas."), - _doc_items_usagehelp = S("Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa."), - description = S("Cocoa Beans"), - stack_max = 64, - groups = dyelocal.dyes[12][4], - on_place = function(itemstack, placer, pointed_thing) - return mcl_cocoas.place(itemstack, placer, pointed_thing, "mcl_cocoas:cocoa_1") - end, +minetest.register_craft({ + output = "mcl_bone_meal:bone_meal 3", + recipe = {{"mcl_mobitems:bone"}}, }) --- Dye mixing + +-- Dye creation recipes. +-- +minetest.register_craft({ + output = "mcl_dye:white", + recipe = {{"mcl_bone_meal:bone_meal"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:black", + recipe = {{"mcl_mobitems:ink_sac"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:yellow", + recipe = {{"mcl_flowers:dandelion"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:yellow 2", + recipe = {{"mcl_flowers:sunflower"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:blue", + recipe = {{"mcl_core:lapis"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:lightblue", + recipe = {{"mcl_flowers:blue_orchid"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:grey", + recipe = {{"mcl_flowers:azure_bluet"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:grey", + recipe = {{"mcl_flowers:oxeye_daisy"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:grey", + recipe = {{"mcl_flowers:tulip_white"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:magenta", + recipe = {{"mcl_flowers:allium"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:magenta 2", + recipe = {{"mcl_flowers:lilac"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:orange", + recipe = {{"mcl_flowers:tulip_orange"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:brown", + recipe = {{"mcl_cocoas:cocoa_beans"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:pink", + recipe = {{"mcl_flowers:tulip_pink"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:pink 2", + recipe = {{"mcl_flowers:peony"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:red", + recipe = {{"mcl_farming:beetroot_item"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:red", + recipe = {{"mcl_flowers:poppy"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:red", + recipe = {{"mcl_flowers:tulip_red"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:red 2", + recipe = {{"mcl_flowers:rose_bush"}}, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_dye:dark_green", + recipe = "mcl_core:cactus", + cooktime = 10, +}) + +-- Dye mixing recipes. +-- minetest.register_craft({ type = "shapeless", output = "mcl_dye:dark_grey 2", recipe = {"mcl_dye:black", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:lightblue 2", recipe = {"mcl_dye:blue", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:grey 3", recipe = {"mcl_dye:black", "mcl_dye:white", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:grey 2", recipe = {"mcl_dye:dark_grey", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:green 2", recipe = {"mcl_dye:dark_green", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:magenta 4", recipe = {"mcl_dye:blue", "mcl_dye:white", "mcl_dye:red", "mcl_dye:red"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:magenta 3", recipe = {"mcl_dye:pink", "mcl_dye:red", "mcl_dye:blue"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:magenta 2", @@ -484,80 +590,34 @@ minetest.register_craft({ output = "mcl_dye:violet 2", recipe = {"mcl_dye:blue", "mcl_dye:red"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:orange 2", recipe = {"mcl_dye:yellow", "mcl_dye:red"}, }) --- Dye creation +-- Legacy items grace conversion recipes. +-- +-- These allow for retrieval of precious items that were converted into +-- dye items after refactoring of the dyes. Should be removed again in +-- the near future. minetest.register_craft({ - output = "mcl_dye:yellow", - recipe = {{"mcl_flowers:dandelion"}}, + output = "mcl_bone_meal:bone_meal", + recipe = {{"mcl_dye:white"}}, }) + minetest.register_craft({ - output = "mcl_dye:yellow 2", - recipe = {{"mcl_flowers:sunflower"}}, + output = "mcl_mobitems:ink_sac", + recipe = {{"mcl_dye:black"}}, }) + minetest.register_craft({ - output = "mcl_dye:lightblue", - recipe = {{"mcl_flowers:blue_orchid"}}, + output = "mcl_core:lapis", + recipe = {{"mcl_dye:blue"}}, }) + minetest.register_craft({ - output = "mcl_dye:grey", - recipe = {{"mcl_flowers:azure_bluet"}}, -}) -minetest.register_craft({ - output = "mcl_dye:grey", - recipe = {{"mcl_flowers:oxeye_daisy"}}, -}) -minetest.register_craft({ - output = "mcl_dye:grey", - recipe = {{"mcl_flowers:tulip_white"}}, -}) -minetest.register_craft({ - output = "mcl_dye:magenta", - recipe = {{"mcl_flowers:allium"}}, -}) -minetest.register_craft({ - output = "mcl_dye:magenta 2", - recipe = {{"mcl_flowers:lilac"}}, -}) -minetest.register_craft({ - output = "mcl_dye:orange", - recipe = {{"mcl_flowers:tulip_orange"}}, -}) -minetest.register_craft({ - output = "mcl_dye:pink", - recipe = {{"mcl_flowers:tulip_pink"}}, -}) -minetest.register_craft({ - output = "mcl_dye:pink 2", - recipe = {{"mcl_flowers:peony"}}, -}) -minetest.register_craft({ - output = "mcl_dye:red", - recipe = {{"mcl_farming:beetroot_item"}}, -}) -minetest.register_craft({ - output = "mcl_dye:red", - recipe = {{"mcl_flowers:poppy"}}, -}) -minetest.register_craft({ - output = "mcl_dye:red", - recipe = {{"mcl_flowers:tulip_red"}}, -}) -minetest.register_craft({ - output = "mcl_dye:red 2", - recipe = {{"mcl_flowers:rose_bush"}}, -}) -minetest.register_craft({ - type = "cooking", - output = "mcl_dye:dark_green", - recipe = "mcl_core:cactus", - cooktime = 10, -}) -minetest.register_craft({ - output = "mcl_dye:white 3", - recipe = {{"mcl_mobitems:bone"}}, + output = "mcl_cocoas:cocoa_beans", + recipe = {{"mcl_dye:brown"}}, }) diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.de.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.de.tr index 29cd4d20d..ca56dff22 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.de.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.de.tr @@ -1,16 +1,16 @@ # textdomain: mcl_dye -Bone Meal=Knochenmehl +White Dye=Weißer Farbstoff Light Grey Dye=Hellgrauer Farbstoff Grey Dye=Grauer Farbstoff -Ink Sac=Tintenbeutel +Black Dye=Schwarzer Farbstoff Purple Dye=Violetter Farbstoff -Lapis Lazuli=Lapislazuli +Blue Dye=Blaue Farbstoff Light Blue Dye=Hellblauer Farbstoff Cyan Dye=Türkiser Farbstoff Cactus Green=Kaktusgrün Lime Dye=Lindgrüner Farbstoff Dandelion Yellow=Löwenzahngelb -Cocoa Beans=Kakaobohnen +Brown Dye=Brauner Farbstoff Orange Dye=Orange Farbstoff Rose Red=Rosenrot Magenta Dye=Magenta Farbstoff diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.es.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.es.tr index d20e8c96a..14c2c12d1 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.es.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.es.tr @@ -1,16 +1,16 @@ # textdomain: mcl_dye -Bone Meal=Harina de hueso +White Dye=Tinte blanca Light Grey Dye=Tinte gris claro Grey Dye=Tinte gris -Ink Sac=Saco de tinta +Black Dye=Tinte negro Purple Dye=Tinte púrpura -Lapis Lazuli=Lapislázuli +Blue Dye=Tinte azul Light Blue Dye=Tinte azul claro Cyan Dye=Tinte cian Cactus Green=Tinte verde Lime Dye=Tinte amarillo verdoso Dandelion Yellow=Tinte amarillo -Cocoa Beans=Granos de cacao +Brown Dye=Tinte marrón Orange Dye=Tinte naranja Rose Red=Tinte rojo Magenta Dye=Tinte magenta diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.fr.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.fr.tr index 8d53cc73e..9418225d6 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.fr.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.fr.tr @@ -1,18 +1,18 @@ # textdomain: mcl_dye -Bone Meal=Poudre d'Os +White Dye=Teinture Blanche Light Grey Dye=Teinture Gris Clair Grey Dye=Teinture Gris -Ink Sac=Poche d'Encre +Black Dye=Teinture Noire Purple Dye=Teinture Violette -Lapis Lazuli=Lapis Lazuli +Blue Dye=Teinture Bleu Light Blue Dye=Teinture Bleu Clair Cyan Dye=Teinture Cyan Cactus Green=Cactus Vert Lime Dye=Teinture Vert Clair -Dandelion Yellow=Pissenlit Jaune -Cocoa Beans=Fèves de Cacao +Dandelion Yellow=Teinture Jaune +Brown Dye=Teinture Marron Orange Dye=Teinture Orange -Rose Red=Rose Rouge +Rose Red=Teinture Rouge Magenta Dye=Teinture Magenta Pink Dye=Teinture Rose This item is a dye which is used for dyeing and crafting.=Cet objet est un colorant utilisé pour la teinture et l'artisanat. diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.ja.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.ja.tr new file mode 100644 index 000000000..1dcd820db --- /dev/null +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.ja.tr @@ -0,0 +1,27 @@ +# textdomain: mcl_dye +Bone Meal=骨粉 +Light Grey Dye=薄灰色の染料 +Grey Dye=灰色の染料 +Ink Sac=イカスミ +Purple Dye=紫色の染料 +Lapis Lazuli=ラピスラズリ +Light Blue Dye=空色の染料 +Cyan Dye=青緑色の染料 +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=骨粉 +Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=骨粉は白色の染料であり、また多くの植物の成長を早める肥料としても有用です。 +Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=ヒツジを右クリックすると、羊毛が白くなります。植物を右クリックすると、成長が早くなります。ただし、すべての植物の肥やしになるわけではありません。草原を右クリックすると、背の高い草や花が一面に生えてきます。 +Cocoa beans are a brown dye and can be used to plant cocoas.=カカオ豆は茶色の染料で、カカオを栽培できます。 +Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=ヒツジを右クリックすると毛が茶色に変わります。ジャングルの木の、幹の側面を右クリックすると、カカオの苗を植えることができます。 +Cocoa Beans=カカオ豆 +Grows at the side of jungle trees=ジャングルの木の側面に生育 +Speeds up plant growth=植物の生育を促進 diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr index d16edb5b0..e9d8e4173 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr @@ -1,16 +1,16 @@ # textdomain: mcl_dye -Bone Meal=Mączka kostna +White Dye=Biały farba Light Grey Dye=Jasnoszara farba Grey Dye=Szara farba -Ink Sac=Torbiel z atramentem +Black Dye=Czarny farba Purple Dye=Fioletowa farba -Lapis Lazuli=Lazuryt +Blue Dye=Niebieska farba 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 +Brown Dye=Brązowy farba Orange Dye=Pomarańczowa farba Rose Red=Różany czerwony Magenta Dye=Karmazynowa farba diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr index e70388115..4e7903132 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr @@ -1,16 +1,16 @@ # textdomain: mcl_dye -Bone Meal=Костная мука +White Dye=Белый краситель Light Grey Dye=Светло-серый краситель Grey Dye=Серый краситель -Ink Sac=Чернильный мешок +Black Dye=Чёрный краситель Purple Dye=Пурпурный краситель -Lapis Lazuli=Ляпис-лазурь +Blue Dye=голубой краситель Light Blue Dye=Светло-голубой краситель Cyan Dye=Голубой краситель Cactus Green=Зелень кактуса Lime Dye=Зелёный лаймовый краситель Dandelion Yellow=Одуванчиковый жёлтый краситель -Cocoa Beans=Какао-бобы +Brown Dye=Коричневый краситель Orange Dye=Оранжевый краситель Rose Red=Экстракт красной розы Magenta Dye=Фиолетовый краситель diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr index 23d2face2..5e236e9dd 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr @@ -1,16 +1,16 @@ # textdomain: mcl_dye -Bone Meal=骨粉 +White Dye=白色染料 Light Grey Dye=淺灰色染料 Grey Dye=灰色染料 -Ink Sac=墨囊 +Black Dye=黑色染料 Purple Dye=紫色染料 -Lapis Lazuli=青金石 +Blue Dye=藍色染料 Light Blue Dye=淺藍色染料 Cyan Dye=青色染料 Cactus Green=仙人掌綠 Lime Dye=淺綠色染料 Dandelion Yellow=蒲公英黃 -Cocoa Beans=可可豆 +Brown Dye=棕色染料 Orange Dye=橙色染料 Rose Red=玫瑰紅 Magenta Dye=洋紅色染料 diff --git a/mods/ITEMS/mcl_dye/locale/template.txt b/mods/ITEMS/mcl_dye/locale/template.txt index 94e250f06..a40b0859a 100644 --- a/mods/ITEMS/mcl_dye/locale/template.txt +++ b/mods/ITEMS/mcl_dye/locale/template.txt @@ -1,16 +1,16 @@ # textdomain: mcl_dye -Bone Meal= +White Dye= Light Grey Dye= Grey Dye= -Ink Sac= +Black Dye= Purple Dye= -Lapis Lazuli= +Blue Dye= Light Blue Dye= Cyan Dye= Cactus Green= Lime Dye= Dandelion Yellow= -Cocoa Beans= +Brown Dye= Orange Dye= Rose Red= Magenta Dye= diff --git a/mods/ITEMS/mcl_dye/textures/mcl_bone_meal_bone_meal.png b/mods/ITEMS/mcl_dye/textures/mcl_bone_meal_bone_meal.png new file mode 100644 index 000000000..bc06c2865 Binary files /dev/null and b/mods/ITEMS/mcl_dye/textures/mcl_bone_meal_bone_meal.png differ diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_black.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_black.png index 95a8df4ad..79670d4e2 100644 Binary files a/mods/ITEMS/mcl_dye/textures/mcl_dye_black.png and b/mods/ITEMS/mcl_dye/textures/mcl_dye_black.png differ diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_blue.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_blue.png index e0e302307..25eaacb4f 100644 Binary files a/mods/ITEMS/mcl_dye/textures/mcl_dye_blue.png and b/mods/ITEMS/mcl_dye/textures/mcl_dye_blue.png differ diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_brown.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_brown.png index 877ee69dc..b24c84b1f 100644 Binary files a/mods/ITEMS/mcl_dye/textures/mcl_dye_brown.png and b/mods/ITEMS/mcl_dye/textures/mcl_dye_brown.png differ diff --git a/mods/ITEMS/mcl_dye/textures/dye_cyan.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_cyan.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_cyan.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_cyan.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_dark_green.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_dark_green.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_dark_green.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_dark_green.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_dark_grey.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_dark_grey.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_dark_grey.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_dark_grey.png diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_green.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_green.png new file mode 100644 index 000000000..7b4d08b34 Binary files /dev/null and b/mods/ITEMS/mcl_dye/textures/mcl_dye_green.png differ diff --git a/mods/ITEMS/mcl_dye/textures/dye_grey.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_grey.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_grey.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_grey.png diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_light_blue.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_lightblue.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/mcl_dye_light_blue.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_lightblue.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_magenta.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_magenta.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_magenta.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_magenta.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_orange.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_orange.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_orange.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_orange.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_pink.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_pink.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_pink.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_pink.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_red.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_red.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_red.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_red.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_violet.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_violet.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_violet.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_violet.png diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_white.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_white.png index bc06c2865..4ceeed439 100644 Binary files a/mods/ITEMS/mcl_dye/textures/mcl_dye_white.png and b/mods/ITEMS/mcl_dye/textures/mcl_dye_white.png differ diff --git a/mods/ITEMS/mcl_dye/textures/dye_yellow.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_yellow.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_yellow.png rename to mods/ITEMS/mcl_dye/textures/mcl_dye_yellow.png diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 34fb55698..fa6dea353 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -520,7 +520,7 @@ function mcl_enchanting.show_enchanting_formspec(player) local table_slots = mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) for i, slot in ipairs(table_slots) do any_enchantment = any_enchantment or slot - local enough_lapis = inv:contains_item("enchanting_lapis", ItemStack({name = "mcl_dye:blue", count = i})) + local enough_lapis = inv:contains_item("enchanting_lapis", ItemStack({name = "mcl_core:lapis", count = i})) local enough_levels = slot and slot.level_requirement <= player_levels local can_enchant = (slot and enough_lapis and enough_levels) local ending = (can_enchant and "" or "_off") @@ -555,7 +555,7 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) local meta = player:get_meta() local num_bookshelfes = meta:get_int("mcl_enchanting:num_bookshelves") local itemstack = inv:get_stack("enchanting_item", 1) - local cost = ItemStack({name = "mcl_dye:blue", count = button_pressed}) + local cost = ItemStack({name = "mcl_core:lapis", count = button_pressed}) if not inv:contains_item("enchanting_lapis", cost) then return end @@ -576,6 +576,7 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) minetest.sound_play("mcl_enchanting_enchant", {to_player = name, gain = 5.0}) mcl_enchanting.reset_table_slots(player) mcl_enchanting.show_enchanting_formspec(player) + awards.unlock(player:get_player_name(), "mcl:enchanter") end end @@ -607,7 +608,7 @@ function mcl_enchanting.allow_inventory_action(player, action, inventory, invent if action == "move" then local listname = inventory_info.to_list local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index) - if stack:get_name() == "mcl_dye:blue" and listname ~= "enchanting_item" then + if stack:get_name() == "mcl_core:lapis" and listname ~= "enchanting_item" then local count = stack:get_count() local old_stack = inventory:get_stack("enchanting_lapis", 1) if old_stack:get_name() ~= "" then @@ -630,7 +631,7 @@ function mcl_enchanting.on_inventory_action(player, action, inventory, inventory if action == "move" and inventory_info.to_list == "enchanting" then local stack = inventory:get_stack("enchanting", 1) local result_list - if stack:get_name() == "mcl_dye:blue" then + if stack:get_name() == "mcl_core:lapis" then result_list = "enchanting_lapis" stack:add_item(inventory:get_stack("enchanting_lapis", 1)) else diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr index 985499964..d8f07507b 100644 --- a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr @@ -1,100 +1,144 @@ # textdomain: mcl_enchanting + + +### enchantments.lua ### + +Arrows passes through multiple objects.=Les flèches traversent plusieurs objets. +Arrows set target on fire.=Les flèches mettent le feu à la cible. +Bane of Arthropods=Fléau des arthropodes +Channeling=Canalisation + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Canalise un éclair vers une cible. Fonctionne uniquement pendant les orages et si la cible n'est pas obstruée par des blocs opaques. + +Curse of Vanishing=Malédiction de disparition +Decreases crossbow charging time.=Diminue le temps de chargement de l'arbalète. +Decreases time until rod catches something.=Diminue le temps jusqu'à ce qu'un poisson ne morde à l'hameçon. +Depth Strider=Agilité aquatique +Efficiency=Efficacité +Extends underwater breathing time.=Prolonge le temps de respiration sous l'eau. +Fire Aspect=Aura de feu +Flame=Flamme +Fortune=Fortune +Frost Walker=Semelles givrantes +Impaling=Empalement +Increases arrow damage.=Augmente les dégâts des flèches. +Increases arrow knockback.=Augmente le recul de la flèche. +Increases certain block drops.=Multiplie les items droppés + +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Augmente les dégâts et applique la lenteur IV aux mobs arthropodes (araignées, araignées des cavernes, lépismes argentés et endermites). + +Increases damage to undead mobs.=Augmente les dégâts infligés aux monstres morts-vivants. +Increases damage.=Augmente les dégâts. +Increases item durability.=Augmente la durabilité des objets. +Increases knockback.=Augmente le recul. +Increases mining speed.=Augmente la vitesse de minage. +Increases mob loot.=Augmente le butin des mobs. +Increases rate of good loot (enchanting books, etc.)=Augmente le taux de bon butin (livres enchanteurs, etc.) +Increases sweeping attack damage.=Augmente les dégâts de l'épée +Increases underwater movement speed.=Augmente la vitesse de déplacement sous l'eau. +Increases walking speed on soul sand.=Augmente la vitesse de marche sur le sable de l'âme. +Infinity=Infinité +Item destroyed on death.=Objet détruit à la mort. +Knockback=Recul +Looting=Butin +Loyalty=Loyauté +Luck of the Sea=Chance de la mer +Lure=Appât +Mending=Raccommodage +Mined blocks drop themselves.=Vous obtenez les blocs minés en minant. +Multishot=Tir multiple +Piercing=Perforation +Power=Puissance +Punch=Frappe +Quick Charge=Charge rapide +Repair the item while gaining XP orbs.=Réparez l'objet tout en gagnant des points d'XP. +Respiration=Apnée +Riptide=Impulsion +Sets target on fire.=Enflamme la cible. +Sharpness=Tranchant +Shoot 3 arrows at the cost of one.=Tirez 3 flèches pour le prix d'une. +Shooting consumes no regular arrows.=Le tir ne consomme pas de flèches standard. +Silk Touch=Toucher de soie +Smite=Châtiment +Soul Speed=Agilité des âmes +Sweeping Edge=Affilage +Trident deals additional damage to ocean mobs.=Le trident inflige des dégâts supplémentaires aux animaux océaniques. + +Trident launches player with itself when thrown. Works only in water or rain.=Le trident emporte le joueur avec lui-même lorsqu'il est lancé. Fonctionne uniquement sous l'eau ou sous la pluie. + +Trident returns after being thrown. Higher levels reduce return time.=Le trident revient après avoir été jeté. Des niveaux plus élevés réduisent le temps de retour. + +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Transforme l'eau sous le joueur en glace givrée et empêche les dommages causés par les blocs de magma. + +Unbreaking=Solidité + +### engine.lua ### + +@1 Enchantment Levels=@1 Niveaux d'enchantement +@1 Lapis Lazuli=@1 Lapis Lazuli +Inventory=Inventaire +Level requirement: @1=Niveau requis: @1 + +### init.lua ### + +'@1' is not a valid number='@1' n'est pas un nombre valide +'@1' is not a valid number.='@1' n'est pas un nombre valide. + []= [] +@1 can't be combined with @2.=@1 ne peut pas être combiné avec @2. + +After finally selecting your enchantment; left-click on the selection, and you will see both the lapis lazuli and your experience levels consumed. And, an enchanted item left in its place.=Après avoir finalement sélectionné un enchantement ; cliquer gauche la sélection, et vous verrez à la fois les lapis-lazuli et vos niveaux d'expérience consommés. Un objet enchanté est laissé à leur place. + +After placing your items in the slots, the enchanting options will be shown. Hover over the options to read what is available to you.=Après avoir placé vos objets dans les emplacements, les options d'enchantement seront montrées. Passer au-dessus des options pour lire ce qui est disponible. + +Enchant=Enchantement +Enchant an item=Enchanter un objet +Enchanted Book=Livre enchanté +Enchanting Table=Table d'enchantement + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.=La table d'enchantement vous permet d'enchanter des armueres, des outils, des armes et des livres avec diverses propriétés. Mais cela coûte de l'expérience et des lapis-lazuli. + +Enchanting succeded.=L'enchantement a réussi. +Forcefully enchant an item=Enchantement forcé d'un objet + +Place a tool, armor, weapon or book into the top left slot, and then place 1-3 Lapis Lazuli in the slot to the right.=Placer un outil, armure, arme ou livre dans l'emplacement en haut à gauche, puis 1-3 Lapis-Lazuli dans l'emplacement à droite. + +Player '@1' cannot be found.=Le joueur '@1' est introuvable. +Rightclick the Enchanting Table to open the enchanting menu.=Cliquer droit la table d'enchantement pour ouvrir le menu d'enchantement. +Spend experience, and lapis to enchant various items.=Dépenser de l'expérience, et des lapis pour enchanter divers objets. + +The number you have entered (@1) is too big, it must be at most @2.=Le nombre que vous avez entré (@1) est trop grand, il doit être au plus de @2. + +The number you have entered (@1) is too small, it must be at least @2.=Le nombre que vous avez entré (@1) est trop petit, il doit être au moins de @2. + +The selected enchantment can't be added to the target item.=L'enchantement sélectionné ne peut pas être ajouté à la cible. +The target doesn't hold an item.=La cible ne contient aucun élément. +The target item is not enchantable.=L'objet cible n'est pas enchantable. +There is no such enchantment '@1'.=Il n'y a pas un tel enchantement '@1'. + +These options are randomized, and dependent on experience level; but the enchantment strength can be increased.=Ces options sont aléatoires et dépendent du niveau d'expérience ; mais la force d'enchantement peut être augmentée. + +To increase the enchantment strength, place bookshelves around the enchanting table. However, you will need to keep 1 air node between the table, & the bookshelves to empower the enchanting table.=Pour augmenter la force d'enchantement, placer des bibliothèques autour de la table d'enchantement. Cependant, vous devrez garder au moins un bloc d'air entre la table et les bibliothèques pour alimenter la table d'enchantement. + +Usage: /enchant []=Usage: /enchant [] +Usage: /forceenchant []=Usage: /forceenchant [] + + +##### not used anymore ##### + +# textdomain: mcl_enchanting Aqua Affinity=Affinité aquatique Increases underwater mining speed.=Augmente la vitesse de minage sous-marine. -Bane of Arthropods=Fléau des arthropodes -Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Augmente les dégâts et applique la lenteur IV aux mobs arthropodes (araignées, araignées des cavernes, lépismes argentés et endermites). 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 é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. -Depth Strider=Agilité aquatique -Increases underwater movement speed.=Augmente la vitesse de déplacement sous l'eau. -Efficiency=Efficacité -Increases mining speed.=Augmente la vitesse de minage. Feather Falling=Chute amortie Reduces fall damage.=Reduit les dégats de chute. -Fire Aspect=Aura de feu -Sets target on fire.=Définit la cible en feu. Fire Protection=Protection contre le feu Reduces fire damage.=Reduit les dégats de feu. -Flame=Flamme -Arrows set target on fire.=Les flèches mettent le feu à la cible. -Fortune=Fortune -Increases certain block drops.=Multiplie les items droppés -Frost Walker=Semelles givrantes -Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Transforme l'eau sous le joueur en glace givrée et empêche les dommages causés par les blocs de magma. -Impaling=Empalement -Trident deals additional damage to ocean mobs.=Trident inflige des dégâts supplémentaires aux mobs océaniques. -Infinity=Infinité -Shooting consumes no regular arrows.=Le tir ne consomme pas de flèches standard. -Knockback=Recul -Increases knockback.=Augmente le recul. -Looting=Butin -Increases mob loot.=Augmente le butin des mobs. -Loyalty=Loyauté -Trident returns after being thrown. Higher levels reduce return time.=Trident revient après avoir été jeté. Des niveaux plus élevés réduisent le temps de retour. -Luck of the Sea=Chance de la mer -Increases rate of good loot (enchanting books, etc.)=Augmente le taux de bon butin (livres enchanteurs, etc.) -Lure=Appât -Decreases time until rod catches something.=Diminue le temps jusqu'à ce qu'un poisson ne morde à l'hameçon. -Mending=Raccommodage -Repair the item while gaining XP orbs.=Réparez l'objet tout en gagnant des points d'XP. -Multishot=Tir multiple -Shoot 3 arrows at the cost of one.=Tirez sur 3 flèches au prix d'une. -Piercing=Perforation -Arrows passes through multiple objects.=Les flèches traversent plusieurs objets. -Power=Puissance -Increases arrow damage.=Augmente les dégâts des flèches. Projectile Protection=Protection contre les projectiles Reduces projectile damage.=Réduit les dommages causés par les projectiles. Protection=Protection Reduces most types of damage by 4% for each level.=éduit la plupart des types de dégâts de 4% pour chaque niveau. -Punch=Frappe -Increases arrow knockback.=Augmente le recul de la flèche. -Quick Charge=Charge rapide -Decreases crossbow charging time.=Diminue le temps de chargement de l'arbalète. -Respiration=Apnée -Extends underwater breathing time.=Prolonge le temps de respiration sous l'eau. -Riptide=Impulsion -Trident launches player with itself when thrown. Works only in water or rain.=Trident lance le joueur avec lui-même lorsqu'il est lancé. Fonctionne uniquement sous l'eau ou sous la pluie. -Sharpness=Tranchant -Increases damage.=Augmente les dégâts. -Silk Touch=Toucher de soie -Mined blocks drop themselves.=Les blocs minés tombent d'eux-mêmes. -Smite=Châtiment -Increases damage to undead mobs.=Augmente les dégâts infligés aux monstres morts-vivants. -Soul Speed=Agilité des âmes -Increases walking speed on soul sand.=Augmente la vitesse de marche sur le sable de l'âme. -Sweeping Edge=Affilage -Increases sweeping attack damage.=Augmente les dégâts de l'épée -Thorns=Épines Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflète une partie des dégâts subis lors de la frappe, au prix d'une réduction de la durabilité à chaque déclenchement. -Unbreaking=Solidité -Increases item durability.=Augmente la durabilité des objets. -Inventory=Inventaire -@1 Lapis Lazuli=@1 Lapis Lazuli -@1 Enchantment Levels=@1 Niveaux d'enchantement -Level requirement: @1=Niveau requis: @1 -Enchant an item=Enchanter un objet - []= [] -Usage: /enchant []=Usage: /enchant [] -Player '@1' cannot be found.=Le joueur '@1' est introuvable. -There is no such enchantment '@1'.=Il n'y a pas un tel enchantement '@1'. -The target doesn't hold an item.=La cible ne contient aucun élément. -The selected enchantment can't be added to the target item.=L'enchantement sélectionné ne peut pas être ajouté à la cible. -'@1' is not a valid number='@1' n'est pas un nombre valide -The number you have entered (@1) is too big, it must be at most @2.=Le nombre que vous avez entré (@1) est trop grand, il doit être au plus de @2. -The number you have entered (@1) is too small, it must be at least @2.=Le nombre que vous avez entré (@1) est trop petit, il doit être au moins de @2. -@1 can't be combined with @2.=@1 ne peut pas être combiné avec @2. -Enchanting succeded.=L'enchantement a réussi. -Forcefully enchant an item=Enchantement forcé d'un objet -Usage: /forceenchant []=Usage: /forceenchant [] -The target item is not enchantable.=L'objet cible n'est pas enchantable. -'@1' is not a valid number.='@1' n'est pas un nombre valide. -Enchanted Book=Livre enchanté -Enchanting Table=Table d'enchantement -Enchant=Enchantement +Thorns=Épines \ No newline at end of file diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ja.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ja.tr new file mode 100644 index 000000000..1983ec4d4 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ja.tr @@ -0,0 +1,144 @@ +# textdomain: mcl_enchanting + + +### enchantments.lua ### + +Arrows passes through multiple objects.=矢が複数のオブジェクトを貫通します。 +Arrows set target on fire.=矢がターゲットを燃やします。 +Bane of Arthropods=殺虫力 +Channeling=召雷 + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=ターゲットに向けて稲妻を落とします。雷雨の時、且つターゲットが不透明なブロックで遮られていない場合のみ有効です。 + +Curse of Vanishing=消滅の呪い +Decreases crossbow charging time.=クロスボウの装填時間が短くなります。 +Decreases time until rod catches something.=釣りで獲物のかかる間隔が短くなります。 +Depth Strider=水中移動 +Efficiency=効率化 +Extends underwater breathing time.=水中での呼吸時間を延長します。 +Fire Aspect=火属性 +Flame=フレイム +Fortune=幸運 +Frost Walker=氷結歩行 +Impaling=串刺し +Increases arrow damage.=矢のダメージが増加します。 +Increases arrow knockback.=矢のノックバックを強化します。 +Increases certain block drops.=特定のブロックのドロップが増加します。 + +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=虫系のMOB(クモ、洞窟グモ、シルバーフィッシュ、エンダーマイト)に対してダメージが増加し、鈍化IVを適用します。 + +Increases damage to undead mobs.=アンデッド系のMOBへのダメージが増加します。 +Increases damage.=ダメージが増加します。 +Increases item durability.=アイテムの耐久度が向上します。 +Increases knockback.=ノックバックを強化します。 +Increases mining speed.=採掘速度が増加します。 +Increases mob loot.=MOBの戦利品が増加します。 +Increases rate of good loot (enchanting books, etc.)=釣果の質が良くなります(エンチャントの本など)。 +Increases sweeping attack damage.=なぎ払い攻撃のダメージが増加します。 +Increases underwater movement speed.=水中での横移動速度が増加します。 +Increases walking speed on soul sand.=ソウルサンドとソウルソイルの上を歩く速度が増加します。 +Infinity=無限 +Item destroyed on death.=死亡時にアイテムが消滅します。 +Knockback=ノックバック +Looting=奪取 +Loyalty=忠誠 +Luck of the Sea=宝釣り +Lure=入れ食い +Mending=自己修復 +Mined blocks drop themselves.=採掘したブロックそのものをドロップするようになります。 +Multishot=拡散弾 +Piercing=貫通 +Power=パワー +Punch=衝撃 +Quick Charge=高速装填 +Repair the item while gaining XP orbs.=アイテムが経験値を得て自己を修復します。 +Respiration=水中呼吸 +Riptide=激流 +Sets target on fire.=ターゲットに火をつけます。 +Sharpness=鋭利 +Shoot 3 arrows at the cost of one.=1本分のコストで、3本の矢を同時に拡散発射します。 +Shooting consumes no regular arrows.=普通の矢は射ても消費しなくなります。 +Silk Touch=シルクタッチ +Smite=破邪 +Soul Speed=ソウルスピード +Sweeping Edge=スイープエッジ +Trident deals additional damage to ocean mobs.=トライデントは水生系のMOBに追加ダメージを与えます。 + +Trident launches player with itself when thrown. Works only in water or rain.=投擲したトライデントと共に、プレイヤーを突進させます。水中か雨天でのみ機能します。 + +Trident returns after being thrown. Higher levels reduce return time.=投擲したトライデントが手に戻ってきます。レベルが高いほど戻る時間が短縮されます。 + +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=プレイヤーの下の水を薄氷に変え、また、マグマブロックからのダメージを防ぎます。 + +Unbreaking=耐久力 + +### engine.lua ### + +@1 Enchantment Levels=@1 エンチャントレベル +@1 Lapis Lazuli=@1 ラピスラズリ +Inventory=インベントリ +Level requirement: @1=必要レベル:@1 + +### init.lua ### + +'@1' is not a valid number='@1'は有効ではない数字 +'@1' is not a valid number.='@1'は有効な数字ではありません。 + []=<プレイヤー> <エンチャント> [<レベル>] +@1 can't be combined with @2.=@1は@2と組み合わせられません。 + +After finally selecting your enchantment; left-click on the selection, and you will see both the lapis lazuli and your experience levels consumed. And, an enchanted item left in its place.=最終的にエンチャントを決めたら;選ぶ箇所を左クリックすると、ラピスラズリと経験値の両方が消費されているのがわかります。そしてエンチャントしたアイテムがその場に残されます。 + +After placing your items in the slots, the enchanting options will be shown. Hover over the options to read what is available to you.=アイテムをスロットに配置すると、エンチャント オプションが表示されます。オプションにカーソルを合わせると、利用可能なオプションが表示されます。 + +Enchant=エンチャント +Enchant an item=アイテムにエンチャントする +Enchanted Book=エンチャント本 +Enchanting Table=エンチャントテーブル + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.=エンチャントテーブルでは、防具や道具、武器、本などに様々な能力をエンチャントできます。ただし多少の経験値や、ラピスラズリを費やすことになります。 + +Enchanting succeded.=エンチャントが成功しました。 +Forcefully enchant an item=アイテムに強制的にエンチャント + +Place a tool, armor, weapon or book into the top left slot, and then place 1-3 Lapis Lazuli in the slot to the right.=左上のスロットに道具、防具、武器、本を入れ、その右のスロットにラピスラズリ1~3個を入れます。 + +Player '@1' cannot be found.=プレイヤー'@1'が見つかりません。 +Rightclick the Enchanting Table to open the enchanting menu.=エンチャントテーブルを右クリックすると、エンチャント メニューが表示されます。 +Spend experience, and lapis to enchant various items.=経験値とラピスを消費して、様々なアイテムにエンチャントできます。 + +The number you have entered (@1) is too big, it must be at most @2.=入力した数値(@1)は大きすぎます、@2以下である必要があります。 + +The number you have entered (@1) is too small, it must be at least @2.=入力した数値(@1)は小さすぎます、@2以上である必要があります。 + +The selected enchantment can't be added to the target item.=選択したエンチャントは、対象アイテムに付加できません。 +The target doesn't hold an item.=対象がアイテムを保持していません。 +The target item is not enchantable.=対象アイテムは、エンチャント不可です。 +There is no such enchantment '@1'.='@1'というエンチャントはありません。 + +These options are randomized, and dependent on experience level; but the enchantment strength can be increased.=これらのオプションはランダム且つ経験値に依存します;しかし、エンチャントを強化できます。 + +To increase the enchantment strength, place bookshelves around the enchanting table. However, you will need to keep 1 air node between the table, & the bookshelves to empower the enchanting table.=エンチャントテーブルの周囲に本棚を置くと、エンチャントを強化できます。ただし、テーブルと本棚の間に空気ノードを1つ入れないと、エンチャントテーブルに力を与えられません。 + +Usage: /enchant []=使用方法:/enchant <プレイヤー> <エンチャント> [<レベル>] +Usage: /forceenchant []=使用方法:/forceenchant <プレイヤー> <エンチャント> [<レベル>] + + +##### not used anymore ##### + +# textdomain: mcl_enchanting +Aqua Affinity=水中採掘 +Increases underwater mining speed.=水中での採掘速度が向上します。 +Blast Protection=爆風耐性 +Reduces explosion damage and knockback.=爆発ダメージとノックバックを軽減します。 +Curse of Binding=束縛の呪い +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=次の場合を除き、防具スロットからアイテムを外せません;アイテムが破損/自身が死亡/クリエイティブモード中 +Feather Falling=落下耐性 +Reduces fall damage.=落下ダメージを軽減します。 +Fire Protection=炎上耐性 +Reduces fire damage.=火炎ダメージを軽減します(溶岩は対象外)。 +Projectile Protection=飛来物耐性 +Reduces projectile damage.=飛来物ダメージを軽減します。 +Protection=外傷耐性 +Reduces most types of damage by 4% for each level.=体の外からのダメージ全般を軽減します(レベル毎に+4%)。 +Thorns=イバラ +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=受けたダメージの一部を与え返せますが、その代わり耐久度が余計に削られます。 diff --git a/mods/ITEMS/mcl_enchanting/locale/template.txt b/mods/ITEMS/mcl_enchanting/locale/template.txt index 1f540d6d3..59876dcf3 100644 --- a/mods/ITEMS/mcl_enchanting/locale/template.txt +++ b/mods/ITEMS/mcl_enchanting/locale/template.txt @@ -127,3 +127,18 @@ Usage: /forceenchant []= # textdomain: mcl_enchanting Aqua Affinity= +Increases underwater mining speed.= +Blast Protection= +Reduces explosion damage and knockback.= +Curse of Binding=Malédiction du lien éternel +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.= +Feather Falling= +Reduces fall damage.= +Fire Protection= +Reduces fire damage.= +Projectile Protection= +Reduces projectile damage.= +Protection= +Reduces most types of damage by 4% for each level.= +Thorns= +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.= diff --git a/mods/ITEMS/mcl_enchanting/mod.conf b/mods/ITEMS/mcl_enchanting/mod.conf index 4d4741fb8..610492857 100644 --- a/mods/ITEMS/mcl_enchanting/mod.conf +++ b/mods/ITEMS/mcl_enchanting/mod.conf @@ -1,5 +1,5 @@ name = mcl_enchanting description = Enchanting for MineClone2 -depends = tt, walkover, mcl_sounds, mcl_colors +depends = tt, walkover, mcl_sounds, mcl_colors, mcl_experience optional_depends = screwdriver author = Fleckenstein diff --git a/mods/ITEMS/mcl_end/building.lua b/mods/ITEMS/mcl_end/building.lua index 06c6722c4..82f6e76e4 100644 --- a/mods/ITEMS/mcl_end/building.lua +++ b/mods/ITEMS/mcl_end/building.lua @@ -29,7 +29,7 @@ minetest.register_node("mcl_end:end_bricks", { groups = {pickaxey=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 9, - _mcl_hardness = 0.8, + _mcl_hardness = 3, }) minetest.register_node("mcl_end:purpur_block", { diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index b7c80c55a..b7882a155 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -1,5 +1,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + local vector = vector local explosion_strength = 6 @@ -65,12 +67,20 @@ local function spawn_crystal(pos) crystals[i] = find_crystal(crystal_pos) if not crystals[i] then return end end + for _,o in pairs(minetest.get_objects_inside_radius(pos,64)) do + local l = o:get_luaentity() + if l and l.name == "mobs_mc:enderdragon" then return end + if not peaceful then + if o:is_player() then + awards.unlock(o:get_player_name(), "mcl:theEndAgain") + end + end + end for _, crystal in pairs(crystals) do crystal_explode(crystal) end - local portal_pos = vector.add(portal_center, vector.new(-3, -1, -3)) - mcl_structures.call_struct(portal_pos, "end_exit_portal") - minetest.add_entity(vector.add(portal_pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()._portal_pos = portal_pos + local portal_pos = vector.add(portal_center, vector.new(0, -1, 0)) + mcl_structures.place_structure(portal_pos,mcl_structures.registered_structures["end_exit_portal"],PseudoRandom(minetest.get_mapgen_setting("seed")),-1) end minetest.register_entity("mcl_end:crystal", { diff --git a/mods/ITEMS/mcl_end/eye_of_ender.lua b/mods/ITEMS/mcl_end/eye_of_ender.lua index ea3d70aba..b5adc7cb6 100644 --- a/mods/ITEMS/mcl_end/eye_of_ender.lua +++ b/mods/ITEMS/mcl_end/eye_of_ender.lua @@ -87,7 +87,7 @@ minetest.register_craftitem("mcl_end:ender_eye", { end local origin = user:get_pos() origin.y = origin.y + 1.5 - local strongholds = mcl_structures.get_registered_structures("stronghold") + local strongholds = mcl_structures.registered_structures["end_shrine"].static_pos local dim = mcl_worlds.pos_to_dimension(origin) local is_creative = minetest.is_creative_enabled(user:get_player_name()) @@ -105,7 +105,7 @@ minetest.register_craftitem("mcl_end:ender_eye", { local closest_stronghold local lowest_dist for s=1, #strongholds do - local h_pos = table.copy(strongholds[s].pos) + local h_pos = table.copy(strongholds[s]) local h_origin = table.copy(origin) h_pos.y = 0 h_origin.y = 0 @@ -128,14 +128,14 @@ minetest.register_craftitem("mcl_end:ender_eye", { if lowest_dist <= 25 then local velocity = 4 -- Stronghold is close: Fly directly to stronghold and take Y into account. - dir = vector.normalize(vector.direction(origin, closest_stronghold.pos)) + dir = vector.normalize(vector.direction(origin, closest_stronghold)) obj:set_velocity({x=dir.x*velocity, y=dir.y*velocity, z=dir.z*velocity}) else local velocity = 12 -- Don't care about Y if stronghold is still far away. -- Fly to direction of X/Z, and always upwards so it can be seen easily. local o = {x=origin.x, y=0, z=origin.z} - local s = {x=closest_stronghold.pos.x, y=0, z=closest_stronghold.pos.z} + local s = {x=closest_stronghold.x, y=0, z=closest_stronghold.z} dir = vector.normalize(vector.direction(o, s)) obj:set_acceleration({x=dir.x*-3, y=4, z=dir.z*-3}) obj:set_velocity({x=dir.x*velocity, y=3, z=dir.z*velocity}) diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.ja.tr b/mods/ITEMS/mcl_end/locale/mcl_end.ja.tr new file mode 100644 index 000000000..647d3aea3 --- /dev/null +++ b/mods/ITEMS/mcl_end/locale/mcl_end.ja.tr @@ -0,0 +1,33 @@ +# textdomain: mcl_end +End Stone=エンドストーン +End Stone Bricks=エンドストーンレンガ +Purpur Block=プルプァブロック +Purpur Pillar=プルプァの柱 +End Rod=エンドロッド +End rods are decorative light sources.=エンドロッドは装飾用の光源です。 +Dragon Egg=ドラゴンの卵 +A dragon egg is a decorative item which can be placed.=ドラゴンの卵は、置いておくだけの装飾用アイテムです。 +Chorus Flower=コーラスフラワー +A chorus flower is the living part of a chorus plant. It can grow into a tall chorus plant, step by step. When it grows, it may die on old age eventually. It also dies when it is unable to grow.=コーラスフラワーは、コーラスプラントの生きた部分です。徐々に成長し、背の高いコーラスプラントになれます。やがて老衰が訪れ、成長した時に枯れることもあります。また、成長できなくなった時にも枯れてしまいます。 +Place it and wait for it to grow. It can only be placed on top of end stone, on top of a chorus plant stem, or at the side of exactly one chorus plant stem.=それを置き、成長を待ちます。置ける所は、エンドストーンかコーラスプラントの茎の上、または きっちり1本分あるコーラスプラントの茎の側面に限られます。 +Dead Chorus Flower=枯れたコーラスフラワー +This is a part of a chorus plant. It doesn't grow. Chorus flowers die of old age or when they are unable to grow. A dead chorus flower can be harvested to obtain a fresh chorus flower which is able to grow again.=これはコーラスプラントの一部です。成長はしません。コーラスフラワーは、老衰や成長できなくなった場合に枯れてしまうのです。枯れたコーラスフラワーを収穫することで、再び成長できる新鮮なコーラスフラワーが得られます。 +Chorus Plant Stem=コーラスプラントの茎 +A chorus plant stem is the part of a chorus plant which holds the whole plant together. It needs end stone as its soil. Stems are grown from chorus flowers.=コーラスプラントの茎は、コーラスプラント全体を支えている部分です。その土壌としてエンドストーンを要します。コーラスフラワーから茎が育ちます。 +Chorus Fruit=コーラスフルーツ +A chorus fruit is an edible fruit from the chorus plant which is home to the End. Eating it teleports you to the top of a random solid block nearby, provided you won't end up inside a liquid, solid or harmful blocks. Teleportation might fail if there are very few or no places to teleport to.=コーラスフルーツはエンドを原産地とする食用の果実で、コーラスプラントから取れます。食べると、近くのランダムな固体のブロックの上にテレポートします。ただし、液体、固体、有害なブロックの中に入ってしまわない場合のみです。テレポート先が殆ど又は全くない場合、テレポートに失敗することがあります。 +Popped Chorus Fruit=爆ぜたコーラスフルーツ +Eye of Ender=エンダーアイ +This item is used to locate End portal shrines in the Overworld and to activate End portals.=これはオーバーワールドにあるエンドポータルの場所を探すのに使い、また、ポータルを起動する場合にも使うアイテムです。 +Use the attack key to release the eye of ender. It will rise and fly in the horizontal direction of the closest end portal shrine. If you're very close, the eye of ender will take the direct path to the End portal shrine instead. After a few seconds, it stops. It may drop as an item, but there's a 20% chance it shatters.=攻撃キーでエンダーアイを放ちます。それは上昇した後、最も近いエンドポータルに向かって水平に飛んでいきます。非常に近くにいる場合はその代わりに、エンドポータルへの直進経路をとるようになり、エンダーアイは数秒後に停止します。使用後はアイテムとしてドロップしますが、それは粉々になる確率20%を通過できた場合です。 +To activate an End portal, eyes of ender need to be placed into each block of an intact End portal frame.=エンドポータルを起動するには、手付かずのエンドポータルフレームの各ブロックに、エンダーアイを配置する必要があります。 +NOTE: The End dimension is currently incomplete and might change in future versions.=注:エンド次元は現在未完成であり、将来のバージョンで変更される可能性があります。 +The stem attaches itself to end stone and other chorus blocks.=茎は、エンドストーンや他のコーラスブロックに取り付けられます。 +Grows on end stone=エンドストーンに生育 +Randomly teleports you when eaten=食べるとランダムにテレポート +Guides the way to the mysterious End dimension=神秘的なエンド次元への道案内 +End Crystal=エンドクリスタル +End Crystals are explosive devices. They can be placed on Obsidian or Bedrock. Ignite them by a punch or a hit with an arrow. End Crystals can also be used the spawn the Ender Dragon by placing one at each side of the End Exit Portal.=エンドクリスタルは爆発装置です。黒曜石や 岩盤の上に置けます。パンチか矢を当てると着火されます。エンドクリスタルは、エンドの出口ポータルの左右に1つずつ配置することで、エンダードラゴンを出現させることもできます。 +Explosion radius: @1=爆発範囲:@1 +Ignited by a punch or a hit with an arrow=パンチか矢を当てると着火 +Place the End Crystal on Obsidian or Bedrock, then punch it or hit it with an arrow to cause an huge and probably deadly explosion. To Spawn the Ender Dragon, place one at each side of the End Exit Portal.=エンドクリスタルを黒曜石や岩盤の上に置き、パンチか矢を当てると、おそらく致命的であろう大爆発を起こします。エンダードラゴンを出現させるには、エンドの出口ポータルの左右に1つずつ配置します。 diff --git a/mods/ITEMS/mcl_farming/README.txt b/mods/ITEMS/mcl_farming/README.txt index 5779d7035..02cdaf93a 100644 --- a/mods/ITEMS/mcl_farming/README.txt +++ b/mods/ITEMS/mcl_farming/README.txt @@ -1,16 +1,12 @@ ===FARMING MOD for MINETEST-C55=== by PilzAdam +Modified heavily by MineClone 2 Dev Team. + Introduction: This mod adds farming to Minetest. -How to install: -Unzip the archive an place it in minetest-base-directory/mods/minetest/ -if you have a windows client or a linux run-in-place client. If you have -a linux system-wide instalation place it in ~/.minetest/mods/minetest/. -If you want to install this mod only in one world create the folder -worldmods/ in your worlddirectory. -For further information or help see: +How to install see: http://wiki.minetest.com/wiki/Installing_Mods How to use the mod: @@ -25,22 +21,8 @@ For further information or help see: http://minetest.net/forum/viewtopic.php?id=2787 License: -Sourcecode: WTFPL (see below) -Graphics: WTFPL (see below) +Sourcecode: CC-BY-SA 4 (see below) +Graphics: CC-BY-SA 4 (see below) See also: http://minetest.net/ - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - - Copyright (C) 2004 Sam Hocevar - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/mods/ITEMS/mcl_farming/carrots.lua b/mods/ITEMS/mcl_farming/carrots.lua index 1c3ebcdfa..b76606be2 100644 --- a/mods/ITEMS/mcl_farming/carrots.lua +++ b/mods/ITEMS/mcl_farming/carrots.lua @@ -89,14 +89,7 @@ minetest.register_craftitem("mcl_farming:carrot_item", { 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 then - return new - else - return minetest.do_item_eat(3, nil, itemstack, placer, pointed_thing) - end - end, + on_place = mcl_farming:get_seed_or_eat_callback("mcl_farming:carrot_1", 3), }) minetest.register_craftitem("mcl_farming:carrot_item_gold", { diff --git a/mods/ITEMS/mcl_farming/hoes.lua b/mods/ITEMS/mcl_farming/hoes.lua index d2250eb70..72d8f7b7a 100644 --- a/mods/ITEMS/mcl_farming/hoes.lua +++ b/mods/ITEMS/mcl_farming/hoes.lua @@ -54,7 +54,8 @@ local uses = { stone = 132, iron = 251, gold = 33, - diamond = 1562, + diamond = 1562, + netherite = 2031, } local hoe_tt = S("Turns block into farmland") @@ -255,6 +256,8 @@ minetest.register_tool("mcl_farming:hoe_diamond", { _mcl_diggroups = { hoey = { speed = 8, level = 5, uses = 1562 } }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_farming:hoe_netherite" }) minetest.register_craft({ @@ -271,5 +274,26 @@ minetest.register_craft({ {"mcl_core:diamond", "mcl_core:diamond"}, {"mcl_core:stick", ""}, {"mcl_core:stick", ""} - } -}) + } +}) + +minetest.register_tool("mcl_farming:hoe_netherite", { + description = S("Netherite Hoe"), + _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.netherite), + _doc_items_longdesc = hoe_longdesc, + _doc_items_usagehelp = hoe_usagehelp, + inventory_image = "farming_tool_netheritehoe.png", + wield_scale = mcl_vars.tool_wield_scale, + on_place = hoe_on_place_function(uses.netherite), + groups = { tool=1, hoe=1, enchantability=10, fire_immune=1 }, + tool_capabilities = { + full_punch_interval = 0.25, + damage_groups = { fleshy = 4, }, + punch_attack_uses = uses.netherite, + }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 8, level = 5, uses = uses.netherite } + }, +}) diff --git a/mods/ITEMS/mcl_farming/init.lua b/mods/ITEMS/mcl_farming/init.lua index adce058ee..60b10105d 100644 --- a/mods/ITEMS/mcl_farming/init.lua +++ b/mods/ITEMS/mcl_farming/init.lua @@ -27,3 +27,6 @@ dofile(minetest.get_modpath("mcl_farming").."/potatoes.lua") -- ========= BEETROOT ========= dofile(minetest.get_modpath("mcl_farming").."/beetroot.lua") + +-- ========= SWEET BERRY ========= +dofile(minetest.get_modpath("mcl_farming").."/sweet_berry.lua") diff --git a/mods/ITEMS/mcl_farming/locale/mcl_farming.ja.tr b/mods/ITEMS/mcl_farming/locale/mcl_farming.ja.tr new file mode 100644 index 000000000..d50c49911 --- /dev/null +++ b/mods/ITEMS/mcl_farming/locale/mcl_farming.ja.tr @@ -0,0 +1,99 @@ +# textdomain: mcl_farming +Beetroot Seeds=ビートルートの種 +Grows into a beetroot plant. Chickens like beetroot seeds.=ビートルートの作物に成長します。ニワトリはビートルートの種を好みます。 +Place the beetroot seeds on farmland (which can be created with a hoe) to plant a beetroot plant. They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it beetroot seeds.=ビートルートの種を耕地(クワで作れる)に置いて植え、ビートルートの苗にします。日光に当たると成長し、湿った耕地ではより早く成長します。動物を右クリックすると、ビートルートの種を食べさせることができます。 +Premature Beetroot Plant (Stage 1)=未成熟なビートルートの苗(1段階目) +Beetroot plants are plants which grow on farmland under sunlight in 4 stages. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature.=ビートルートの苗は、耕地で日光を浴びて育つ植物で、成長が4段階あります。湿った耕地では、やや早く成長します。収穫はいつでも可能なものの、益があるのは成熟してからです。 +Premature Beetroot Plant=未成熟なビートルートの苗 +Premature Beetroot Plant (Stage 2)=未成熟なビートルートの苗(2段階目) +Premature Beetroot Plant (Stage 3)=未成熟なビートルートの苗(3段階目) +Mature Beetroot Plant=成熟したビートルートの苗 +A mature beetroot plant is a farming plant which is ready to be harvested for a beetroot and some beetroot seeds. It won't grow any further.=成熟したビートルートの苗は、ビートルートとその種をいくつか収穫できる農作物です。これ以上は成長しません。 +Beetroot=ビートルート +Beetroots are both used as food item and a dye ingredient. Pigs like beetroots, too.=ビートルートは、食材としても染料としても使われます。ブタの好物でもあります。 +Hold it in your hand and right-click to eat it. Rightclick an animal to feed it.=手に持って右クリックすると食べられます。動物を右クリックすると、餌を与えることができます。 +Beetroot Soup=ビートルートスープ +Beetroot soup is a food item.=ビートルートスープは食料アイテムです。 +Premature Carrot Plant=未成熟なニンジンの苗 +Carrot plants are plants which grow on farmland under sunlight in 8 stages, but only 4 stages can be visually told apart. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature.=ニンジンは、耕地で日光を浴びて育つ植物で、成長が8段階あります。ただし目視で見分けられるのは4段階だけです。湿った耕地では、やや早く成長します。収穫はいつでも可能なものの、益があるのは成熟してからです。 +Premature Carrot Plant (Stage @1)=未成熟なニンジンの苗(@1段階目) +Mature Carrot Plant=成熟したニンジンの苗 +Mature carrot plants are ready to be harvested for carrots. They won't grow any further.=成熟したニンジンの苗からは、ニンジンをいくつか収穫できます。これ以上は成長しません。 +Carrot=ニンジン +Carrots can be eaten and planted. Pigs and rabbits like carrots.=ニンジンは食べてもいいし、植えてもいいでしょう。ブタやウサギはニンジンが好きです。 +Hold it in your hand and rightclick to eat it. Place it on top of farmland to plant the carrot. It grows in sunlight and grows faster on hydrated farmland. Rightclick an animal to feed it.=手に持って右クリックすると食べます。耕地に置くとニンジンを植えます。日光で育ち、湿った耕地では早く育ちます。動物を右クリックすると餌付けできます。 +Golden Carrot=金のニンジン +A golden carrot is a precious food item which can be eaten. It is really, really filling!=金のニンジンは貴重な食料アイテムです。これは本当に、マジで食べ応えがあります! +Hoes are essential tools for growing crops. They are used to create farmland in order to plant seeds on it. Hoes can also be used as very weak weapons in a pinch.=クワは農作物を育てるのに欠かせない道具です。種を植えるための耕地を作るのに使います。また、いざというときには、非常に弱い武器としても使えます。 +Use the hoe on a cultivatable block (by rightclicking it) to turn it into farmland. Dirt, grass blocks and grass paths are cultivatable blocks. Using a hoe on coarse dirt turns it into dirt.=耕せるブロックに(右クリックで)クワを使うと耕地になります。土、草原、オフロードは耕せるブロックです。粗い土にクワを使うと、土になります。 +Wood Hoe=木製のクワ +Stone Hoe=石のクワ +Iron Hoe=鉄のクワ +Golden Hoe=金のクワ +Diamond Hoe=ダイヤモンドのクワ +Melon Seeds=スイカの種 +Grows into a melon stem which in turn grows melons. Chickens like melon seeds.=成長するとスイカの茎になり、そこからスイカがなります。ニワトリはこの種が好きです。 +Place the melon seeds on farmland (which can be created with a hoe) to plant a melon stem. Melon stems grow in sunlight and grow faster on hydrated farmland. When mature, the stem will attempt to grow a melon at the side. Rightclick an animal to feed it melon seeds.=スイカの種を耕地(クワで作れる)に置いて植え、スイカの茎にします。茎は日光で育ち、湿った耕地では早く育ちます。成熟すると、茎の隣にスイカを実らせようとします。動物を右クリックすると、スイカの種を食べさせることができます。 +Melon=スイカ +A melon is a block which can be grown from melon stems, which in turn are grown from melon seeds. It can be harvested for melon slices.=スイカは、スイカの種から育つ茎を経て実るブロックです。収穫してスイカの薄切りにできます。 +Premature Melon Stem=未成熟なスイカの茎 +Melon stems grow on farmland in 8 stages. On hydrated farmland, the growth is a bit quicker. Mature melon stems are able to grow melons.=スイカの茎は耕地で育つ植物で、成長が8段階あります。湿った耕地では、やや早く成長します。成熟したスイカの茎は、スイカを実らせることができます。 +Premature Melon Stem (Stage @1)=未成熟なスイカの茎(@1段階目) +Mature Melon Stem=成熟したスイカの茎 +A mature melon stem attempts to grow a melon at one of its four adjacent blocks. A melon can only grow on top of farmland, dirt, or a grass block. When a melon is next to a melon stem, the melon stem immediately bends and connects to the melon. While connected, a melon stem can't grow another melon. As soon all melons around the stem have been removed, it loses the connection and is ready to grow another melon.=成熟したスイカの茎は、隣接する4つのブロックのいずれかでスイカを実らせようとします。実るのは、耕地、土、草原の上だけです。スイカの茎の隣にスイカがあると、茎はすぐに曲がってスイカにつながります。つながっている間は、他のスイカを実らせられません。茎の周りのスイカをすべて取り除くと、接続が切れて次のスイカが実るようになります。 +Melon Slice=スイカの薄切り +This is a food item which can be eaten.=これは食用アイテムです。 +Premature Potato Plant=未成熟なジャガイモの苗 +Potato plants are plants which grow on farmland under sunlight in 8 stages, but only 4 stages can be visually told apart. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature.=ジャガイモは、耕地で日光を浴びて育つ植物で、成長が8段階あります。ただし目視で見分けられるのは4段階だけです。湿った耕地では、やや早く成長します。収穫はいつでも可能なものの、益があるのは成熟してからです。 +Premature Potato Plant (Stage @1)=未成熟なジャガイモの苗(@1段階目) +Mature Potato Plant=成熟したジャガイモの苗 +Mature potato plants are ready to be harvested for potatoes. They won't grow any further.=成熟したジャガイモの苗からは、ジャガイモをいくつか収穫できます。これ以上は成長しません。 +Potato=ジャガイモ +Potatoes are food items which can be eaten, cooked in the furnace and planted. Pigs like potatoes.=ジャガイモはそのまま食べるも良し、かまどで焼くも良し。植えるのもいいでしょう。ブタはジャガイモが好きです。 +Hold it in your hand and rightclick to eat it. Place it on top of farmland to plant it. It grows in sunlight and grows faster on hydrated farmland. Rightclick an animal to feed it.=手に持って右クリックすると食べます。耕地に置くとジャガイモを植えます。日光で育ち、湿った耕地では早く育ちます。動物を右クリックすると餌付けできます。 +Baked Potato=ベイクドポテト +Baked potatoes are food items which are more filling than the unbaked ones.=ベイクドポテトは、焼いていないものよりも食べ応えがある食料アイテムです。 +Poisonous Potato=芽吹いたジャガイモ +This potato doesn't look too healthy. You can eat it to restore hunger points, but there's a 60% chance it will poison you briefly.=このジャガイモは、あまり体によくなさそうです。食べると満腹度が多めに回復するものの、短時間の食中毒を引き起こす確率が60%あります。 +Pumpkin Seeds=カボチャの種 +Grows into a pumpkin stem which in turn grows pumpkins. Chickens like pumpkin seeds.=成長するとカボチャの茎になり、そこからカボチャがなります。ニワトリはこの種が好きです。 +Place the pumpkin seeds on farmland (which can be created with a hoe) to plant a pumpkin stem. Pumpkin stems grow in sunlight and grow faster on hydrated farmland. When mature, the stem attempts to grow a pumpkin next to it. Rightclick an animal to feed it pumpkin seeds.=カボチャの種を耕地(クワで作れる)に置いて植え、カボチャの茎にします。茎は日光で育ち、湿った耕地では早く育ちます。成熟すると、茎の隣にカボチャを実らせようとします。動物を右クリックすると、カボチャの種を食べさせることができます。 +Premature Pumpkin Stem=未成熟なカボチャの茎 +Pumpkin stems grow on farmland in 8 stages. On hydrated farmland, the growth is a bit quicker. Mature pumpkin stems are able to grow pumpkins.=カボチャの茎は耕地で育つ植物で、成長が8段階あります。湿った耕地では、やや早く成長します。成熟したカボチャの茎は、カボチャを実らせることができます。 +Premature Pumpkin Stem (Stage @1)=未成熟なカボチャの茎(@1段階目) +Mature Pumpkin Stem=成熟したカボチャの茎 +A mature pumpkin stem attempts to grow a pumpkin at one of its four adjacent blocks. A pumpkin can only grow on top of farmland, dirt or a grass block. When a pumpkin is next to a pumpkin stem, the pumpkin stem immediately bends and connects to the pumpkin. A connected pumpkin stem can't grow another pumpkin. As soon all pumpkins around the stem have been removed, it loses the connection and is ready to grow another pumpkin.=成熟したカボチャの茎は、隣接する4つのブロックのいずれかでカボチャを実らせようとします。実るのは、耕地、土、草原の上だけです。カボチャの茎の隣にカボチャがあると、茎はすぐに曲がってカボチャにつながります。つながっている間は、他のカボチャを実らせられません。茎の周りのカボチャをすべて取り除くと、接続が切れて次のカボチャが実るようになります。 +Faceless Pumpkin=顔のないカボチャ +A faceless pumpkin is a decorative block. It can be carved with shears to obtain pumpkin seeds.=顔のないカボチャは装飾ブロックです。これをハサミで彫ると、カボチャの種が得られます。 +Pumpkin=カボチャ +A pumpkin can be worn as a helmet. Pumpkins grow from pumpkin stems, which in turn grow from pumpkin seeds.=カボチャは、カボチャの種から育つ茎を経て実ります。ハサミで彫るとヘルメットとして被る事もできます。 +Jack o'Lantern=ジャック・オー・ランタン +A jack o'lantern is a traditional Halloween decoration made from a pumpkin. It glows brightly.=ジャック・オー・ランタンとは、カボチャから作られるハロウィンの伝統的な飾りです。明るく光ります。 +Pumpkin Pie=パンプキンパイ +A pumpkin pie is a tasty food item which can be eaten.=パンプキンパイは、美味しくいただける食料アイテムです。 +Farmland=耕地 +Farmland is used for farming, a necessary surface to plant crops. It is created when a hoe is used on dirt or a similar block. Plants are able to grow on farmland, but slowly. Farmland will become hydrated farmland (on which plants grow faster) when it rains or a water source is nearby. This block will turn back to dirt when a solid block appears above it or a piston arm extends above it.=耕地とは農業に使うもので、作物の栽培に必要な地面のことです。土やそれに近いブロックの上でクワを使うとできます。たんなる耕地の上でも植物は育ちますが、そのスピードはゆるやかです。雨が降ったり、水源が近くにあったりすると、耕地は「湿った耕地」となります(植物の成長が早くなります)。上に固体ブロックが現れたり、上にピストンアームが伸びたりすると、このブロックは土に戻ります。 +Hydrated Farmland=湿った耕地 +Hydrated farmland is used in farming, this is where you can plant and grow some plants. It is created when farmland is under rain or near water. Without water, this block will dry out eventually. This block will turn back to dirt when a solid block appears above it or a piston arm extends above it.=湿った耕地は農業に使われるもので、ここに何らかの作物を植えて育てられます。耕地が雨に降られたり水辺にある場合、これが出来上がります。水がなければ、やがて乾いてしまいます。上に固体ブロックが現れたり、上にピストンアームが伸びたりすると、このブロックは土に戻ります。 +Wheat Seeds=小麦の種 +Grows into a wheat plant. Chickens like wheat seeds.=小麦の苗に成長します。ニワトリは小麦の種を好みます。 +Place the wheat seeds on farmland (which can be created with a hoe) to plant a wheat plant. They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it wheat seeds.=小麦の種を耕地(クワで作れる)に置いて植え、小麦の苗にします。日光に当たると成長し、湿った耕地ではより早く成長します。動物を右クリックすると、小麦の種を食べさせることができます。 +Premature Wheat Plant=未成熟な小麦の苗 +Premature wheat plants grow on farmland under sunlight in 8 stages. On hydrated farmland, they grow faster. They can be harvested at any time but will only yield a profit when mature.=小麦は、耕地で日光を浴びて育つ植物で、成長が8段階あります。湿った耕地では、やや早く成長します。収穫はいつでも可能なものの、益があるのは成熟してからです。 +Premature Wheat Plant (Stage @1)=未成熟な小麦の苗(@1段階目) +Mature Wheat Plant=成熟した小麦の苗 +Mature wheat plants are ready to be harvested for wheat and wheat seeds. They won't grow any further.=成熟した小麦の苗からは、小麦をいくつか収穫できます。これ以上は成長しません。 +Wheat=小麦 +Wheat is used in crafting. Some animals like wheat.=小麦はクラフトに使われます。小麦が好きな動物もいます。 +Cookie=クッキー +Bread=パン +Hay Bale=干草の俵 +Hay bales are decorative blocks made from wheat.=干草の俵とは、小麦から作られた装飾ブロックのことです。 +To carve a face into the pumpkin, use the shears on the side you want to carve.=カボチャに顔を彫るには、彫りたい方の面にハサミを使います。 +Use the “Place” key on an animal to try to feed it wheat.=動物に「配置」キーを使って、小麦を与えてみましょう。 +Grows on farmland=耕地に生育 +Turns block into farmland=ブロックを耕地にする +60% chance of poisoning=60%の確率で食あたり +Surface for crops=農作物用地面 +Can become wet=潤いが得られる +Uses: @1=使用:@1 diff --git a/mods/ITEMS/mcl_farming/potatoes.lua b/mods/ITEMS/mcl_farming/potatoes.lua index 04a971de8..50bb66a3b 100644 --- a/mods/ITEMS/mcl_farming/potatoes.lua +++ b/mods/ITEMS/mcl_farming/potatoes.lua @@ -91,18 +91,11 @@ minetest.register_craftitem("mcl_farming:potato_item", { _doc_items_longdesc = S("Potatoes are food items which can be eaten, cooked in the furnace and planted. Pigs like potatoes."), _doc_items_usagehelp = S("Hold it in your hand and rightclick to eat it. Place it on top of farmland to plant it. It grows in sunlight and grows faster on hydrated farmland. Rightclick an animal to feed it."), inventory_image = "farming_potato.png", - groups = {food = 2, eatable = 1, compostability = 65}, + groups = {food = 2, eatable = 1, compostability = 65, smoker_cookable = 1}, _mcl_saturation = 0.6, stack_max = 64, on_secondary_use = minetest.item_eat(1), - on_place = function(itemstack, placer, pointed_thing) - local new = mcl_farming:place_seed(itemstack, placer, pointed_thing, "mcl_farming:potato_1") - if new then - return new - else - return minetest.do_item_eat(1, nil, itemstack, placer, pointed_thing) - end - end, + on_place = mcl_farming:get_seed_or_eat_callback("mcl_farming:potato_1", 1), }) minetest.register_craftitem("mcl_farming:potato_item_baked", { diff --git a/mods/ITEMS/mcl_farming/shared_functions.lua b/mods/ITEMS/mcl_farming/shared_functions.lua index 7b9784503..bbb5cdc20 100644 --- a/mods/ITEMS/mcl_farming/shared_functions.lua +++ b/mods/ITEMS/mcl_farming/shared_functions.lua @@ -69,7 +69,7 @@ function mcl_farming:add_plant(identifier, full_grown, names, interval, chance) interval = interval, chance = chance, action = function(pos, node) - local low_speed = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name ~= "mcl_farming:soil_wet" + local low_speed = minetest.get_node({ x = pos.x, y = pos.y - 1, z = pos.z }).name ~= "mcl_farming:soil_wet" mcl_farming:grow_plant(identifier, pos, node, false, false, low_speed) end, }) @@ -130,7 +130,7 @@ function mcl_farming:grow_plant(identifier, pos, node, stages, ignore_light, low stages = 1 end stages = stages + math.ceil(intervals_counter) - local new_node = {name = plant_info.names[step+stages]} + local new_node = { name = plant_info.names[step + stages] } if new_node.name == nil then new_node.name = plant_info.full_grown end @@ -157,14 +157,14 @@ function mcl_farming:place_seed(itemstack, placer, pointed_thing, plantname) end end - local pos = {x=pt.above.x, y=pt.above.y-1, z=pt.above.z} + local pos = { x = pt.above.x, y = pt.above.y - 1, z = pt.above.z } local farmland = minetest.get_node(pos) - pos= {x=pt.above.x, y=pt.above.y, z=pt.above.z} + pos = { x = pt.above.x, y = pt.above.y, z = pt.above.z } local place_s = minetest.get_node(pos) - if string.find(farmland.name, "mcl_farming:soil") and string.find(place_s.name, "air") then - minetest.sound_play(minetest.registered_nodes[plantname].sounds.place, {pos = pos}, true) - minetest.add_node(pos, {name=plantname, param2 = minetest.registered_nodes[plantname].place_param2}) + if string.find(farmland.name, "mcl_farming:soil") and string.find(place_s.name, "air") then + minetest.sound_play(minetest.registered_nodes[plantname].sounds.place, { pos = pos }, true) + minetest.add_node(pos, { name = plantname, param2 = minetest.registered_nodes[plantname].place_param2 }) --local intervals_counter = get_intervals_counter(pos, 1, 1) else return @@ -179,7 +179,7 @@ end --[[ Helper function to create a gourd (e.g. melon, pumpkin), the connected stem nodes as -- full_unconnected_stem: itemstring of the full-grown but unconnceted stem node. This node must already be done +- full_unconnected_stem: itemstring of the full-grown but unconnected stem node. This node must already be done - connected_stem_basename: prefix of the itemstrings used for the 4 connected stem nodes to create - stem_itemstring: Desired itemstring of the fully-grown unconnected stem node - stem_def: Partial node definition of the fully-grown unconnected stem node. Many fields are already defined. You need to add `tiles` and `description` at minimum. Don't define on_construct without good reason @@ -202,10 +202,10 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s } local neighbors = { - { x=-1, y=0, z=0 }, - { x=1, y=0, z=0 }, - { x=0, y=0, z=-1 }, - { x=0, y=0, z=1 }, + { x = -1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + { x = 0, y = 0, z = -1 }, + { x = 0, y = 0, z = 1 }, } -- Connect the stem at stempos to the first neighboring gourd block. @@ -215,19 +215,19 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s if stem.name ~= full_unconnected_stem then return false end - for n=1, #neighbors do + for n = 1, #neighbors do local offset = neighbors[n] local blockpos = vector.add(stempos, offset) local block = minetest.get_node(blockpos) if block.name == gourd_itemstring then if offset.x == 1 then - minetest.set_node(stempos, {name=connected_stem_names[1]}) + minetest.set_node(stempos, { name = connected_stem_names[1] }) elseif offset.x == -1 then - minetest.set_node(stempos, {name=connected_stem_names[2]}) + minetest.set_node(stempos, { name = connected_stem_names[2] }) elseif offset.z == 1 then - minetest.set_node(stempos, {name=connected_stem_names[3]}) + minetest.set_node(stempos, { name = connected_stem_names[3] }) elseif offset.z == -1 then - minetest.set_node(stempos, {name=connected_stem_names[4]}) + minetest.set_node(stempos, { name = connected_stem_names[4] }) end return true end @@ -238,13 +238,13 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s if not gourd_def.after_destruct then gourd_def.after_destruct = function(blockpos, oldnode) -- Disconnect any connected stems, turning them back to normal stems - for n=1, #neighbors do + for n = 1, #neighbors do local offset = neighbors[n] local expected_stem = connected_stem_names[n] local stempos = vector.add(blockpos, offset) local stem = minetest.get_node(stempos) if stem.name == expected_stem then - minetest.add_node(stempos, {name=full_unconnected_stem}) + minetest.add_node(stempos, { name = full_unconnected_stem }) try_connect_stem(stempos) end end @@ -253,7 +253,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s if not gourd_def.on_construct then function gourd_def.on_construct(blockpos) -- Connect all unconnected stems at full size - for n=1, #neighbors do + for n = 1, #neighbors do local stempos = vector.add(blockpos, neighbors[n]) try_connect_stem(stempos) end @@ -272,7 +272,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s stem_def.selection_box = { type = "fixed", fixed = { - {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15} + { -0.15, -0.5, -0.15, 0.15, 0.5, 0.15 } }, } end @@ -292,7 +292,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s stem_def.drop = stem_drop end if stem_def.groups == nil then - stem_def.groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,} + stem_def.groups = { dig_immediate = 3, not_in_creative_inventory = 1, plant = 1, attached_node = 1, dig_by_water = 1, destroy_by_lava_flow = 1, } end if stem_def.sounds == nil then stem_def.sounds = mcl_sounds.node_sound_leaves_defaults() @@ -310,48 +310,48 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s local connected_stem_tiles = { { "blank.png", --top - "blank.png", -- bottom - "blank.png", -- right - "blank.png", -- left - connected_stem_texture, -- back - connected_stem_texture.."^[transformFX90" --front + "blank.png", -- bottom + "blank.png", -- right + "blank.png", -- left + connected_stem_texture, -- back + connected_stem_texture .. "^[transformFX90" --front }, { "blank.png", --top - "blank.png", -- bottom - "blank.png", -- right - "blank.png", -- left - connected_stem_texture.."^[transformFX90", --back - connected_stem_texture, -- front + "blank.png", -- bottom + "blank.png", -- right + "blank.png", -- left + connected_stem_texture .. "^[transformFX90", --back + connected_stem_texture, -- front }, { "blank.png", --top - "blank.png", -- bottom - connected_stem_texture.."^[transformFX90", -- right - connected_stem_texture, -- left - "blank.png", --back - "blank.png", -- front + "blank.png", -- bottom + connected_stem_texture .. "^[transformFX90", -- right + connected_stem_texture, -- left + "blank.png", --back + "blank.png", -- front }, { "blank.png", --top - "blank.png", -- bottom - connected_stem_texture, -- right - connected_stem_texture.."^[transformFX90", -- left - "blank.png", --back - "blank.png", -- front + "blank.png", -- bottom + connected_stem_texture, -- right + connected_stem_texture .. "^[transformFX90", -- left + "blank.png", --back + "blank.png", -- front } } local connected_stem_nodebox = { - {-0.5, -0.5, 0, 0.5, 0.5, 0}, - {-0.5, -0.5, 0, 0.5, 0.5, 0}, - {0, -0.5, -0.5, 0, 0.5, 0.5}, - {0, -0.5, -0.5, 0, 0.5, 0.5}, + { -0.5, -0.5, 0, 0.5, 0.5, 0 }, + { -0.5, -0.5, 0, 0.5, 0.5, 0 }, + { 0, -0.5, -0.5, 0, 0.5, 0.5 }, + { 0, -0.5, -0.5, 0, 0.5, 0.5 }, } local connected_stem_selectionbox = { - {-0.1, -0.5, -0.1, 0.5, 0.2, 0.1}, - {-0.5, -0.5, -0.1, 0.1, 0.2, 0.1}, - {-0.1, -0.5, -0.1, 0.1, 0.2, 0.5}, - {-0.1, -0.5, -0.5, 0.1, 0.2, 0.1}, + { -0.1, -0.5, -0.1, 0.5, 0.2, 0.1 }, + { -0.5, -0.5, -0.1, 0.1, 0.2, 0.1 }, + { -0.1, -0.5, -0.1, 0.1, 0.2, 0.5 }, + { -0.1, -0.5, -0.5, 0.1, 0.2, 0.1 }, } - for i=1, 4 do + for i = 1, 4 do minetest.register_node(connected_stem_names[i], { _doc_items_create_entry = false, paramtype = "light", @@ -369,7 +369,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s }, tiles = connected_stem_tiles[i], use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, - groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,}, + groups = { dig_immediate = 3, not_in_creative_inventory = 1, plant = 1, attached_node = 1, dig_by_water = 1, destroy_by_lava_flow = 1, }, sounds = mcl_sounds.node_sound_leaves_defaults(), _mcl_blast_resistance = 0, }) @@ -380,9 +380,9 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s end minetest.register_abm({ - label = "Grow gourd stem to gourd ("..full_unconnected_stem.." → "..gourd_itemstring..")", - nodenames = {full_unconnected_stem}, - neighbors = {"air"}, + label = "Grow gourd stem to gourd (" .. full_unconnected_stem .. " → " .. gourd_itemstring .. ")", + nodenames = { full_unconnected_stem }, + neighbors = { "air" }, interval = grow_interval, chance = grow_chance, action = function(stempos) @@ -390,20 +390,20 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s if light and light > 10 then -- Check the four neighbors and filter out neighbors where gourds can't grow local neighbors = { - { x=-1, y=0, z=0 }, - { x=1, y=0, z=0 }, - { x=0, y=0, z=-1 }, - { x=0, y=0, z=1 }, + { x = -1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + { x = 0, y = 0, z = -1 }, + { x = 0, y = 0, z = 1 }, } local floorpos, floor - for n=#neighbors, 1, -1 do + for n = #neighbors, 1, -1 do local offset = neighbors[n] local blockpos = vector.add(stempos, offset) - floorpos = { x=blockpos.x, y=blockpos.y-1, z=blockpos.z } + floorpos = vector.offset (blockpos, 0, -1,0) -- replaces { x = blockpos.x, y = blockpos.y - 1, z = blockpos.z } floor = minetest.get_node(floorpos) local block = minetest.get_node(blockpos) local soilgroup = minetest.get_item_group(floor.name, "soil") - if not ((minetest.get_item_group(floor.name, "grass_block") == 1 or floor.name=="mcl_core:dirt" or soilgroup == 2 or soilgroup == 3) and block.name == "air") then + if not ((minetest.get_item_group(floor.name, "grass_block") == 1 or floor.name == "mcl_core:dirt" or soilgroup == 2 or soilgroup == 3) and block.name == "air") then table.remove(neighbors, n) end end @@ -416,27 +416,35 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s local blockpos = vector.add(stempos, offset) local p2 if offset.x == 1 then - minetest.set_node(stempos, {name=connected_stem_names[1]}) + minetest.set_node(stempos, { name = connected_stem_names[1] }) p2 = 3 elseif offset.x == -1 then - minetest.set_node(stempos, {name=connected_stem_names[2]}) + minetest.set_node(stempos, { name = connected_stem_names[2] }) p2 = 1 elseif offset.z == 1 then - minetest.set_node(stempos, {name=connected_stem_names[3]}) + minetest.set_node(stempos, { name = connected_stem_names[3] }) p2 = 2 elseif offset.z == -1 then - minetest.set_node(stempos, {name=connected_stem_names[4]}) + minetest.set_node(stempos, { name = connected_stem_names[4] }) p2 = 0 end -- Place the gourd if gourd_def.paramtype2 == "facedir" then - minetest.add_node(blockpos, {name=gourd_itemstring, param2=p2}) + minetest.add_node(blockpos, { name = gourd_itemstring, param2 = p2 }) else - minetest.add_node(blockpos, {name=gourd_itemstring}) + minetest.add_node(blockpos, { name = gourd_itemstring }) end + -- Reset farmland, etc. to dirt when the gourd grows on top + + -- FIXED: The following 2 lines were missing, and wasn't being set (outside of the above loop that + -- finds the neighbors.) + -- FYI - don't factor this out thinking that the loop above is setting the positions correctly. + floorpos = vector.offset (blockpos, 0, -1,0) -- replaces { x = blockpos.x, y = blockpos.y - 1, z = blockpos.z } + floor = minetest.get_node(floorpos) + -- END OF FIX ------------------------------------- if minetest.get_item_group(floor.name, "dirtifies_below_solid") == 1 then - minetest.set_node(floorpos, {name = "mcl_core:dirt"}) + minetest.set_node(floorpos, { name = "mcl_core:dirt" }) end end end @@ -452,7 +460,7 @@ end function mcl_farming:stem_color(startcolor, endcolor, step, step_count) local color = {} local function get_component(startt, endd, step, step_count) - return math.floor(math.max(0, math.min(255, (startt + (((step-1)/step_count) * endd))))) + return math.floor(math.max(0, math.min(255, (startt + (((step - 1) / step_count) * endd))))) end color.r = get_component(startcolor.r, endcolor.r, step, step_count) color.g = get_component(startcolor.g, endcolor.g, step, step_count) @@ -461,17 +469,32 @@ function mcl_farming:stem_color(startcolor, endcolor, step, step_count) return colorstring end +--[[Get a callback that either eats the item or plants it. + +Used for on_place callbacks for craft items which are seeds that can also be consumed. +]] +function mcl_farming:get_seed_or_eat_callback(plantname, hp_change) + return function(itemstack, placer, pointed_thing) + local new = mcl_farming:place_seed(itemstack, placer, pointed_thing, plantname) + if new then + return new + else + return minetest.do_item_eat(hp_change, nil, itemstack, placer, pointed_thing) + end + end +end + minetest.register_lbm({ label = "Add growth for unloaded farming plants", name = "mcl_farming:growth", - nodenames = {"group:plant"}, + nodenames = { "group:plant" }, run_at_every_load = true, action = function(pos, node) local identifier = plant_nodename_to_id_list[node.name] if not identifier then return end - local low_speed = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name ~= "mcl_farming:soil_wet" + local low_speed = minetest.get_node({ x = pos.x, y = pos.y - 1, z = pos.z }).name ~= "mcl_farming:soil_wet" mcl_farming:grow_plant(identifier, pos, node, false, false, low_speed) end, }) diff --git a/mods/ITEMS/mcl_farming/soil.lua b/mods/ITEMS/mcl_farming/soil.lua index 8b31d888f..a6721cc26 100644 --- a/mods/ITEMS/mcl_farming/soil.lua +++ b/mods/ITEMS/mcl_farming/soil.lua @@ -21,7 +21,7 @@ minetest.register_node("mcl_farming:soil", { end, groups = {handy=1,shovely=1, dirtifies_below_solid=1, dirtifier=1, soil=2, soil_sapling=1, deco_block=1 }, sounds = mcl_sounds.node_sound_dirt_defaults(), - _mcl_blast_resistance = 0.5, + _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, }) diff --git a/mods/ITEMS/mcl_farming/sweet_berry.lua b/mods/ITEMS/mcl_farming/sweet_berry.lua new file mode 100644 index 000000000..8a91c0e79 --- /dev/null +++ b/mods/ITEMS/mcl_farming/sweet_berry.lua @@ -0,0 +1,128 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local planton = {"mcl_core:dirt_with_grass", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:coarse_dirt", "mcl_farming:soil", "mcl_farming:soil_wet", "mcl_moss:moss"} + +for i=0, 3 do + local texture = "mcl_farming_sweet_berry_bush_" .. i .. ".png" + local node_name = "mcl_farming:sweet_berry_bush_" .. i + local groups = {sweet_berry=1, dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1, flammable=3, fire_encouragement=60, fire_flammability=20, compostability=30} + if i > 0 then + groups.sweet_berry_thorny = 1 + end + local drop_berries = (i >= 2) + local berries_to_drop = drop_berries and {i - 1, i} or nil + + minetest.register_node(node_name, { + drawtype = "plantlike", + tiles = {texture}, + description = S("Sweet Berry Bush (Stage @1)", i), + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "meshoptions", + place_param2 = 3, + liquid_viscosity = 15, + liquidtype = "source", + liquid_alternative_flowing = node_name, + liquid_alternative_source = node_name, + liquid_renewable = false, + liquid_range = 0, + walkable = false, + -- Dont even create a table if no berries are dropped. + drop = not drop_berries and "" or { + max_items = 1, + items = { + { items = {"mcl_farming:sweet_berry " .. berries_to_drop[1] }, rarity = 2 }, + { items = {"mcl_farming:sweet_berry " .. berries_to_drop[2] } } + } + }, + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, (-0.30 + (i*0.25)), 6 / 16}, + }, + inventory_image = texture, + wield_image = texture, + groups = groups, + sounds = mcl_sounds.node_sound_leaves_defaults(), + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local pn = clicker:get_player_name() + if clicker:is_player() and minetest.is_protected(pos, pn) then + minetest.record_protection_violation(pos, pn) + return itemstack + end + if 3 ~= i and mcl_dye and + clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + mcl_dye.apply_bone_meal({under=pos},clicker) + if not minetest.is_creative_enabled(pn) then + itemstack:take_item() + end + return + end + + if drop_berries then + for j=1, berries_to_drop[math.random(2)] do + minetest.add_item(pos, "mcl_farming:sweet_berry") + end + minetest.swap_node(pos, {name = "mcl_farming:sweet_berry_bush_1"}) + end + return itemstack + end, + }) + minetest.register_alias("mcl_sweet_berry:sweet_berry_bush_" .. i, node_name) +end + +minetest.register_craftitem("mcl_farming:sweet_berry", { + description = S("Sweet Berry"), + inventory_image = "mcl_farming_sweet_berry.png", + _mcl_saturation = 0.4, + groups = { food = 2, eatable = 1, compostability=30 }, + on_secondary_use = minetest.item_eat(1), + on_place = function(itemstack, placer, pointed_thing) + local pn = placer:get_player_name() + if placer:is_player() and minetest.is_protected(pointed_thing.above, pn or "") then + minetest.record_protection_violation(pointed_thing.above, pn) + return itemstack + end + if pointed_thing.type == "node" and + table.indexof(planton, minetest.get_node(pointed_thing.under).name) ~= -1 and + pointed_thing.above.y > pointed_thing.under.y and + minetest.get_node(pointed_thing.above).name == "air" then + minetest.set_node(pointed_thing.above, {name="mcl_farming:sweet_berry_bush_0"}) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + return itemstack + end + return minetest.do_item_eat(1, nil, itemstack, placer, pointed_thing) + end, +}) +minetest.register_alias("mcl_sweet_berry:sweet_berry", "mcl_farming:sweet_berry") + +-- TODO: Find proper interval and chance values for sweet berry bushes. Current interval and chance values are copied from mcl_farming:beetroot which has similar growth stages. +mcl_farming:add_plant("plant_sweet_berry_bush", "mcl_farming:sweet_berry_bush_3", {"mcl_farming:sweet_berry_bush_0", "mcl_farming:sweet_berry_bush_1", "mcl_farming:sweet_berry_bush_2"}, 68, 3) + +local function berry_damage_check(obj) + local p = obj:get_pos() + if not p then return end + if not minetest.find_node_near(p,0.4,{"group:sweet_berry_thorny"},true) then return end + local v = obj:get_velocity() + if v.x < 0.1 and v.y < 0.1 and v.z < 0.1 then return end + + mcl_util.deal_damage(obj, 0.5, {type = "sweet_berry"}) +end + +local etime = 0 +minetest.register_globalstep(function(dtime) + etime = dtime + etime + if etime < 0.5 then return end + etime = 0 + for _,pl in pairs(minetest.get_connected_players()) do + berry_damage_check(pl) + end + for _,ent in pairs(minetest.luaentities) do + if ent.is_mob then + berry_damage_check(ent.object) + end + end +end) diff --git a/mods/ITEMS/mcl_farming/textures/farming_tool_netheritehoe.png b/mods/ITEMS/mcl_farming/textures/farming_tool_netheritehoe.png new file mode 100644 index 000000000..f6acbbff3 Binary files /dev/null and b/mods/ITEMS/mcl_farming/textures/farming_tool_netheritehoe.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry.png new file mode 100644 index 000000000..7c2349971 Binary files /dev/null and b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_0.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_0.png new file mode 100644 index 000000000..6f8c0d833 Binary files /dev/null and b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_0.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_1.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_1.png new file mode 100644 index 000000000..2ac3c205d Binary files /dev/null and b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_1.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_2.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_2.png new file mode 100644 index 000000000..5e9a6dd14 Binary files /dev/null and b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_2.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_3.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_3.png new file mode 100644 index 000000000..a473882f4 Binary files /dev/null and b/mods/ITEMS/mcl_farming/textures/mcl_farming_sweet_berry_bush_3.png differ diff --git a/mods/ITEMS/mcl_farming/wheat.lua b/mods/ITEMS/mcl_farming/wheat.lua index a254ed36c..44d82b566 100644 --- a/mods/ITEMS/mcl_farming/wheat.lua +++ b/mods/ITEMS/mcl_farming/wheat.lua @@ -117,7 +117,7 @@ minetest.register_craft({ minetest.register_craft({ output = "mcl_farming:cookie 8", recipe = { - {"mcl_farming:wheat_item", "mcl_dye:brown", "mcl_farming:wheat_item"}, + {"mcl_farming:wheat_item", "mcl_cocoas:cocoa_beans", "mcl_farming:wheat_item"}, } }) diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.ja.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.ja.tr new file mode 100644 index 000000000..80eaadaa5 --- /dev/null +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.ja.tr @@ -0,0 +1,18 @@ +# textdomain: mcl_fences +Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=フェンスは道を塞ぐ構造物です。他のフェンスや固体ブロックに隣接すると繋がります。単なるジャンプでは飛び越えられません。 +Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=フェンスゲートは開閉ができ、飛び越えることはできません。フェンスとフェンスゲートはキレイに繋がります。 +Right-click the fence gate to open or close it.=右クリックで、フェンスゲートを開閉できます。 +Oak Fence=オークのフェンス +Oak Fence Gate=オークのフェンスゲート +Spruce Fence=トウヒのフェンス +Spruce Fence Gate=トウヒのフェンスゲート +Birch Fence=シラカバのフェンス +Birch Fence Gate=シラカバのフェンスゲート +Jungle Fence=ジャングルのフェンス +Jungle Fence Gate=ジャングルのフェンスゲート +Dark Oak Fence=ダークオークのフェンス +Dark Oak Fence Gate=ダークオークのフェンスゲート +Acacia Fence=アカシアのフェンス +Acacia Fence Gate=アカシアのフェンスゲート +Nether Brick Fence=ネザーレンガのフェンス +Openable by players and redstone power=プレイヤーとレッドストーン動力によって開放可能 diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index 79b46a701..8827b9f9a 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -378,9 +378,9 @@ else -- Fire enabled minetest.register_abm({ label = "Ignite fire by lava", nodenames = {"mcl_core:lava_source","mcl_nether:nether_lava_source"}, - neighbors = {"air","group:flammable"}, - interval = 7, - chance = 3, + neighbors = {"group:flammable"}, + interval = 15, + chance = 9, catch_up = false, action = function(pos) local p=get_ignitable_by_lava(pos) diff --git a/mods/ITEMS/mcl_fire/locale/mcl_fire.ja.tr b/mods/ITEMS/mcl_fire/locale/mcl_fire.ja.tr new file mode 100644 index 000000000..5f8964b1b --- /dev/null +++ b/mods/ITEMS/mcl_fire/locale/mcl_fire.ja.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_fire +Fire Charge=発火弾 +Fire charges are primarily projectiles which can be launched from dispensers, they will fly in a straight line and burst into a fire on impact. Alternatively, they can be used to ignite fires directly.=発火弾は、主に発射体としてディスペンサーから射出するもので、一直線に飛んでいき着弾した場所に火を着けます。あるいは、直接火を着けるのに使うこともできます。 +Put the fire charge into a dispenser and supply it with redstone power to launch it. To ignite a fire directly, simply place the fire charge on the ground, which uses it up.=発火弾をディスペンサーに入れ、レッドストーン動力を供給すると発射されます。直接火を着けるには、シンプルに発火弾を地面に置くだけです。なお、使い切りです。 +Flint and Steel=火打石と打ち金 +Flint and steel is a tool to start fires and ignite blocks.=火打石と打ち金は、火をおこしたり、ブロックに着火するための道具です。 +Rightclick the surface of a block to attempt to light a fire in front of it or ignite the block. A few blocks have an unique reaction when ignited.=ブロックの表面で右クリックすると、ブロックの前で火をつけたり、ブロックへの着火を試みます。いくつかのブロックは、着火すると独特の反応をします。 +Fire is a damaging and destructive but short-lived kind of block. It will destroy and spread towards near flammable blocks, but fire will disappear when there is nothing to burn left. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=炎はダメージが大きく破壊力がありますが、寿命の短いブロックの一種です。近くの燃えやすいブロックを破壊しながら広がりますが、燃えるものがなくなると消えます。近くの水や雨でも消えます。炎はパンチで安全に破壊できますが、直接その中に立つと酷い目にあいます。ネザーラックやマグマブロックの上で火を起こすと、すぐに永続的な炎になります。 +Fire is a damaging but non-destructive short-lived kind of block. It will disappear when there is no flammable block around. Fire does not destroy blocks, at least not in this world. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=炎は、ダメージを与えるが破壊されない短命のブロックの一種です。周りに可燃性ブロックがないと消えてしまいます。少なくともこの世界では、炎はブロックを破壊しません。近くの水や雨で消えます。炎はパンチで安全に破壊できますが、直接その中に立つと酷い目にあいます。ネザーラックやマグマブロックの上で火を起こすと、すぐに永続的な炎になります。 +Eternal fire is a damaging block that might create more fire. It will create fire around it when flammable blocks are nearby. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=永続的な炎は、より多くの炎を生み出す可能性のあるダメージブロックです。可燃性ブロックが近くにあると、その周囲に炎が発生します。永続的な炎は、パンチや近くの水ブロックによって消せます。(通常の)炎以外の永続的な炎は、それ自体では消えず、雨の下でも燃え続けます。永続的な炎をパンチするのは安全ですが、中に立つと痛いです。 +Eternal fire is a damaging block. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=永続的な炎はダメージを与えるブロックです。パンチや近くの水ブロックによって消せます。(通常の)炎以外の永続的な炎は、それ自体では消えず、雨の下でも燃え続けます。永続的な炎をパンチするのは安全ですが、中に立つと痛いです。 +@1 has been cooked crisp.=@1はカリッと焼けた。 +@1 felt the burn.=@1は火傷を感じた。 +@1 died in the flames.=@1は炎の中で死亡した。 +@1 died in a fire.=@1は火災で死亡した。 +Fire=炎 +Eternal Fire=永続的な炎 +Dispenser projectile=ディスペンサーの発射体 +Starts fires and ignites blocks=火起こしやブロックへの着火 diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ja.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ja.tr new file mode 100644 index 000000000..cd6da01c4 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket=ロケット花火 +Flight Duration:=飛行時間: \ No newline at end of file diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index 1d8f24fb3..b543b8d99 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -75,6 +75,7 @@ local fish = function(itemstack, player, pointed_thing) stacks_min = 1, stacks_max = 1, }, pr) + awards.unlock(player:get_player_name(), "mcl:fishyBusiness") elseif r <= junk_value then -- Junk items = mcl_loot.get_loot({ @@ -88,7 +89,7 @@ local fish = function(itemstack, player, pointed_thing) { itemstring = "mcl_mobitems:string", weight = 5 }, { itemstring = "mcl_potions:water", weight = 10 }, { itemstring = "mcl_mobitems:bone", weight = 10 }, - { itemstring = "mcl_dye:black", weight = 1, amount_min = 10, amount_max = 10 }, + { itemstring = "mcl_mobitems:ink_sac", weight = 1, amount_min = 10, amount_max = 10 }, { itemstring = "mcl_mobitems:string", weight = 10 }, -- TODO: Tripwire Hook }, stacks_min = 1, @@ -110,6 +111,7 @@ local fish = function(itemstack, player, pointed_thing) { itemstring = "mcl_mobs:nametag", }, { itemstring = "mcl_mobitems:saddle", }, { itemstring = "mcl_flowers:waterlily", }, + { itemstring = "mcl_mobitems:nautilus_shell", }, }, stacks_min = 1, stacks_max = 1, @@ -124,6 +126,9 @@ local fish = function(itemstack, player, pointed_thing) local inv = player:get_inventory() if inv:room_for_item("main", item) then inv:add_item("main", item) + if item:get_name() == "mcl_mobitems:leather" then + awards.unlock(player:get_player_name(), "mcl:killCow") + end else minetest.add_item(pos, item) end @@ -385,7 +390,7 @@ minetest.register_tool("mcl_fishing:fishing_rod", { _doc_items_usagehelp = S("Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?"), groups = { tool=1, fishing_rod=1, enchantability=1 }, inventory_image = "mcl_fishing_fishing_rod.png", - wield_image = "mcl_fishing_fishing_rod.png^[transformR270", + wield_image = "mcl_fishing_fishing_rod.png^[transformFY^[transformR90", wield_scale = { x = 1.5, y = 1.5, z = 1 }, stack_max = 1, on_place = fish, diff --git a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ja.tr b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ja.tr new file mode 100644 index 000000000..d68a8ab96 --- /dev/null +++ b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ja.tr @@ -0,0 +1,18 @@ +# textdomain: mcl_fishing +Fishing Rod=釣竿 +Fishing rods can be used to catch fish.=釣竿で魚が釣れます。 +Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?=右クリックで釣り糸を飛ばします。沈んだらまた右クリックで巻き上げ。何が釣れるかはお楽しみ。 +Raw Fish=生鱈 +Raw fish is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=生のタラは釣りで得られ、安全に食べられる食材です。調理することで栄養価がアップします。 +Cooked Fish=焼き鱈 +Mmh, fish! This is a healthy food item.=ん~、サカナ! これはヘルシーな食材ですね。 +Raw Salmon=生鮭 +Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=生のサケは釣りで得られ、安全に食べられる食材です。調理することで栄養価がアップします。 +Cooked Salmon=焼き鮭 +This is a healthy food item which can be eaten.=これは食べられるヘルシーな食材です。 +Clownfish=クマノミ +Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=クマノミは釣り(と運)で手に入れることができ、安全に食べられる食材です。 +Pufferfish=フグ +Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=フグは一般的な魚の一種で、釣りでゲットできます。技術的には食べることができますが、人間にとっては最悪のものです。フグを食べると空腹感が1ポイントしか回復せず、過酷な毒(死なない程度にヘルスを消耗)と、深刻な食中毒(空腹感の増加)を引き起こすことになります。 +Catches fish in water=水中の魚を捕獲 +Very poisonous=猛毒 diff --git a/mods/ITEMS/mcl_fishing/mod.conf b/mods/ITEMS/mcl_fishing/mod.conf index c4e5f5f2e..71bde6146 100644 --- a/mods/ITEMS/mcl_fishing/mod.conf +++ b/mods/ITEMS/mcl_fishing/mod.conf @@ -1,3 +1,3 @@ name = mcl_fishing description = Adds fish and fishing poles to go fishing. -depends = mcl_core, mcl_sounds, mcl_loot, mcl_mobs, mcl_enchanting, mcl_throwing, mcl_colors +depends = mcl_core, mcl_sounds, mcl_loot, mcl_mobs, mcl_enchanting, mcl_throwing, mcl_colors, mcl_buckets diff --git a/mods/ITEMS/mcl_fishing/textures/cod_bucket.png b/mods/ITEMS/mcl_fishing/textures/cod_bucket.png new file mode 100644 index 000000000..582207cb0 Binary files /dev/null and b/mods/ITEMS/mcl_fishing/textures/cod_bucket.png differ diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png b/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png index 2fbcc7344..564188f7e 100644 Binary files a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png and b/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png differ diff --git a/mods/ITEMS/mcl_fishing/textures/pufferfish_bucket.png b/mods/ITEMS/mcl_fishing/textures/pufferfish_bucket.png new file mode 100644 index 000000000..2c88bac35 Binary files /dev/null and b/mods/ITEMS/mcl_fishing/textures/pufferfish_bucket.png differ diff --git a/mods/ITEMS/mcl_fishing/textures/salmon_bucket.png b/mods/ITEMS/mcl_fishing/textures/salmon_bucket.png new file mode 100644 index 000000000..b9ac22fd9 Binary files /dev/null and b/mods/ITEMS/mcl_fishing/textures/salmon_bucket.png differ diff --git a/mods/ITEMS/mcl_fishing/textures/tropical_fish_bucket.png b/mods/ITEMS/mcl_fishing/textures/tropical_fish_bucket.png new file mode 100644 index 000000000..edf7dd244 Binary files /dev/null and b/mods/ITEMS/mcl_fishing/textures/tropical_fish_bucket.png differ diff --git a/mods/ITEMS/mcl_fletching_table/README.md b/mods/ITEMS/mcl_fletching_table/README.md index af0b88185..a30e2c1b4 100644 --- a/mods/ITEMS/mcl_fletching_table/README.md +++ b/mods/ITEMS/mcl_fletching_table/README.md @@ -10,4 +10,10 @@ LGPLv2.1 License of media ---------------- -See the main MineClone 2 README.md file. \ No newline at end of file + +fletching_table_bottom.png +fletching_table_front.png +fletching_table_side.png +fletching_table_top.png +License: CC BY-SA 4.0 +Author: MrRar diff --git a/mods/ITEMS/mcl_fletching_table/init.lua b/mods/ITEMS/mcl_fletching_table/init.lua index 88763b218..686a1dc2c 100644 --- a/mods/ITEMS/mcl_fletching_table/init.lua +++ b/mods/ITEMS/mcl_fletching_table/init.lua @@ -5,12 +5,14 @@ minetest.register_node("mcl_fletching_table:fletching_table", { _tt_help = S("A fletching table"), _doc_items_longdesc = S("This is the fletcher villager's work station. It currently has no use beyond decoration."), tiles = { - "fletching_table_top.png", "fletching_table_top.png", - "fletching_table_side.png", "fletching_table_side.png", - "fletching_table_front.png", "fletching_table_front.png" + "fletching_table_top.png", "fletching_table_bottom.png", + "fletching_table_front.png", "fletching_table_front.png", + "fletching_table_side.png", "fletching_table_side.png" }, paramtype2 = "facedir", - groups = {choppy=1, deco_block=1, material_wood=1, flammable=1} + groups = { axey = 2, handy = 1, deco_block = 1, material_wood = 1, flammable = 1 }, + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5 }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.fr.tr b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.fr.tr new file mode 100644 index 000000000..cea6ab417 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_fletching_table +Fletching Table=Table d'Archerie +A fletching table=une table d'archerie +This is the fletcher villager's work station. It currently has no use beyond decoration.=Ceci est le poste de travail du villageois fléchier. Il n'a actuellement aucune autre utilité que la décoration. \ No newline at end of file diff --git a/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ja.tr b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ja.tr new file mode 100644 index 000000000..ecf8dd8d4 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_fletching_table +Fletching Table=矢細工台 +A fletching table=矢細工台 +This is the fletcher villager's work station. It currently has no use beyond decoration.=これは矢師の村人たちの職場です。現在、装飾以上の用途はありません。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_fletching_table/locale/template.txt b/mods/ITEMS/mcl_fletching_table/locale/template.txt new file mode 100644 index 000000000..b42ea2578 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: mcl_fletching_table +Fletching Table= +A fletching table= +This is the fletcher villager's work station. It currently has no use beyond decoration.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_fletching_table/textures/fletching_table_bottom.png b/mods/ITEMS/mcl_fletching_table/textures/fletching_table_bottom.png new file mode 100644 index 000000000..5c1289766 Binary files /dev/null and b/mods/ITEMS/mcl_fletching_table/textures/fletching_table_bottom.png differ diff --git a/mods/ITEMS/mcl_fletching_table/textures/fletching_table_front.png b/mods/ITEMS/mcl_fletching_table/textures/fletching_table_front.png index da2eb3519..091389e26 100644 Binary files a/mods/ITEMS/mcl_fletching_table/textures/fletching_table_front.png and b/mods/ITEMS/mcl_fletching_table/textures/fletching_table_front.png differ diff --git a/mods/ITEMS/mcl_fletching_table/textures/fletching_table_side.png b/mods/ITEMS/mcl_fletching_table/textures/fletching_table_side.png index c79454afe..33ff2842f 100644 Binary files a/mods/ITEMS/mcl_fletching_table/textures/fletching_table_side.png and b/mods/ITEMS/mcl_fletching_table/textures/fletching_table_side.png differ diff --git a/mods/ITEMS/mcl_fletching_table/textures/fletching_table_top.png b/mods/ITEMS/mcl_fletching_table/textures/fletching_table_top.png index 0ecead696..e6088e7d2 100644 Binary files a/mods/ITEMS/mcl_fletching_table/textures/fletching_table_top.png and b/mods/ITEMS/mcl_fletching_table/textures/fletching_table_top.png differ diff --git a/mods/ITEMS/mcl_flowerpots/init.lua b/mods/ITEMS/mcl_flowerpots/init.lua index 578553b31..4d45e6ffd 100644 --- a/mods/ITEMS/mcl_flowerpots/init.lua +++ b/mods/ITEMS/mcl_flowerpots/init.lua @@ -2,8 +2,18 @@ local S = minetest.get_translator(minetest.get_current_modname()) local has_doc = minetest.get_modpath("doc") mcl_flowerpots = {} + +---@type table mcl_flowerpots.registered_pots = {} +---@type nodebox +local pot_box = { + type = "fixed", + fixed = { + { -0.1875, -0.5, -0.1875, 0.1875, -0.125, 0.1875 }, + }, +} + minetest.register_node("mcl_flowerpots:flower_pot", { description = S("Flower Pot"), _tt_help = S("Can hold a small flower or plant"), @@ -14,23 +24,16 @@ minetest.register_node("mcl_flowerpots:flower_pot", { tiles = { "mcl_flowerpots_flowerpot.png", }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + use_texture_alpha = "clip", visual_scale = 0.5, wield_image = "mcl_flowerpots_flowerpot_inventory.png", - wield_scale = {x=1.0, y=1.0, z=1.0}, paramtype = "light", sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - collision_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, + selection_box = pot_box, + collision_box = pot_box, is_ground_content = false, inventory_image = "mcl_flowerpots_flowerpot_inventory.png", - groups = {dig_immediate=3, deco_block=1, attached_node=1, dig_by_piston=1, flower_pot=1}, + groups = { dig_immediate = 3, deco_block = 1, attached_node = 1, dig_by_piston = 1, flower_pot = 1 }, sounds = mcl_sounds.node_sound_stone_defaults(), on_rightclick = function(pos, node, clicker, itemstack) local name = clicker:get_player_name() @@ -40,7 +43,7 @@ minetest.register_node("mcl_flowerpots:flower_pot", { end local item = clicker:get_wielded_item():get_name() if mcl_flowerpots.registered_pots[item] then - minetest.swap_node(pos, {name="mcl_flowerpots:flower_pot_"..mcl_flowerpots.registered_pots[item]}) + minetest.swap_node(pos, { name = "mcl_flowerpots:flower_pot_" .. mcl_flowerpots.registered_pots[item] }) if not minetest.is_creative_enabled(clicker:get_player_name()) then itemstack:take_item() end @@ -51,37 +54,32 @@ minetest.register_node("mcl_flowerpots:flower_pot", { minetest.register_craft({ output = "mcl_flowerpots:flower_pot", recipe = { - {"mcl_core:brick", "", "mcl_core:brick"}, - {"", "mcl_core:brick", ""}, - {"", "", ""}, - } + { "mcl_core:brick", "", "mcl_core:brick" }, + { "", "mcl_core:brick", "" }, + { "", "", "" }, + }, }) +---@param name string +---@param def {name: string, desc: string, image: string} function mcl_flowerpots.register_potted_flower(name, def) mcl_flowerpots.registered_pots[name] = def.name - minetest.register_node(":mcl_flowerpots:flower_pot_"..def.name, { - description = def.desc.." "..S("Flower Pot"), + minetest.register_node(":mcl_flowerpots:flower_pot_" .. def.name, { + description = def.desc .. " " .. S("Flower Pot"), _doc_items_create_entry = false, drawtype = "mesh", mesh = "flowerpot.obj", tiles = { - "[combine:32x32:0,0=mcl_flowerpots_flowerpot.png:0,0="..def.image, + "[combine:32x32:0,0=mcl_flowerpots_flowerpot.png:0,0=" .. def.image, }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + use_texture_alpha = "clip", visual_scale = 0.5, - wield_scale = {x=1.0, y=1.0, z=1.0}, paramtype = "light", sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - collision_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, + selection_box = pot_box, + collision_box = pot_box, is_ground_content = false, - groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2}, + groups = { dig_immediate = 3, attached_node = 1, dig_by_piston = 1, not_in_creative_inventory = 1, flower_pot = 2 }, sounds = mcl_sounds.node_sound_stone_defaults(), on_rightclick = function(pos, item, clicker) local player_name = clicker:get_player_name() @@ -89,46 +87,41 @@ function mcl_flowerpots.register_potted_flower(name, def) minetest.record_protection_violation(pos, player_name) return end - minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, name) - minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"}) + minetest.add_item(vector.offset(pos, 0, 0.5, 0), name) + minetest.set_node(pos, { name = "mcl_flowerpots:flower_pot" }) end, drop = { items = { - { items = { "mcl_flowerpots:flower_pot", name } } - } + { items = { "mcl_flowerpots:flower_pot", name } }, + }, }, }) -- Add entry alias for the Help if has_doc then - doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..name) + doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_" .. name) end end +---@param name string +---@param def {name: string, desc: string, image: string} function mcl_flowerpots.register_potted_cube(name, def) mcl_flowerpots.registered_pots[name] = def.name - minetest.register_node(":mcl_flowerpots:flower_pot_"..def.name, { - description = def.desc.." "..S("Flower Pot"), + minetest.register_node(":mcl_flowerpots:flower_pot_" .. def.name, { + description = def.desc .. " " .. S("Flower Pot"), _doc_items_create_entry = false, drawtype = "mesh", mesh = "flowerpot_with_long_cube.obj", tiles = { def.image, }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + use_texture_alpha = "clip", visual_scale = 0.5, - wield_scale = {x=1.0, y=1.0, z=1.0}, paramtype = "light", sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - collision_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, + selection_box = pot_box, + collision_box = pot_box, is_ground_content = false, - groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2}, + groups = { dig_immediate = 3, attached_node = 1, dig_by_piston = 1, not_in_creative_inventory = 1, flower_pot = 2 }, sounds = mcl_sounds.node_sound_stone_defaults(), on_rightclick = function(pos, item, clicker) local player_name = "" @@ -139,18 +132,18 @@ function mcl_flowerpots.register_potted_cube(name, def) minetest.record_protection_violation(pos, player_name) return end - minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, name) - minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"}) + minetest.add_item(vector.offset(pos, 0, 0.5, 0), name) + minetest.set_node(pos, { name = "mcl_flowerpots:flower_pot" }) end, drop = { items = { - { items = { "mcl_flowerpots:flower_pot", name } } - } + { items = { "mcl_flowerpots:flower_pot", name } }, + }, }, }) -- Add entry alias for the Help if has_doc then - doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..def.name) + doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_" .. def.name) end end diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ja.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ja.tr new file mode 100644 index 000000000..8e8a71b02 --- /dev/null +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ja.tr @@ -0,0 +1,26 @@ +# textdomain: mcl_flowerpots +Dandelion Flower Pot=鉢に植えたタンポポ +Poppy Flower Pot=鉢に植えたポピー +Blue Orchid Flower Pot=鉢に植えたヒスイラン +Allium Flower Pot=鉢に植えたアリウム +Azure Bluet Flower Pot=鉢に植えたヒナソウ +Red Tulip Flower Pot=鉢に植えた赤色のチューリップ +Pink Tulip Flower Pot=鉢に植えた桃色のチューリップ +White Tulip Flower Pot=鉢に植えた白色のチューリップ +Orange Tulip Flower Pot=鉢に植えた橙色のチューリップ +Oxeye Daisy Flower Pot=鉢に植えたフランスギク +Brown Mushroom Flower Pot=鉢に植えた茶色キノコ +Red Mushroom Flower Pot=鉢に植えた赤色キノコ +Oak Sapling Flower Pot=鉢に植えたオークの苗木 +Acacia Sapling Flower Pot=鉢に植えたアカシアの苗木 +Jungle Sapling Flower Pot=鉢に植えたジャングルの苗木 +Dark Oak Sapling Flower Pot=鉢に植えたダークオークの苗木 +Spruce Sapling Flower Pot=鉢に植えたマツの苗木 +Birch Sapling Flower Pot=鉢に植えたシラカバの苗木 +Dead Bush Flower Pot=鉢に植えた枯れ木 +Fern Flower Pot=鉢に植えたシダ +Cactus Flower Pot=鉢に植えたサボテン +Flower Pot=植木鉢 +Flower pots are decorative blocks in which flowers and other small plants can be placed.=植木鉢は、花や小さな植物を植えることができる装飾ブロックです。 +Just place a plant on the flower pot. Flower pots can hold small flowers (not higher than 1 block), saplings, ferns, dead bushes, mushrooms and cacti. Rightclick a potted plant to retrieve the plant.=植木鉢の上に植物を置くだけ。 植木鉢に置けるのは、小さな花(1ブロックより高くないもの)、苗木、シダ、枯れ木、キノコ、サボテンです。植木鉢を右クリックすると、その植物を取り出せます。 +Can hold a small flower or plant=小さな花や植物を保持可能 diff --git a/mods/ITEMS/mcl_flowers/init.lua b/mods/ITEMS/mcl_flowers/init.lua index 33ea531c5..d7b046cf5 100644 --- a/mods/ITEMS/mcl_flowers/init.lua +++ b/mods/ITEMS/mcl_flowers/init.lua @@ -51,6 +51,9 @@ local on_place_flower = mcl_util.generate_on_place_plant_function(function(pos, if (light_night and light_night >= 8) or (light_day and light_day >= minetest.LIGHT_MAX) then light_ok = true end + if itemstack:get_name() == "mcl_flowers:wither_rose" and ( minetest.get_item_group(soil_node.name, "grass_block") > 0 or soil_node.name == "mcl_core:dirt" or soil_node.name == "mcl_core:coarse_dirt" or soil_node.name == "mcl_mud:mud" or soil_node.name == "mcl_moss:moss" or soil_node.name == "mcl_nether:netherrack" or minetest.get_item_group(soil_node.name, "soul_block") > 0 ) then + return true,colorize + end local is_flower = minetest.get_item_group(itemstack:get_name(), "flower") == 1 local ok = (soil_node.name == "mcl_core:dirt" or minetest.get_item_group(soil_node.name, "grass_block") == 1 or (not is_flower and (soil_node.name == "mcl_core:coarse_dirt" or soil_node.name == "mcl_core:podzol" or soil_node.name == "mcl_core:podzol_snow"))) and light_ok return ok, colorize diff --git a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ja.tr b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ja.tr new file mode 100644 index 000000000..60daf85b0 --- /dev/null +++ b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ja.tr @@ -0,0 +1,32 @@ +# textdomain: mcl_flowers +This is a small flower. Small flowers are mainly used for dye production and can also be potted.=これは小さな花です。小さな花は主に染料作りに使われ、鉢植えも可能です。 +It can only be placed on a block on which it would also survive.=生き残るブロックにのみ配置できます。 +Poppy=ポピー +Dandelion=タンポポ +Oxeye Daisy=フランスギク +Orange Tulip=橙色のチューリップ +Pink Tulip=桃色のチューリップ +Red Tulip=赤色のチューリップ +White Tulip=白色のチューリップ +Allium=アリウム +Azure Bluet=ヒナソウ +Blue Orchid=ヒスイラン +Tall Grass=丈が高い草 +Tall grass is a small plant which often occurs on the surface of grasslands. It can be harvested for wheat seeds. By using bone meal, tall grass can be turned into double tallgrass which is two blocks high.=丈が高い草は、草原の表面によく見られる小さな植物です。そこから小麦の種を収穫できることがあります。骨粉を使うことで、高さ2ブロックの、丈が倍高い草に変えられます。 +Fern=シダ +Ferns are small plants which occur naturally in jungles and taigas. They can be harvested for wheat seeds. By using bone meal, a fern can be turned into a large fern which is two blocks high.=シダは、ジャングルやタイガに自生する小さな植物です。そこから小麦の種を収穫できることがあります。骨粉を使うことで、高さ2ブロックの、大きなシダに変えられます。 +(Top Part)=(上部) +Peony=ボタン +A peony is a large plant which occupies two blocks. It is mainly used in dye production.=ボタンは、2つのブロックを占める大きな植物です。主に染料に使われます。 +Rose Bush=バラの低木 +A rose bush is a large plant which occupies two blocks. It is safe to touch it. Rose bushes are mainly used in dye production.=バラの低木は、2ブロック分を占める大きな植物です。触っても大丈夫です。バラの低木は主に染料に使われます。 +Lilac=ライラック +A lilac is a large plant which occupies two blocks. It is mainly used in dye production.=ライラックは、2つのブロックを占める大きな植物です。主に染料に使われます。 +Sunflower=ヒマワリ +A sunflower is a large plant which occupies two blocks. It is mainly used in dye production.=ヒマワリは、2つのブロックを占める大きな植物です。主に染料に使われます。 +Double tallgrass a variant of tall grass and occupies two blocks. It can be harvested for wheat seeds.=丈が倍高い草は、丈が高い草の変種であり、2ブロックを占有します。そこから小麦の種を収穫できることがあります。 +Large fern is a variant of fern and occupies two blocks. It can be harvested for wheat seeds.=大きなシダは、シダの変種であり、2ブロックを占有します。そこから小麦の種を収穫できることがあります。 +Double Tallgrass=丈が倍高い草 +Large Fern=大きなシダ +Lily Pad=スイレンの葉 +A lily pad is a flat plant block which can be walked on. They can be placed on water sources, ice and frosted ice.=スイレンの葉は、歩くことができるペラい植物ブロックです。水源や氷、フロストアイスの上に置けます。 diff --git a/mods/ITEMS/mcl_flowers/register.lua b/mods/ITEMS/mcl_flowers/register.lua index b45f3e1ee..c1bd37878 100644 --- a/mods/ITEMS/mcl_flowers/register.lua +++ b/mods/ITEMS/mcl_flowers/register.lua @@ -59,4 +59,10 @@ mcl_flowers.register_simple_flower("blue_orchid", { image = "mcl_flowers_blue_orchid.png", selection_box = { -5/16, -0.5, -5/16, 5/16, 7/16, 5/16 }, potted = true, -}) \ No newline at end of file +}) +mcl_flowers.register_simple_flower("wither_rose", { + desc = S("Wither Rose"), + image = "mcl_flowers_wither_rose.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }, + potted = true, +}) diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_wither_rose.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_wither_rose.png new file mode 100644 index 000000000..539722a34 Binary files /dev/null and b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_wither_rose.png differ diff --git a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ja.tr b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ja.tr new file mode 100644 index 000000000..950419915 --- /dev/null +++ b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ja.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_furnaces +Furnace=かまど +Furnaces cook or smelt several items, using a furnace fuel, into something else.=かまどは、燃料を使っていくつかのアイテムを調理または精錬し、別のものに作り変えます。 +Use the furnace to open the furnace menu. Place a furnace fuel in the lower slot and the source material in the upper slot. The furnace will slowly use its fuel to smelt the item. The result will be placed into the output slot at the right side.=かまどを使用して、かまどのメニューを開きます。下スロットに燃料を、上スロットに素材を入れます。かまどはゆっくりと燃料を使い、アイテムを精錬します。精錬の結果は右側の出力スロットに置かれます。 +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=レシピ本を使って、何を製錬できるか、何を燃料にできるか、どれくらい燃えるかを確認しましょう。 +Burning Furnace=燻製器 燃焼中 +Recipe book=レシピ本 +Inventory=インベントリ +Uses fuel to smelt or cook items=燃料を使ってアイテムを精錬・調理 diff --git a/mods/ITEMS/mcl_grindstone/init.lua b/mods/ITEMS/mcl_grindstone/init.lua new file mode 100644 index 000000000..00c373536 --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/init.lua @@ -0,0 +1,343 @@ +-- Code based from mcl_anvils + +local S = minetest.get_translator(minetest.get_current_modname()) + +local MAX_WEAR = 65535 + +-- formspecs +local function get_grindstone_formspec() + return "size[9,8.75]".. + "image[3,1.5;1.5,1;gui_crafting_arrow.png]".. + "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. + "label[1,0.1;"..minetest.formspec_escape(minetest.colorize("#313131", S("Repair & Disenchant"))).."]".. + "list[context;main;0,0;8,4;]".. + "list[current_player;main;0,4.5;9,3;9]".. + mcl_formspec.get_itemslot_bg(0,4.5,9,3).. + "list[current_player;main;0,7.74;9,1;]".. + mcl_formspec.get_itemslot_bg(0,7.74,9,1).. + "list[context;input;1,1;1,1;]".. + mcl_formspec.get_itemslot_bg(1,1,1,1).. + "list[context;input;1,2;1,1;1]".. + mcl_formspec.get_itemslot_bg(1,2,1,1).. + "list[context;output;6,1.5;1,1;]".. + mcl_formspec.get_itemslot_bg(6,1.5,1,1).. + "listring[context;output]".. + "listring[current_player;main]".. + "listring[context;input]".. + "listring[current_player;main]" +end + +-- Creates a new item with the wear of the items and custom name +local function create_new_item(name_item, meta, wear) + local new_item = ItemStack(name_item) + if wear ~= nil then + new_item:set_wear(wear) + end + local new_meta = new_item:get_meta() + new_meta:set_string("name", meta:get_string("name")) + tt.reload_itemstack_description(new_item) + return new_item +end + +-- If an item has an enchanment then remove "_enchanted" from the name +local function remove_enchant_name(stack) + if mcl_enchanting.is_enchanted(stack:get_name()) then + local name = stack:get_name() + return name.sub(name, 1, -11) + else + return stack:get_name() + end +end + +-- If an input has a curse transfer it to the new item +local function transfer_curse(old_itemstack, new_itemstack) + local enchants = mcl_enchanting.get_enchantments(old_itemstack) + for enchant, level in pairs(enchants) do + if mcl_enchanting.enchantments[enchant].curse == true then + new_itemstack = mcl_enchanting.enchant(new_itemstack, enchant, level) + end + end + return new_itemstack +end + +-- Depending on an enchantment level and isn't a curse multiply xp given +local function calculate_xp(stack) + local xp = 0 + local enchants = mcl_enchanting.get_enchantments(stack) + for enchant, level in pairs(enchants) do + if level > 0 and mcl_enchanting.enchantments[enchant].curse == false then + -- Add a bit of uniform randomisation + xp = xp + math.random(7, 13) * level + end + end + return xp +end + +-- Helper function to make sure update_grindstone_slots NEVER overstacks the output slot +local function fix_stack_size(stack) + if not stack or stack == "" then return "" end + local count = stack:get_count() + local max_count = stack:get_stack_max() + + if count > max_count then + stack:set_count(max_count) + count = max_count + end + return count +end + + +-- Update the inventory slots of an grindstone node. +-- meta: Metadata of grindstone node +local function update_grindstone_slots(meta) + local inv = meta:get_inventory() + local input1 = inv:get_stack("input", 1) + local input2 = inv:get_stack("input", 2) + local meta = input1:get_meta() + + local new_output + + -- Both input slots are occupied + if (not input1:is_empty() and not input2:is_empty()) then + local def1 = input1:get_definition() + local def2 = input2:get_definition() + -- Remove enchant name if they have one + local name1 = remove_enchant_name(input1) + local name2 = remove_enchant_name(input2) + + -- Calculate repair + local function calculate_repair(dur1, dur2) + -- Grindstone gives a 5% bonus to durability + local new_durability = (MAX_WEAR - dur1) + (MAX_WEAR - dur2) * 1.05 + return math.max(0, math.min(MAX_WEAR, MAX_WEAR - new_durability)) + end + + -- Check if both are tools and have the same tool type + if def1.type == "tool" and def2.type == "tool" and name1 == name2 then + local new_wear = calculate_repair(input1:get_wear(), input2:get_wear()) + local new_item = create_new_item(name1, meta, new_wear) + -- Transfer curses if both items have any + new_output = transfer_curse(input1, new_item) + new_output = transfer_curse(input2, new_output) + else + new_output = "" + end + -- Check if at least one input has an item + -- Check if the item is's an enchanted book or tool + elseif (not input1:is_empty() and input2:is_empty()) or (input1:is_empty() and not input2:is_empty()) then + if input2:is_empty() then + local def1 = input1:get_definition() + local meta = input1:get_meta() + if def1.type == "tool" and mcl_enchanting.is_enchanted(input1:get_name()) then + local name = remove_enchant_name(input1) + local wear = input1:get_wear() + local new_item = create_new_item(name, meta, wear) + new_output = transfer_curse(input1, new_item) + elseif input1:get_name() == "mcl_enchanting:book_enchanted" then + new_item = create_new_item("mcl_books:book", meta, nil) + new_output = transfer_curse(input1, new_item) + else + new_output = "" + end + else + local def2 = input2:get_definition() + local meta = input2:get_meta() + if def2.type == "tool" and mcl_enchanting.is_enchanted(input2:get_name()) then + local name = remove_enchant_name(input2) + local wear = input2:get_wear() + local new_item = create_new_item(name, meta, wear) + new_output = transfer_curse(input2, new_item) + elseif input2:get_name() == "mcl_enchanting:book_enchanted" then + new_item = create_new_item("mcl_books:book", meta, nil) + new_output = transfer_curse(input2, new_item) + else + new_output = "" + end + end + else + new_output = "" + end + + -- Set the new output slot + if new_output then + fix_stack_size(new_output) + inv:set_stack("output", 1, new_output) + end +end + +-- Drop any items inside the grindstone if destroyed +local function drop_grindstone_items(pos, meta) + local inv = meta:get_inventory() + for i=1, inv:get_size("input") do + local stack = inv:get_stack("input", i) + if not stack:is_empty() then + local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + minetest.add_item(p, stack) + end + end +end + +local node_box = { + type = "fixed", + -- created with nodebox editor + fixed = { + {-0.25, -0.25, -0.375, 0.25, 0.5, 0.375}, + {-0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875}, + {0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875}, + {0.25, -0.5, -0.125, 0.375, -0.0625, 0.125}, + {-0.375, -0.5, -0.125, -0.25, -0.0625, 0.125}, + } +} + +minetest.register_node("mcl_grindstone:grindstone", { + description = S("Grindstone"), + _tt_help = S("Used to disenchant/fix tools"), + _doc_items_longdesc = S("Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station."), + _doc_items_usagehelp = S("To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.").."\n".. + S("To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.").."\n".. + S("To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.").."\n".. + S("If both items have enchantments the player will get xp from both items from the disenchant.").."\n".. + S("Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined."), + tiles = { + "grindstone_top.png", + "grindstone_top.png", + "grindstone_side.png", + "grindstone_side.png", + "grindstone_front.png", + "grindstone_front.png" + }, + drawtype = "nodebox", + paramtype2 = "facedir", + node_box = node_box, + selection_box = node_box, + collision_box = node_box, + sounds = mcl_sounds.node_sound_stone_defaults(), + groups = {pickaxey = 1, deco_block = 1}, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local meta = minetest.get_meta(pos) + local meta2 = meta:to_table() + meta:from_table(oldmetadata) + drop_grindstone_items(pos, meta) + meta:from_table(meta2) + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + elseif listname == "output" then + return 0 + else + return stack:get_count() + end + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + elseif to_list == "output" then + return 0 + elseif from_list == "output" and to_list == "input" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if inv:get_stack(to_list, to_index):is_empty() then + return count + else + return 0 + end + else + return count + end + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + update_grindstone_slots(meta) + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + if from_list == "output" and to_list == "input" then + local inv = meta:get_inventory() + for i=1, inv:get_size("input") do + if i ~= to_index then + local istack = inv:get_stack("input", i) + istack:set_count(math.max(0, istack:get_count() - count)) + inv:set_stack("input", i, istack) + end + end + end + update_grindstone_slots(meta) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if listname == "output" then + local xp_earnt = 0 + local inv = meta:get_inventory() + local input1 = inv:get_stack("input", 1) + local input2 = inv:get_stack("input", 2) + -- Both slots occupied? + if not input1:is_empty() and not input2:is_empty() then + -- Get xp earnt from the enchanted items + xp_earnt = calculate_xp(input1) + calculate_xp(input1) + input1:take_item() + input2:take_item() + inv:set_stack("input", 1, input1) + inv:set_stack("input", 2, input2) + else + -- If only one input item + if not input1:is_empty() then + xp_earnt = calculate_xp(input1) + input1:set_count(math.max(0, input1:get_count() - stack:get_count())) + inv:set_stack("input", 1, input1) + end + if not input2:is_empty() then + xp_earnt = calculate_xp(input2) + input2:set_count(math.max(0, input2:get_count() - stack:get_count())) + inv:set_stack("input", 2, input2) + end + end + -- Give the player xp + if mcl_experience.throw_xp and xp_earnt > 0 then + mcl_experience.throw_xp(pos, xp_earnt) + end + elseif listname == "input" then + update_grindstone_slots(meta) + end + end, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("input", 2) + inv:set_size("output", 1) + local form = get_grindstone_formspec() + meta:set_string("formspec", form) + end, + on_rightclick = function(pos, node, player, itemstack) + if not player:get_player_control().sneak then + local meta = minetest.get_meta(pos) + update_grindstone_slots(meta) + meta:set_string("formspec", get_grindstone_formspec()) + end + end, + _mcl_blast_resistance = 6, + _mcl_hardness = 2 +}) + +minetest.register_craft({ + output = "mcl_grindstone:grindstone", + recipe = { + { "mcl_core:stick", "mcl_stairs:slab_stone_rough", "mcl_core:stick"}, + { "group:wood", "", "group:wood"}, + } +}) diff --git a/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.fr.tr b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.fr.tr new file mode 100644 index 000000000..338bae06a --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.fr.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_grindstone +Inventory=Inventaire +Repair & Disenchant=Répare & Désenchante +Grindstone=Meule +Used to disenchant/fix tools=Utilisée pour désenchanter/réparer +Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station.=Les meules désenchantent les outils et armures sauf si elles sont maudites, et répare deux objets du même type, c'est aussi le poste de travail du forgeron d'armes. +To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.=Pour utiliser la meule, cliquer droit, deux emplacements d'entrée (à gauche) et un seul emplacement de sortie. +To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.=Pour désenchanter un objet, placer un objet enchanté à l'entrée et récupérer l'objet désenchanté à la sortie. +To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.=Pour réparer un outil vous avez besoin d'un outil du même type et matériau, placer deux objets à l'entrée et à la sortie leurs durabilités seront combinées avec un bonus de 5%. +If both items have enchantments the player will get xp from both items from the disenchant.=Si les deux objets ont des enchantements le joueur aura de l'expérience à partir des deux objets à désenchanter. +Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined.=Les malédictions ne peuvent pas être retirées et sont transférées à l'objet réparé, si les deux objets ont des malédictions différentes elles sont combinées. \ No newline at end of file diff --git a/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ja.tr b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ja.tr new file mode 100644 index 000000000..c0bd0a4d4 --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ja.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_grindstone +Inventory=インベントリ +Repair & Disenchant=修理とエンチャント解除 +Grindstone=砥石 +Used to disenchant/fix tools=道具のエンチャント解除/修復に使用 +Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station.=砥石は、ツールやアーマーからエンチャントを解除(呪い以外)したり、同種の2つのアイテムで修理したりできます。これは、武器鍛冶の職場でもあります。 +To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.=砥石を使うには、右クリックします。 入力スロットが2つ(左側)、出力スロットが1つです。 +To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.=エンチャントを解除するには、エンチャントされたアイテムを入力スロットの1つに置き、出力から解除されたアイテムを取り出します。 +To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.=道具を修理するには、同種・同素材の道具が必要です。両方のアイテムを入力スロットに入れると、出力スロットは2つのアイテムの耐久値に5%のボーナスを加えて結合します。 +If both items have enchantments the player will get xp from both items from the disenchant.=両方のアイテムにエンチャントがかかっている場合、プレイヤーは両方からエンチャント解除による経験値を得られます。 +Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined.=呪いは取り除くことができず、新しい修理品に引き継がれます。両方の修理品に異なる呪いがある場合、呪いは統合されます。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_grindstone/locale/template.txt b/mods/ITEMS/mcl_grindstone/locale/template.txt new file mode 100644 index 000000000..8cce10880 --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/locale/template.txt @@ -0,0 +1,11 @@ +# textdomain: mcl_grindstone +Inventory= +Repair & Disenchant= +Grindstone= +Used to disenchant/fix tools= +Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station.= +To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.= +To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.= +To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.= +If both items have enchantments the player will get xp from both items from the disenchant.= +Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_grindstone/mod.conf b/mods/ITEMS/mcl_grindstone/mod.conf new file mode 100644 index 000000000..66773c57f --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/mod.conf @@ -0,0 +1,4 @@ +name = mcl_grindstone +author = TheRandomLegoBrick, ChrisPHP +depends = mcl_experience, mcl_sounds +description = Add block that disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station. diff --git a/mods/ITEMS/mcl_grindstone/textures/grindstone_front.png b/mods/ITEMS/mcl_grindstone/textures/grindstone_front.png new file mode 100644 index 000000000..ec72b0470 Binary files /dev/null and b/mods/ITEMS/mcl_grindstone/textures/grindstone_front.png differ diff --git a/mods/ITEMS/mcl_grindstone/textures/grindstone_side.png b/mods/ITEMS/mcl_grindstone/textures/grindstone_side.png new file mode 100644 index 000000000..ec28f3014 Binary files /dev/null and b/mods/ITEMS/mcl_grindstone/textures/grindstone_side.png differ diff --git a/mods/ITEMS/mcl_grindstone/textures/grindstone_top.png b/mods/ITEMS/mcl_grindstone/textures/grindstone_top.png new file mode 100644 index 000000000..1096deba6 Binary files /dev/null and b/mods/ITEMS/mcl_grindstone/textures/grindstone_top.png differ diff --git a/mods/ITEMS/mcl_grindstone/textures/gui_crafting_arrow.png b/mods/ITEMS/mcl_grindstone/textures/gui_crafting_arrow.png new file mode 100644 index 000000000..93ce1e1b9 Binary files /dev/null and b/mods/ITEMS/mcl_grindstone/textures/gui_crafting_arrow.png differ diff --git a/mods/ITEMS/mcl_hamburger/init.lua b/mods/ITEMS/mcl_hamburger/init.lua new file mode 100644 index 000000000..7d4707bdd --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/init.lua @@ -0,0 +1,120 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 11/19/22 7:13 AM +--- + +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 10/23/22 4:50 AM +--- +-- LOCALIZATION + +local S = minetest.get_translator("mcl_hamburger") + +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local table = table +local DEBUG = false + +local enable_burger = minetest.settings:get_bool("mcl_enable_hamburger",true) +local use_alt = minetest.settings:get_bool("mcl_hamburger_alt_texture",false) + +mcl_hamburger = {} + +if DEBUG then + minetest.log("MCL_Hamburger::START.") +end + +-- call to register your hamburger. +function mcl_hamburger.register_burger_craft(cooked_meat) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_hamburger:hamburger", + burntime = 2, + }) + + minetest.register_craft({ + output = "mcl_hamburger:hamburger", + recipe = { + { "mcl_farming:bread"}, + { cooked_meat }, -- "mcl_mobitems:cooked_beef" for a reg hamburger. Grind up clowns for a Big Mac. + { "mcl_farming:bread" }, + }, + }) + minetest.register_craft({ + output = "mcl_hamburger:hamburger", + recipe = { + -- "mcl_mobitems:cooked_beef" for a reg hamburger. Grind up clowns for a Big Mac. + { "mcl_farming:bread", cooked_meat, "mcl_farming:bread"}, + }, + }) + +end + +local hamburger_def = { + description = S("A Hamburger"), + _doc_items_longdesc = S("A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten."), + _doc_items_usagehelp = S("Wield this item to pull villagers to you."), + _tt_help = S("A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy."), + inventory_image = "mcl_hamburger.png", + wield_image = "mcl_hamburger.png", + on_place = minetest.item_eat(8), + on_secondary_use = minetest.item_eat(8), + groups = { food = 2, eatable = 8 }, + _mcl_saturation = 13.8, +} + +if not enable_burger then + hamburger_def.groups.not_in_creative_inventory = 1 +end + +if use_alt == false then + minetest.register_craftitem("mcl_hamburger:hamburger", hamburger_def) +else + local hamburger_alt = table.copy(hamburger_def) + hamburger_alt.inventory_image = "mcl_hamburger_alt.png" + hamburger_alt.wield_image = "mcl_hamburger_alt.png" + minetest.register_craftitem("mcl_hamburger:hamburger", hamburger_alt) +end + +local function register_achievements() + + awards.register_achievement("mcl_hamburger:hamburger", { + title = S("Burger Time!"), + description = S("Craft a Hamburger."), + icon = "mcl_hamburger_alt.png", + trigger = { + type = "craft", + item = "mcl_hamburger:hamburger", + target = 1 + }, + type = "Advancement", + group = "Overworld", + }) + +end + +local function register_doc_entry() + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("craftitems", "mcl_hamburger:hamburger", "craftitems", "mcl_hamburger:hamburger") + end + +end + +if enable_burger then + -- make the villagers follow the item + minetest.registered_entities["mobs_mc:villager"].nofollow = false + -- add it to the follow items. + table.insert(minetest.registered_entities["mobs_mc:villager"].follow,"mcl_hamburger:hamburger") + -- register the item and crafting recipe. + mcl_hamburger.register_burger_craft("mcl_mobitems:cooked_beef") + -- add in the super cool achievement(s)! + register_achievements() + register_doc_entry() +end + diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.de.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.de.tr new file mode 100644 index 000000000..8d375dbd5 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.de.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Ein Hamburger + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Ein leckerer Hamburger, der die Dorfbewohner sicher wie eine Leine anlocken wird. Kann gegessen werden. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Ein leckerer Hamburger, der die Dorfbewohner anlocken wird. "Ich bezahle dir gerne den Dienstag, für heute einen Hamburger." - Wimpy. + +Burger Time!=Burgerzeit! +Craft a Hamburger.=Stelle einen Hamburger her. +Wield this item to pull villagers to you.=Benutze diesen Gegenstand, um Dorfbewohner zu dir zu ziehen. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.es.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.es.tr new file mode 100644 index 000000000..ad10560e4 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.es.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Una hamburguesa + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Una sabrosa hamburguesa que seguramente atraerá a los aldeanos como una pista. Se puede comer. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Una sabrosa hamburguesa que seguramente atraerá a los aldeanos. 'Con gusto te pago el martes, por una hamburguesa hoy.' - Wimpy. + +Burger Time!=¡Tiempo de hamburguesas! +Craft a Hamburger.=Elabora una hamburguesa. +Wield this item to pull villagers to you.=Utiliza este objeto para atraer a los aldeanos hacia ti. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.fr.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.fr.tr new file mode 100644 index 000000000..1463a69ad --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.fr.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Un hamburger + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Un hamburger savoureux qui ne manquera pas d'attirer les villageois comme une piste. Peut être mangé. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Un hamburger savoureux qui ne manquera pas d'attirer les villageois. «Je vous paierai volontiers mardi, pour un hamburger aujourd'hui.» - Wimpy. + +Burger Time!=L'heure des burgers! +Craft a Hamburger.=Fabriquez un hamburger. +Wield this item to pull villagers to you.=Maniez cet objet pour attirer les villageois vers vous. \ No newline at end of file diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ja.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ja.tr new file mode 100644 index 000000000..7cd12d735 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ja.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=ハンバーガー + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=リードでも付けたかのように村人を引き寄せる、美味しいハンバーガーです。食べられます。 + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=村人たちを魅了する美味しいハンバーガーです。「今日のハンバーガー代、喜んで払いますよ、火曜日に」。- へたれ(WIMPY)。 + +Burger Time!=バーガータイム! +Craft a Hamburger.=ハンバーガーをクラフトします。 +Wield this item to pull villagers to you.=このアイテムを手に持つと、村人を引き寄せられます。 diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pl.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pl.tr new file mode 100644 index 000000000..09569a2ba --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pl.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Hamburger + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Smaczny hamburger, który zwabi wieśniaków jak trop. Można jeść. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Smaczny hamburger, który z pewnością zwabi wieśniaków. - Chętnie zapłacę we wtorek za hamburgera dzisiaj. - Mięczak (Wimpy). + +Burger Time!=Czas na burgery! +Craft a Hamburger.=Stwórz hamburgera. +Wield this item to pull villagers to you.=Chwyć ten przedmiot, aby przyciągnąć wieśniaków do siebie. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr new file mode 100644 index 000000000..736f182a5 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Гамбургер + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Вкусный гамбургер, который обязательно привлечет жителей деревни, как наживку. Можно есть. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Вкусный гамбургер, который обязательно привлечет жителей деревни. — Я с радостью заплачу тебе во вторник за гамбургер сегодня. - Вимпи. + +Burger Time!=Время бургеров! +Craft a Hamburger.=Изготовить гамбургер. +Wield this item to pull villagers to you.=Используйте этот предмет, чтобы притягивать к себе жителей деревни. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.zh_TW.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.zh_TW.tr new file mode 100644 index 000000000..46f30c88e --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.zh_TW.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_hamburger +A Hamburger=一個漢堡 +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=一個美味的漢堡包,肯定會像鉛一樣吸引村民。 可以吃 +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=一個美味的漢堡包,一定會吸引村民。 “我很樂意在星期二付錢給你,今天就買一個漢堡包。” - 懦弱。 +Burger Time!=漢堡時間! +Craft a Hamburger.=製作一個漢堡包。 +Wield this item to pull villagers to you.=使用此物品將村民拉到你身邊。 + + + + + + + + + diff --git a/mods/ITEMS/mcl_hamburger/locale/template.txt b/mods/ITEMS/mcl_hamburger/locale/template.txt new file mode 100644 index 000000000..850ff62b0 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/template.txt @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger= + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.= + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.= + +Burger Time!= +Craft a Hamburger.= +Wield this item to pull villagers to you.= diff --git a/mods/ITEMS/mcl_hamburger/mod.conf b/mods/ITEMS/mcl_hamburger/mod.conf new file mode 100644 index 000000000..f5baca506 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/mod.conf @@ -0,0 +1,5 @@ +name = mcl_hamburger +author = Michieal +description = A cute (and easy to use) replacement for not having leashes in MC2 +depends = mcl_core, mcl_sounds, mobs_mc, mcl_mobitems, awards +optional_depends = doc diff --git a/mods/ITEMS/mcl_hamburger/readme.txt b/mods/ITEMS/mcl_hamburger/readme.txt new file mode 100644 index 000000000..e479c01b9 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/readme.txt @@ -0,0 +1,43 @@ +Tags: Hamburger +Icon set: Fugue 16px Additional Icons +Author: Yusuke Kamiyamane +License: CC Attribution 3.0 Unported +Readme file +Commercial usage: Allowed +Posted: November 22, 2011 +Icon Readme file: + +Fugue Icons + +(C) 2011 Yusuke Kamiyamane. All rights reserved. +These icons are licensed under a Creative Commons +Attribution 3.0 License. + + +If you can't or don't want to provide attribution, please +purchase a royalty-free license. + + +I'm unavailable for custom icon design work. But your +suggestions are always welcome! + + +------------------------------------------------------------ + +The images contained within have been altered to be more legible within the game and not rendered with weird +antialiasing by Michieal. All extraneous information in the images have been removed to decrease file size. + +This mod is licensed under CC-BY-SA 3, with the intent of it being used by the Mineclone 2 game for Minetest. +This code was written by Michieal, with additions included by Cora. + +The achievement "Burger Time!" is an homage to the classic coin-op arcade game BurgerTime, by Data East (1982) and +Bally Midway. + +Information about the BurgerTime Arcade Game: + +From https://thepinballgameroom.com/product/burgertime-arcade-machine/ on the original game: +BurgerTime Arcade Machine, originally released as Hamburger in Japan, is a 1982 arcade game developed by Data East +initially for its DECO Cassette System. In the United States, Data East USA licensed BurgerTime Arcade Machine for +distribution by Bally Midway as a standard dedicated arcade game. Data East also released its own version of BurgerTime +in the United States through its DECO Cassette System. The Data East and Midway versions are distinguished by the +manufacturer’s name on the title screen and by the marquee and cabinet artworks, as the game itself is identical. diff --git a/mods/ITEMS/mcl_hamburger/textures/mcl_hamburger.png b/mods/ITEMS/mcl_hamburger/textures/mcl_hamburger.png new file mode 100644 index 000000000..432d05bba Binary files /dev/null and b/mods/ITEMS/mcl_hamburger/textures/mcl_hamburger.png differ diff --git a/mods/ITEMS/mcl_hamburger/textures/mcl_hamburger_alt.png b/mods/ITEMS/mcl_hamburger/textures/mcl_hamburger_alt.png new file mode 100644 index 000000000..70fd29448 Binary files /dev/null and b/mods/ITEMS/mcl_hamburger/textures/mcl_hamburger_alt.png differ diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index c14079393..69c26b97d 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -1,5 +1,6 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local minetest = minetest local mod_doc = minetest.get_modpath("doc") local mod_screwdriver = minetest.get_modpath("screwdriver") @@ -8,159 +9,289 @@ if minetest.get_modpath("mcl_armor") then equip_armor = mcl_armor.equip_on_use end --- Heads system +mcl_heads = {} -local function addhead(name, texture, desc, longdesc, rangemob, rangefactor) - local on_rotate_floor, on_rotate_wall - if mod_screwdriver then - on_rotate_floor = function(pos, node, user, mode, new_param2) - if mode == screwdriver.ROTATE_AXIS then - node.name = node.name .. "_wall" - node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) - minetest.set_node(pos, node) - return true - end - end - on_rotate_wall = function(pos, node, user, mode, new_param2) - if mode == screwdriver.ROTATE_AXIS then - node.name = string.sub(node.name, 1, string.len(node.name)-5) - node.param2 = minetest.dir_to_facedir(minetest.wallmounted_to_dir(node.param2)) - minetest.set_node(pos, node) - return true - end +-- rotations of head nodes within a quadrant (0° ≤ θ ≤ 90°) +mcl_heads.FLOOR_DEGREES = { [0]='', '22_5', '45', '67_5', } + +-- box of head nodes +mcl_heads.FLOOR_BOX = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, } + +-- floor head node nodedef template ------------------------------------------------------------------------------------ + +--- node definition template for floor mod heads +mcl_heads.deftemplate_floor = { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + groups = { + handy = 1, + armor = 1, + armor_head = 1, + non_combat_armor = 1, + non_combat_armor_head = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _mcl_armor_element = "head", + _mcl_blast_resistance = 1, + _mcl_hardness = 1, + + on_secondary_use = equip_armor, +} + +mcl_heads.deftemplate_floor_angled = { + drawtype = "mesh", + selection_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + collision_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + groups = { + handy = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + not_in_creative_inventory = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _doc_items_create_entry = false, + _mcl_blast_resistance = 1, + _mcl_hardness = 1, +} + +function mcl_heads.deftemplate_floor.on_rotate(pos, node, user, mode, new_param2) + if mode == screwdriver.ROTATE_AXIS then + node.name = node.name .. "_wall" + node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) + minetest.set_node(pos, node) + return true + end +end + +function mcl_heads.deftemplate_floor.on_place(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if not def then return itemstack end + + -- Allow pointed node's on_rightclick callback to override place. + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack end end - minetest.register_node("mcl_heads:"..name, { - description = desc, - _doc_items_longdesc = longdesc, - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "fixed", - fixed = { - { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - }, - }, - groups = {handy = 1, armor = 1, armor_head = 1, non_combat_armor = 1, non_combat_armor_head = 1, head = 1, deco_block = 1, dig_by_piston = 1}, + local above = pointed_thing.above + local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} + local wdir = minetest.dir_to_wallmounted(dir) + + local itemstring = itemstack:get_name() + local placestack = ItemStack(itemstack) + + -- place wall head node (elsewhere) + if wdir ~= 0 and wdir ~= 1 then + placestack:set_name(itemstring .."_wall") + itemstack = minetest.item_place(placestack, placer, pointed_thing, wdir) + + -- place floor head node (floor and ceiling) + else + local fdir = minetest.dir_to_facedir(dir) + + -- determine the head node rotation based on player's yaw (in cw direction from North/Z+) + local yaw = placer:get_look_horizontal() + yaw = wdir == 1 and math.pi*2 - yaw or yaw + + local rotation_level = math.min(math.max(math.round((yaw / (math.pi*2)) * 16), 0), 15) + placestack:set_name(itemstring ..mcl_heads.FLOOR_DEGREES[rotation_level % 4]) + + -- determine the head node face direction based on rotation level + fdir = math.floor(rotation_level / 4) + (wdir == 1 and 0 or 20) + + itemstack = minetest.item_place(placestack, placer, pointed_thing, fdir) + end + + -- restore item from angled and wall head nodes + itemstack:set_name(itemstring) + return itemstack +end + +-- wall head node nodedef template ------------------------------------------------------------------------------------- + +--- node definition template for wall mod heads +mcl_heads.deftemplate_wall = { + drawtype = "nodebox", + node_box = { + type = "wallmounted", + wall_bottom = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, + wall_top = { -0.25, 0.0, -0.25, 0.25, 0.5, 0.25, }, + wall_side = { -0.5, -0.25, -0.25, 0.0, 0.25, 0.25, }, + }, + groups = { + handy = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + not_in_creative_inventory = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "wallmounted", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _doc_items_create_entry = false, + _mcl_blast_resistance = 1, + _mcl_hardness = 1, +} + +function mcl_heads.deftemplate_wall.on_rotate(pos, node, user, mode, new_param2) + if mode == screwdriver.ROTATE_AXIS then + node.name = string.sub(node.name, 1, string.len(node.name)-5) + node.param2 = minetest.dir_to_facedir(minetest.wallmounted_to_dir(node.param2)) + minetest.set_node(pos, node) + return true + end +end + +-- API functions ------------------------------------------------------------------------------------------------------- + +--- @class HeadDef +--- @field name string identifier for node +--- @field texture string armor texture for node +--- @field description string translated description +--- @field longdesc string translated doc description +--- @field range_mob string name of mob affected by range reduction +--- @field range_factor number factor of range reduction + +--- registers a head +--- @param head_def HeadDef head node definition +function mcl_heads.register_head(head_def) + local name = "mcl_heads:" ..head_def.name + + -- register the floor head node + minetest.register_node(name, table.update(table.copy(mcl_heads.deftemplate_floor), { + description = head_def.description, + _doc_items_longdesc = head_def.longdesc, + -- The head textures are based off the textures of an actual mob. tiles = { -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. -- This is required for skeleton skull and wither skeleton skull. - "[combine:16x16:-4,4="..texture, -- top - "([combine:16x16:-4,4="..texture..")^([combine:16x16:-12,4="..texture..")", -- bottom - "[combine:16x16:-12,0="..texture, -- left - "[combine:16x16:4,0="..texture, -- right - "[combine:16x16:-20,0="..texture, -- back - "[combine:16x16:-4,0="..texture, -- front + -- Note: -x coords go right per-pixel, -y coords go down per-pixel + "[combine:16x16:-36,4=" ..head_def.texture, -- top + "([combine:16x16:-36,4=" ..head_def.texture..")^([combine:16x16:-44,4="..head_def.texture..")", -- bottom + "[combine:16x16:-28,0=" ..head_def.texture, -- left + "[combine:16x16:-44,0=" ..head_def.texture, -- right + "[combine:16x16:-52,0=" ..head_def.texture, -- back + "[combine:16x16:-36,0=" ..head_def.texture, -- front }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - stack_max = 64, - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - selection_box = { - type = "fixed", - fixed = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - }, - sounds = mcl_sounds.node_sound_defaults({ - footstep = {name="default_hard_footstep", gain=0.3} - }), - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - -- no interaction possible with entities, for now. - return itemstack - end - local under = pointed_thing.under - local node = minetest.get_node(under) - local def = minetest.registered_nodes[node.name] - if not def then return itemstack end + _mcl_armor_mob_range_mob = head_def.range_mob, + _mcl_armor_mob_range_factor = head_def.range_factor, + _mcl_armor_texture = head_def.texture + })) - -- Call on_rightclick if the pointed node defines it - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack - end - end - - local above = pointed_thing.above - local diff = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} - local wdir = minetest.dir_to_wallmounted(diff) - - local itemstring = itemstack:get_name() - local fakestack = ItemStack(itemstack) - --local idef = fakestack:get_definition() - local retval - if wdir == 0 or wdir == 1 then - return minetest.item_place(itemstack, placer, pointed_thing) - else - retval = fakestack:set_name("mcl_heads:"..name.."_wall") - end - if not retval then - return itemstack - end - itemstack = minetest.item_place(fakestack, placer, pointed_thing, wdir) - itemstack:set_name(itemstring) - return itemstack - end, - on_secondary_use = equip_armor, - - on_rotate = on_rotate_floor, - - _mcl_armor_mob_range_mob = rangemob, - _mcl_armor_mob_range_factor = rangefactor, - _mcl_armor_element = "head", - _mcl_armor_texture = "mcl_heads_" .. name .. ".png", - _mcl_blast_resistance = 1, - _mcl_hardness = 1, - }) - - minetest.register_node("mcl_heads:"..name.."_wall", { - _doc_items_create_entry = false, - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "wallmounted", - wall_bottom = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - wall_top = { -0.25, 0.0, -0.25, 0.25, 0.5, 0.25, }, - wall_side = { -0.5, -0.25, -0.25, 0.0, 0.25, 0.25, }, - }, - groups = {handy=1, head=1, deco_block=1, dig_by_piston=1, not_in_creative_inventory=1}, - -- The head textures are based off the textures of an actual mob. - tiles = { - { name = "[combine:16x16:-4,-4="..texture, align_style = "world" }, -- front - { name = "[combine:16x16:-20,-4="..texture, align_style = "world" }, -- back - { name = "[combine:16x16:-8,-4="..texture, align_style = "world" }, -- left - { name = "[combine:16x16:0,-4="..texture, align_style = "world" }, -- right - { name = "([combine:16x16:-4,0="..texture..")^[transformR180", align_style = "node" }, -- top - { name = "([combine:16x16:-4,8="..texture..")^([combine:16x16:-12,8="..texture..")", align_style = "node" }, -- bottom - }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - paramtype = "light", - stack_max = 64, - paramtype2 = "wallmounted", - sunlight_propagates = true, - walkable = true, - sounds = mcl_sounds.node_sound_defaults({ - footstep = {name="default_hard_footstep", gain=0.3} - }), - drop = "mcl_heads:"..name, - on_rotate = on_rotate_wall, - _mcl_blast_resistance = 1, - _mcl_hardness = 1, - }) - - if mod_doc then - doc.add_entry_alias("nodes", "mcl_heads:" .. name, "nodes", "mcl_heads:" .. name .. "_wall") + -- register the angled floor head nodes + for i, d in ipairs(mcl_heads.FLOOR_DEGREES) do + minetest.register_node(name ..d, table.update(table.copy(mcl_heads.deftemplate_floor_angled), { + mesh = "mcl_heads_floor" ..d ..".obj", + tiles = { head_def.texture }, + drop = name, + })) end + + -- register the wall head node + minetest.register_node(name .."_wall", table.update(table.copy(mcl_heads.deftemplate_wall), { + -- The head textures are based off the textures of an actual mob. + -- Note: -x coords go right per-pixel, -y coords go down per-pixel + tiles = { + { name = "[combine:16x16:-36,-4=" ..head_def.texture, align_style = "world" }, -- front + { name = "[combine:16x16:-52,-4="..head_def.texture, align_style = "world" }, -- back + { name = "[combine:16x16:-40,-4=" ..head_def.texture, align_style = "world" }, -- right + { name = "[combine:16x16:-32,-4=" ..head_def.texture, align_style = "world" }, -- left + { name = "([combine:16x16:-36,0=" ..head_def.texture ..")^[transformR180", align_style = "node" }, -- top + -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. + -- This is required for skeleton skull and wither skeleton skull. + { name = "([combine:16x16:-36,0=" ..head_def.texture ..")^([combine:16x16:-44,8=" ..head_def.texture..")", align_style = "node" }, -- bottom + }, + drop = name, + })) end --- Add heads -addhead("zombie", "mcl_heads_zombie_node.png", S("Zombie Head"), S("A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%."), "mobs_mc:zombie", 0.5) -addhead("creeper", "mcl_heads_creeper_node.png", S("Creeper Head"), S("A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%."), "mobs_mc:creeper", 0.5) +-- initial heads ------------------------------------------------------------------------------------------------------- + +mcl_heads.register_head{ + name = "zombie", + texture = "mcl_heads_zombie.png", + description = S("Zombie Head"), + longdesc = S("A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%."), + range_mob = "mobs_mc:zombie", + range_factor = 0.5, +} + +mcl_heads.register_head{ + name = "creeper", + texture = "mcl_heads_creeper.png", + description = S("Creeper Head"), + longdesc = S("A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%."), + range_mob = "mobs_mc:creeper", + range_factor = 0.5, +} + -- Original Minecraft name: “Head” -addhead("steve", "mcl_heads_steve_node.png", S("Human Head"), S("A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.")) -addhead("skeleton", "mcl_heads_skeleton_node.png", S("Skeleton Skull"), S("A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%."), "mobs_mc:skeleton", 0.5) -addhead("wither_skeleton", "mcl_heads_wither_skeleton_node.png", S("Wither Skeleton Skull"), S("A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection.")) +mcl_heads.register_head{ + name = "steve", + texture = "mcl_heads_steve.png", + description = S("Human Head"), + longdesc = S("A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection."), +} + +mcl_heads.register_head{ + name = "skeleton", + texture = "mcl_heads_skeleton.png", + description = S("Skeleton Skull"), + longdesc = S("A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%."), + range_mob = "mobs_mc:skeleton", + range_factor = 0.5, +} + +mcl_heads.register_head{ + name = "wither_skeleton", + texture = "mcl_heads_wither_skeleton.png", + description = S("Wither Skeleton Skull"), + longdesc = S("A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection."), +} diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.ja.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.ja.tr new file mode 100644 index 000000000..b3ced046c --- /dev/null +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.ja.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_heads +Zombie Head=ゾンビヘッド +A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.=ゾンビヘッドは、ゾンビの頭を模した小さな装飾ブロックです。ヘルメットとして着用することもでき、ゾンビの探知範囲を50%狭めることができます。 +Creeper Head=クリーパーヘッド +A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%.=クリーパーヘッドは、クリーパーの頭を模した小さな装飾ブロックです。ヘルメットとして着用することもでき、ゾンビの探知範囲を50%狭めることができます。 +Human Head=人の頭 +A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=人の頭は、人間(=プレイヤーキャラ)の頭部を模した小さな装飾ブロックです。遊びでヘルメットとして装着することもできますが、保護機能はありません。 +Skeleton Skull=スケルトンスカル +A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%.=スケルトンスカルは、スケルトンの頭蓋骨を模した小さな装飾ブロックです。ヘルメットとして着用することもでき、ゾンビの探知範囲を50%狭めることができます。 +Wither Skeleton Skull=ウィザースケルトンスカル +A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection.=ウィザースケルトンスカルは、ウィザースケルトンの頭蓋骨を模した小さな装飾ブロックです。ヘルメットとして楽しむこともできますが、保護機能はありません。 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj new file mode 100644 index 000000000..8e48015fc --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor22_5.mtl +o Cube.001 +v -0.326641 -0.500000 0.135299 +v -0.326641 0.000000 0.135299 +v -0.135299 -0.500000 -0.326641 +v -0.135299 0.000000 -0.326641 +v 0.135299 -0.500000 0.326641 +v 0.135299 0.000000 0.326641 +v 0.326641 -0.500000 -0.135299 +v 0.326641 0.000000 -0.135299 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.9239 0.0000 -0.3827 +vn 0.3827 0.0000 -0.9239 +vn 0.9239 0.0000 0.3827 +vn -0.3827 0.0000 0.9239 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.001 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj new file mode 100644 index 000000000..6300d4484 --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor45.mtl +o Cube.002 +v -0.353553 -0.500000 0.000000 +v -0.353553 0.000000 0.000000 +v 0.000000 -0.500000 -0.353553 +v 0.000000 0.000000 -0.353553 +v 0.000000 -0.500000 0.353553 +v 0.000000 0.000000 0.353553 +v 0.353553 -0.500000 0.000000 +v 0.353553 0.000000 0.000000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 0.7071 +vn -0.7071 0.0000 0.7071 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.002 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj new file mode 100644 index 000000000..0fe5567e3 --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor67_5.mtl +o Cube.003 +v -0.326641 -0.500000 -0.135299 +v -0.326641 0.000000 -0.135299 +v 0.135299 -0.500000 -0.326641 +v 0.135299 0.000000 -0.326641 +v -0.135299 -0.500000 0.326641 +v -0.135299 0.000000 0.326641 +v 0.326641 -0.500000 0.135299 +v 0.326641 0.000000 0.135299 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.3827 0.0000 -0.9239 +vn 0.9239 0.0000 -0.3827 +vn 0.3827 0.0000 0.9239 +vn -0.9239 0.0000 0.3827 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.003 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png deleted file mode 100644 index 99b432ac6..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png deleted file mode 100644 index 0af86cd6a..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png index 361795a52..471a8b3c8 100644 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png and b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png deleted file mode 100644 index 43c1beb5a..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png deleted file mode 100644 index 671f40547..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png deleted file mode 100644 index ef85701e8..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_honey/init.lua b/mods/ITEMS/mcl_honey/init.lua new file mode 100644 index 000000000..82e3d0995 --- /dev/null +++ b/mods/ITEMS/mcl_honey/init.lua @@ -0,0 +1,147 @@ +--------------- +---- Honey ---- +--------------- + +-- Variables +local S = minetest.get_translator(minetest.get_current_modname()) +local alldirs = {{x=0,y=0,z=1}, {x=1,y=0,z=0}, {x=0,y=0,z=-1}, {x=-1,y=0,z=0}, {x=0,y=-1,z=0}, {x=0,y=1,z=0}} + +-- Honeycomb +minetest.register_craftitem("mcl_honey:honeycomb", { + description = S("Honeycomb"), + _doc_items_longdesc = S("Used to craft beehives and protect copper blocks from further oxidation."), + _doc_items_usagehelp = S("Use on copper blocks to prevent further oxidation."), + inventory_image = "mcl_honey_honeycomb.png", + groups = { craftitem = 1 }, +}) + +minetest.register_node("mcl_honey:honeycomb_block", { + description = S("Honeycomb Block"), + _doc_items_longdesc = S("Honeycomb Block. Used as a decoration."), + tiles = { + "mcl_honey_honeycomb_block.png" + }, + groups = { handy = 1, deco_block = 1 }, + sounds = { + dig = {name="slimenodes_dug", gain=0.6, pitch=1.2}, + dug = {name="slimenodes_dug", gain=0.6}, + place = {name="slimenodes_place", gain=0.6}, + footstep = {name="slimenodes_step", gain=0.3}, + }, + _mcl_blast_resistance = 0.6, + _mcl_hardness = 0.6, +}) + +-- Honey +minetest.register_craftitem("mcl_honey:honey_bottle", { + description = S("Honey Bottle"), + _doc_items_longdesc = S("Honey Bottle is used to craft honey blocks and to restore hunger points."), + _doc_items_usagehelp = S("Drinking will restore 6 hunger points. Can also be used to craft honey blocks."), + inventory_image = "mcl_honey_honey_bottle.png", + groups = { craftitem = 1, food = 3, eatable = 6, can_eat_when_full=1 }, + on_place = minetest.item_eat(6, "mcl_potions:glass_bottle"), + on_secondary_use = minetest.item_eat(6, "mcl_potions:glass_bottle"), + _mcl_saturation = 1.2, + stack_max = 16, +}) + +minetest.register_node("mcl_honey:honey_block", { + description = S("Honey Block"), + _doc_items_longdesc = S("Honey Block. Used as a decoration and in redstone. Is sticky on some sides."), + tiles = {"mcl_honey_block_side.png"}, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, + groups = { handy = 1, deco_block = 1, fall_damage_add_percent = -80 }, + sounds = { + dug = {name="slimenodes_dug", gain=0.6}, + place = {name="slimenodes_place", gain=0.6}, + footstep = {name="slimenodes_step", gain=0.3}, + }, + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.4, -0.4, -0.4, 0.4, 0.4, 0.4}, + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + } + }, + selection_box = { + type = "regular", + }, + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + mvps_sticky = function(pos, node, piston_pos) + local connected = {} + for n, v in ipairs(alldirs) do + local neighbor_pos = vector.add(pos, v) + local neighbor_node = minetest.get_node(neighbor_pos) + if neighbor_node then + if neighbor_node.name == "ignore" then + minetest.get_voxel_manip():read_from_map(neighbor_pos, neighbor_pos) + neighbor_node = minetest.get_node(neighbor_pos) + end + local name = neighbor_node.name + if name ~= "air" and name ~= "ignore" and not mesecon.mvps_unsticky[name] then + local piston, piston_side, piston_up, piston_down = false, false, false, false + if name == "mesecons_pistons:piston_sticky_off" or name == "mesecons_pistons:piston_normal_off" then + piston, piston_side = true, true + elseif name == "mesecons_pistons:piston_up_sticky_off" or name == "mesecons_pistons:piston_up_normal_off" then + piston, piston_up = true, true + elseif name == "mesecons_pistons:piston_down_sticky_off" or name == "mesecons_pistons:piston_down_normal_off" then + piston, piston_down = true, true + end + if not( (piston_side and (n-1==neighbor_node.param2)) or (piston_up and (n==5)) or (piston_down and (n==6)) ) then + if piston and piston_pos then + if piston_pos.x == neighbor_pos.x and piston_pos.y == neighbor_pos.y and piston_pos.z == neighbor_pos.z then + -- Loopback to the same piston! Preventing unwanted behavior: + return {}, true + end + end + table.insert(connected, neighbor_pos) + end + end + end + end + return connected, false + end, +}) + +-- Crafting +minetest.register_craft({ + output = "mcl_honey:honeycomb_block", + recipe = { + { "mcl_honey:honeycomb", "mcl_honey:honeycomb" }, + { "mcl_honey:honeycomb", "mcl_honey:honeycomb" }, + }, +}) + +minetest.register_craft({ + output = "mcl_honey:honey_block", + recipe = { + { "mcl_honey:honey_bottle", "mcl_honey:honey_bottle" }, + { "mcl_honey:honey_bottle", "mcl_honey:honey_bottle" }, + }, + replacements = { + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + }, +}) + +minetest.register_craft({ + output = "mcl_honey:honey_bottle 4", + recipe = { + { "mcl_potions:glass_bottle", "mcl_potions:glass_bottle", "mcl_honey:honey_block" }, + { "mcl_potions:glass_bottle", "mcl_potions:glass_bottle", "" }, + }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_core:sugar 3", + recipe = { "mcl_honey:honey_bottle" }, + replacements = { + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + }, +}) diff --git a/mods/ITEMS/mcl_honey/locale/mcl_honey.ja.tr b/mods/ITEMS/mcl_honey/locale/mcl_honey.ja.tr new file mode 100644 index 000000000..4cb018f84 --- /dev/null +++ b/mods/ITEMS/mcl_honey/locale/mcl_honey.ja.tr @@ -0,0 +1,10 @@ +Honeycomb=ハニカム +Used to craft beehives and protect copper blocks from further oxidation.=ハチの巣を作ったり、銅ブロックがこれ以上酸化しないように保護するために使われます。 +Use on copper blocks to prevent further oxidation.=銅ブロックに使用すると、これ以上の酸化を防げます。 +Honeycomb Block=ハニカムブロック +Honeycomb Block. Used as a decoration.=ハニカムブロック。装飾用です。 +Honey Bottle=ハチミツ入り瓶 +Honey Bottle is used to craft honey blocks and to restore hunger points.=ハチミツ入り瓶は、ハチミツブロックの製造や満腹度回復に使用します。 +Drinking will restore 6 hunger points. Can also be used to craft honey blocks.=飲むと満腹度が6回復します。また、ハチミツブロックを作るのにも使えます。 +Honey Block=ハチミツブロック +Honey Block. Used as a decoration and in redstone. Is sticky on some sides.=ハチミツブロック。装飾品として、またはレッドストーン機構の部品として利用します。側面には粘着性があります。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_honey/locale/template.txt b/mods/ITEMS/mcl_honey/locale/template.txt new file mode 100644 index 000000000..a9814d617 --- /dev/null +++ b/mods/ITEMS/mcl_honey/locale/template.txt @@ -0,0 +1,10 @@ +Honeycomb= +Used to craft beehives and protect copper blocks from further oxidation.= +Use on copper blocks to prevent further oxidation.= +Honeycomb Block= +Honeycomb Block. Used as a decoration.= +Honey Bottle= +Honey Bottle is used to craft honey blocks and to restore hunger points.= +Drinking will restore 6 hunger points. Can also be used to craft honey blocks.= +Honey Block= +Honey Block. Used as a decoration and in redstone. Is sticky on some sides.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_honey/mod.conf b/mods/ITEMS/mcl_honey/mod.conf new file mode 100644 index 000000000..436811291 --- /dev/null +++ b/mods/ITEMS/mcl_honey/mod.conf @@ -0,0 +1,4 @@ +name = mcl_honey +author = PrairieWind +description = MineClone 2 mod that adds honey and honeycomb and the respective block versions. +depends = mesecons_mvps diff --git a/mods/ITEMS/mcl_honey/textures/mcl_honey_block_bottom.png b/mods/ITEMS/mcl_honey/textures/mcl_honey_block_bottom.png new file mode 100644 index 000000000..9de965284 Binary files /dev/null and b/mods/ITEMS/mcl_honey/textures/mcl_honey_block_bottom.png differ diff --git a/mods/ITEMS/mcl_honey/textures/mcl_honey_block_side.png b/mods/ITEMS/mcl_honey/textures/mcl_honey_block_side.png new file mode 100644 index 000000000..4cdecfb03 Binary files /dev/null and b/mods/ITEMS/mcl_honey/textures/mcl_honey_block_side.png differ diff --git a/mods/ITEMS/mcl_honey/textures/mcl_honey_block_top.png b/mods/ITEMS/mcl_honey/textures/mcl_honey_block_top.png new file mode 100644 index 000000000..c2f330440 Binary files /dev/null and b/mods/ITEMS/mcl_honey/textures/mcl_honey_block_top.png differ diff --git a/mods/ITEMS/mcl_honey/textures/mcl_honey_honey_bottle.png b/mods/ITEMS/mcl_honey/textures/mcl_honey_honey_bottle.png new file mode 100644 index 000000000..16956f56e Binary files /dev/null and b/mods/ITEMS/mcl_honey/textures/mcl_honey_honey_bottle.png differ diff --git a/mods/ITEMS/mcl_honey/textures/mcl_honey_honeycomb.png b/mods/ITEMS/mcl_honey/textures/mcl_honey_honeycomb.png new file mode 100644 index 000000000..a590d517a Binary files /dev/null and b/mods/ITEMS/mcl_honey/textures/mcl_honey_honeycomb.png differ diff --git a/mods/ITEMS/mcl_honey/textures/mcl_honey_honeycomb_block.png b/mods/ITEMS/mcl_honey/textures/mcl_honey_honeycomb_block.png new file mode 100644 index 000000000..42c4ce85e Binary files /dev/null and b/mods/ITEMS/mcl_honey/textures/mcl_honey_honeycomb_block.png differ diff --git a/mods/ITEMS/mcl_hoppers/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index 87831490f..258767aad 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -1,30 +1,48 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_hoppers", false) +local function mcl_log(message) + if LOGGING_ON then + mcl_util.mcl_log(message, "[Hoppers]", true) + end +end --[[ BEGIN OF NODE DEFINITIONS ]] -local mcl_hoppers_formspec = - "size[9,7]".. - "label[2,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Hopper"))).."]".. - "list[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[context;main]".. - "listring[current_player;main]" +local mcl_hoppers_formspec = table.concat({ + "size[9,7]", + "label[2,0;" .. F(C("#313131", S("Hopper"))) .. "]", + "list[context;main;2,0.5;5,1;]", + mcl_formspec.get_itemslot_bg(2, 0.5, 5, 1), + "label[0,2;" .. F(C("#313131", S("Inventory"))) .. "]", + "list[current_player;main;0,2.5;9,3;9]", + mcl_formspec.get_itemslot_bg(0, 2.5, 9, 3), + "list[current_player;main;0,5.74;9,1;]", + mcl_formspec.get_itemslot_bg(0, 5.74, 9, 1), + "listring[context;main]", + "listring[current_player;main]", +}) -- Downwards hopper (base definition) +---@type node_definition local def_hopper = { inventory_image = "mcl_hoppers_item.png", wield_image = "mcl_hoppers_item.png", - groups = {pickaxey=1, container=2,deco_block=1,hopper=1}, + groups = {pickaxey = 1, container = 2, deco_block = 1, hopper = 1}, drawtype = "nodebox", paramtype = "light", -- FIXME: mcl_hoppers_hopper_inside.png is unused by hoppers. - tiles = {"mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png"}, + tiles = { + "mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + }, node_box = { type = "fixed", fixed = { @@ -64,10 +82,10 @@ local def_hopper = { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for i=1,inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5) minetest.add_item(p, stack) end end @@ -101,16 +119,16 @@ local def_hopper = { end end, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in mcl_hoppers at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to mcl_hoppers at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from mcl_hoppers at " .. minetest.pos_to_string(pos)) end, sounds = mcl_sounds.node_sound_metal_defaults(), @@ -124,18 +142,22 @@ local def_hopper = { -- Enabled downwards hopper local def_hopper_enabled = table.copy(def_hopper) def_hopper_enabled.description = S("Hopper") -def_hopper_enabled._tt_help = S("5 inventory slots").."\n"..S("Collects items from above, moves items to container below").."\n"..S("Can be disabled with redstone power") -def_hopper_enabled._doc_items_longdesc = S("Hoppers are containers with 5 inventory slots. They collect dropped items from above, take items from a container above and attempt to put its items it into an adjacent container. Hoppers can go either downwards or sideways. Hoppers interact with chests, droppers, dispensers, shulker boxes, furnaces and hoppers.").."\n\n".. +def_hopper_enabled._tt_help = S("5 inventory slots") .. + "\n" .. S("Collects items from above, moves items to container below") .. "\n" .. + S("Can be disabled with redstone power") +def_hopper_enabled._doc_items_longdesc = S("Hoppers are containers with 5 inventory slots. They collect dropped items from above, take items from a container above and attempt to put its items it into an adjacent container. Hoppers can go either downwards or sideways. Hoppers interact with chests, droppers, dispensers, shulker boxes, furnaces and hoppers.") + .. "\n\n" .. -S("Hoppers interact with containers the following way:").."\n".. -S("• Furnaces: Hoppers from above will put items into the source slot. Hoppers from below take items from the output slot. They also take items from the fuel slot when they can't be used as a fuel. Sideway hoppers that point to the furnace put items into the fuel slot").."\n".. -S("• Ender chests: No interaction.").."\n".. -S("• Other containers: Normal interaction.").."\n\n".. + S("Hoppers interact with containers the following way:") .. "\n" .. + S("• Furnaces: Hoppers from above will put items into the source slot. Hoppers from below take items from the output slot. They also take items from the fuel slot when they can't be used as a fuel. Sideway hoppers that point to the furnace put items into the fuel slot") + .. "\n" .. + S("• Ender chests: No interaction.") .. "\n" .. + S("• Other containers: Normal interaction.") .. "\n\n" .. -S("Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.") + S("Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.") def_hopper_enabled._doc_items_usagehelp = S("To place a hopper vertically, place it on the floor or a ceiling. To place it sideways, place it at the side of a block. Use the hopper to access its inventory.") def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing) - local upos = pointed_thing.under + local upos = pointed_thing.under local apos = pointed_thing.above local uposnode = minetest.get_node(upos) @@ -166,21 +188,22 @@ def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing) fake_itemstack:set_name("mcl_hoppers:hopper_side") param2 = 1 end - local itemstack,_ = minetest.item_place_node(fake_itemstack, placer, pointed_thing, param2) + local itemstack, _ = minetest.item_place_node(fake_itemstack, placer, pointed_thing, param2) itemstack:set_name("mcl_hoppers:hopper") return itemstack end def_hopper_enabled.mesecons = { effector = { action_on = function(pos, node) - minetest.swap_node(pos, {name="mcl_hoppers:hopper_disabled", param2=node.param2}) + minetest.swap_node(pos, {name = "mcl_hoppers:hopper_disabled", param2 = node.param2}) end, }, } minetest.register_node("mcl_hoppers:hopper", def_hopper_enabled) --- Disabled downwards hopper +---Disabled downwards hopper +---@type node_definition local def_hopper_disabled = table.copy(def_hopper) def_hopper_disabled.description = S("Disabled Hopper") def_hopper_disabled.inventory_image = nil @@ -190,7 +213,7 @@ def_hopper_disabled.drop = "mcl_hoppers:hopper" def_hopper_disabled.mesecons = { effector = { action_off = function(pos, node) - minetest.swap_node(pos, {name="mcl_hoppers:hopper", param2=node.param2}) + minetest.swap_node(pos, {name = "mcl_hoppers:hopper", param2 = node.param2}) end, }, } @@ -204,15 +227,23 @@ if minetest.get_modpath("screwdriver") then on_rotate = screwdriver.rotate_simple end --- Sidewars hopper (base definition) +---Sidewars hopper (base definition) +---@type node_definition local def_hopper_side = { _doc_items_create_entry = false, drop = "mcl_hoppers:hopper", - groups = {pickaxey=1, container=2,not_in_creative_inventory=1,hopper=2}, + groups = {pickaxey = 1, container = 2, not_in_creative_inventory = 1, hopper = 2}, drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir", - tiles = {"mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png"}, + tiles = { + "mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + }, node_box = { type = "fixed", fixed = { @@ -252,10 +283,10 @@ local def_hopper_side = { local meta2 = meta meta:from_table(oldmetadata) local inv = meta:get_inventory() - for i=1,inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5) minetest.add_item(p, stack) end end @@ -289,16 +320,16 @@ local def_hopper_side = { end end, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in mcl_hoppers at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to mcl_hoppers at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from mcl_hoppers at " .. minetest.pos_to_string(pos)) end, on_rotate = on_rotate, sounds = mcl_sounds.node_sound_metal_defaults(), @@ -307,23 +338,25 @@ local def_hopper_side = { _mcl_hardness = 3, } +---@type node_definition local def_hopper_side_enabled = table.copy(def_hopper_side) def_hopper_side_enabled.description = S("Side Hopper") def_hopper_side_enabled.mesecons = { effector = { action_on = function(pos, node) - minetest.swap_node(pos, {name="mcl_hoppers:hopper_side_disabled", param2=node.param2}) + minetest.swap_node(pos, {name = "mcl_hoppers:hopper_side_disabled", param2 = node.param2}) end, }, } minetest.register_node("mcl_hoppers:hopper_side", def_hopper_side_enabled) +---@type node_definition local def_hopper_side_disabled = table.copy(def_hopper_side) def_hopper_side_disabled.description = S("Disabled Side Hopper") def_hopper_side_disabled.mesecons = { effector = { action_off = function(pos, node) - minetest.swap_node(pos, {name="mcl_hoppers:hopper_side", param2=node.param2}) + minetest.swap_node(pos, {name = "mcl_hoppers:hopper_side", param2 = node.param2}) end, }, } @@ -331,16 +364,102 @@ minetest.register_node("mcl_hoppers:hopper_side_disabled", def_hopper_side_disab --[[ END OF NODE DEFINITIONS ]] +local function hopper_pull_from_mc(mc_ent, dest_pos, inv_size) + local inv = mcl_entity_invs.load_inv(mc_ent, inv_size) + if not inv then + mcl_log("No inv") + return false + end + + local dest_meta = minetest.get_meta(dest_pos) + local dest_inv = dest_meta:get_inventory() + if not dest_inv then + mcl_log("No dest inv") + return + end + + mcl_log("inv. size: " .. mc_ent._inv_size) + for i = 1, mc_ent._inv_size, 1 do + local stack = inv:get_stack("main", i) + + mcl_log("i: " .. tostring(i)) + mcl_log("Name: [" .. tostring(stack:get_name()) .. "]") + mcl_log("Count: " .. tostring(stack:get_count())) + mcl_log("stack max: " .. tostring(stack:get_stack_max())) + + if not stack:get_name() or stack:get_name() ~= "" then + if dest_inv:room_for_item("main", stack:peek_item()) then + mcl_log("Room so unload") + dest_inv:add_item("main", stack:take_item()) + inv:set_stack("main", i, stack) + + -- Take one item and stop until next time + return + else + mcl_log("no Room") + end + + else + mcl_log("nothing there") + end + end +end + --[[ BEGIN OF ABM DEFINITONS ]] +minetest.register_abm({ + label = "Hoppers pull from minecart hoppers", + nodenames = {"mcl_hoppers:hopper", "mcl_hoppers:hopper_side"}, + interval = 0.5, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + mcl_log("ABM for: " .. minetest.pos_to_string(pos)) + local objs = minetest.get_objects_inside_radius(pos, 3) + + if objs and #objs > 0 then + for k, v in pairs(objs) do + local entity = v:get_luaentity() + if entity and entity.name then + --mcl_log("Name of object near: " .. tostring(entity.name)) + + if entity.name == "mcl_minecarts:hopper_minecart" or entity.name == "mcl_minecarts:chest_minecart" then + local hm_pos = entity.object:get_pos() + mcl_log("We have a minecart with inventory close: " .. minetest.pos_to_string(hm_pos)) + + --if hm_pos.y == pos.y + 1 then mcl_log("y is correct") end + --if (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC) then mcl_log("x is within range") end + --if (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then mcl_log("z is within range") end + + local DIST_FROM_MC = 1.5 + if (hm_pos.y == pos.y + 1) + and (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC) + and (hm_pos.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then + mcl_log("Minecart close enough") + if entity.name == "mcl_minecarts:hopper_minecart" then + hopper_pull_from_mc(entity, pos, 5) + elseif entity.name == "mcl_minecarts:chest_minecart" then + hopper_pull_from_mc(entity, pos, 27) + end + end + end + else + mcl_log("no entity") + end + end + else + mcl_log("objs missing") + end + end, +}) + -- Make hoppers suck in dropped items minetest.register_abm({ label = "Hoppers suck in dropped items", - nodenames = {"mcl_hoppers:hopper","mcl_hoppers:hopper_side"}, + nodenames = {"mcl_hoppers:hopper", "mcl_hoppers:hopper_side"}, interval = 1.0, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local abovenode = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}) + local abovenode = minetest.get_node(vector.offset(pos, 0, 1, 0)) if not minetest.registered_items[abovenode.name] then return end -- Don't bother checking item enties if node above is a container (should save some CPU) if minetest.get_item_group(abovenode.name, "container") ~= 0 then @@ -349,15 +468,16 @@ minetest.register_abm({ 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" and not object:get_luaentity()._removed then + for _, object in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and + not object:get_luaentity()._removed then if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then -- Item must get sucked in when the item just TOUCHES the block above the hopper -- This is the reason for the Y calculation. -- Test: Items on farmland and slabs get sucked, but items on full blocks don't local posob = object:get_pos() local posob_miny = posob.y + object:get_properties().collisionbox[2] - if math.abs(posob.x-pos.x) <= 0.5 and (posob_miny-pos.y < 1.5 and posob.y-pos.y >= 0.3) then + if math.abs(posob.x - pos.x) <= 0.5 and (posob_miny - pos.y < 1.5 and posob.y - pos.y >= 0.3) then inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) object:get_luaentity().itemstring = "" object:remove() @@ -368,8 +488,14 @@ minetest.register_abm({ end, }) --- Returns true if itemstack is fuel, but not for lava bucket if destination already has one -local is_transferrable_fuel = function(itemstack, src_inventory, src_list, dst_inventory, dst_list) +---Returns true if itemstack is fuel, but not for lava bucket if destination already has one +---@param itemstack ItemStack +---@param src_inventory InvRef +---@param src_list string +---@param dst_inventory InvRef +---@param dst_list string +---@return boolean +local function is_transferrable_fuel(itemstack, src_inventory, src_list, dst_inventory, dst_list) if mcl_util.is_fuel(itemstack) then if itemstack:get_name() == "mcl_buckets:bucket_lava" then return dst_inventory:is_empty(dst_list) @@ -381,8 +507,6 @@ local is_transferrable_fuel = function(itemstack, src_inventory, src_list, dst_i end end - - minetest.register_abm({ label = "Hopper/container item exchange", nodenames = {"mcl_hoppers:hopper"}, @@ -391,8 +515,8 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) -- Get node pos' for item transfer - local uppos = {x=pos.x,y=pos.y+1,z=pos.z} - local downpos = {x=pos.x,y=pos.y-1,z=pos.z} + local uppos = vector.offset(pos, 0, 1, 0) + local downpos = vector.offset(pos, 0, -1, 0) -- Suck an item from the container above into the hopper local upnode = minetest.get_node(uppos) @@ -402,7 +526,7 @@ minetest.register_abm({ -- Also suck in non-fuel items from furnace fuel slot if not sucked and g == 4 then - local finv = minetest.get_inventory({type="node", pos=uppos}) + local finv = minetest.get_inventory({type = "node", pos = uppos}) if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then mcl_util.move_item_container(uppos, pos, "fuel") end @@ -426,15 +550,15 @@ minetest.register_abm({ local face = minetest.get_node(pos).param2 local front = {} if face == 0 then - front = {x=pos.x-1,y=pos.y,z=pos.z} + front = vector.offset(pos, -1, 0, 0) elseif face == 1 then - front = {x=pos.x,y=pos.y,z=pos.z+1} + front = vector.offset(pos, 0, 0, 1) elseif face == 2 then - front = {x=pos.x+1,y=pos.y,z=pos.z} + front = vector.offset(pos, 1, 0, 0) elseif face == 3 then - front = {x=pos.x,y=pos.y,z=pos.z-1} + front = vector.offset(pos, 0, 0, -1) end - local above = {x=pos.x,y=pos.y+1,z=pos.z} + local above = vector.offset(pos, 0, 1, 0) local frontnode = minetest.get_node(front) if not minetest.registered_nodes[frontnode.name] then return end @@ -447,7 +571,7 @@ minetest.register_abm({ -- Also suck in non-fuel items from furnace fuel slot if not sucked and g == 4 then - local finv = minetest.get_inventory({type="node", pos=above}) + local finv = minetest.get_inventory({type = "node", pos = above}) if finv and not mcl_util.is_fuel(finv:get_stack("fuel", 1)) then mcl_util.move_item_container(above, pos, "fuel") end @@ -459,9 +583,9 @@ minetest.register_abm({ mcl_util.move_item_container(pos, front) elseif g == 4 then -- Put fuel into fuel slot - local sinv = minetest.get_inventory({type="node", pos = pos}) - local dinv = minetest.get_inventory({type="node", pos = front}) - local slot_id,_ = mcl_util.get_eligible_transfer_item_slot(sinv, "main", dinv, "fuel", is_transferrable_fuel) + local sinv = minetest.get_inventory({type = "node", pos = pos}) + local dinv = minetest.get_inventory({type = "node", pos = front}) + local slot_id, _ = mcl_util.get_eligible_transfer_item_slot(sinv, "main", dinv, "fuel", is_transferrable_fuel) if slot_id then mcl_util.move_item_container(pos, front, nil, slot_id, "fuel") end @@ -469,13 +593,124 @@ minetest.register_abm({ end }) +if minetest.get_modpath("mcl_composters") then + minetest.register_abm({ + label = "Bonemeal extraction from composter", + nodenames = {"mcl_hoppers:hopper", "mcl_hoppers:hopper_side"}, + neighbors = {"mcl_composters:composter_ready"}, + interval = 1.0, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local uppos = vector.offset(pos, 0, 1, 0) + --local downpos = vector.offset(pos, 0, -1, 0) + + -- Get bonemeal from composter above + local upnode = minetest.get_node(uppos) + if upnode.name == "mcl_composters:composter_ready" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + minetest.swap_node(uppos, {name = "mcl_composters:composter"}) + + inv:add_item("main", "mcl_bone_meal:bone_meal") + end + end, + }) + + ---@param node node + ---@return integer? + ---@nodiscard + local function composter_level(node) + local nn = node.name + if nn == "mcl_composters:composter" then + return 0 + elseif nn == "mcl_composters:composter_1" then + return 1 + elseif nn == "mcl_composters:composter_2" then + return 2 + elseif nn == "mcl_composters:composter_3" then + return 3 + elseif nn == "mcl_composters:composter_4" then + return 4 + elseif nn == "mcl_composters:composter_5" then + return 5 + elseif nn == "mcl_composters:composter_6" then + return 6 + elseif nn == "mcl_composters:composter_7" then + return 7 + else + return nil + end + end + + for i = 1, 7 do + assert(composter_level({name = "mcl_composters:composter_" .. i}) == i) + end + + assert(composter_level({name = "mcl_composters:composter"}) == 0) + assert(composter_level({name = "mcl_composters:some_other_node"}) == nil) + + minetest.register_abm({ + label = "Add compostable items on composter", + nodenames = {"mcl_hoppers:hopper"}, + neighbors = { + "mcl_composters:composter", + "mcl_composters:composter_1", + "mcl_composters:composter_2", + "mcl_composters:composter_3", + "mcl_composters:composter_4", + "mcl_composters:composter_5", + "mcl_composters:composter_6", + "mcl_composters:composter_7", + }, + interval = 1.0, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + --local uppos = vector.offset(pos, 0, 1, 0) + local downpos = vector.offset(pos, 0, -1, 0) + + local downnode = minetest.get_node(downpos) + + ---@type integer|string|nil + local level = composter_level(downnode) + + --Consume compostable items and update composter below + if level then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + for i = 1, 5 do + local stack = inv:get_stack("main", i) + local compchance = minetest.get_item_group(stack:get_name(), "compostability") + + if compchance > 0 then + stack:take_item() + inv:set_stack("main", i, stack) + + if compchance >= math.random(0, 100) then + mcl_dye.add_bone_meal_particle(vector.offset(downpos, 0, level / 8, 0)) + if level < 7 then + level = level + 1 + else + level = "ready" + end + minetest.swap_node(downpos, {name = "mcl_composters:composter_" .. level}) + end + break + end + end + end + end, + }) +end + minetest.register_craft({ output = "mcl_hoppers:hopper", recipe = { - {"mcl_core:iron_ingot","","mcl_core:iron_ingot"}, - {"mcl_core:iron_ingot","mcl_chests:chest","mcl_core:iron_ingot"}, - {"","mcl_core:iron_ingot",""}, - } + {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot", "mcl_chests:chest", "mcl_core:iron_ingot"}, + {"", "mcl_core:iron_ingot", ""}, + }, }) -- Add entry aliases for the Help @@ -489,7 +724,7 @@ minetest.register_alias("mcl_hoppers:hopper_item", "mcl_hoppers:hopper") minetest.register_lbm({ label = "Update hopper formspecs (0.60.0", name = "mcl_hoppers:update_formspec_0_60_0", - nodenames = { "group:hopper" }, + nodenames = {"group:hopper"}, run_at_every_load = false, action = function(pos, node) local meta = minetest.get_meta(pos) diff --git a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ja.tr b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ja.tr new file mode 100644 index 000000000..81d32f48c --- /dev/null +++ b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ja.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_hoppers +Hopper=ホッパー +Hoppers are containers with 5 inventory slots. They collect dropped items from above, take items from a container above and attempt to put its items it into an adjacent container. Hoppers can go either downwards or sideways. Hoppers interact with chests, droppers, dispensers, shulker boxes, furnaces and hoppers.=ホッパーは、5つのインベントリースロットを持つコンテナです。それらは上から落ちてくるアイテムを集めたり、上のコンテナからアイテムを取ったり、そのアイテムを隣のコンテナに入れようとします。ホッパーは下方向にも横方向にも移送することができます。ホッパーはチェスト、ドロッパー、ディスペンサー、シュルカーボックス、かまど、ホッパーと相互作用します。 +Hoppers interact with containers the following way:=ホッパーはコンテナ類と次のように相互作用: +• Furnaces: Hoppers from above will put items into the source slot. Hoppers from below take items from the output slot. They also take items from the fuel slot when they can't be used as a fuel. Sideway hoppers that point to the furnace put items into the fuel slot=かまど: 上方のホッパーは、アイテムを供給スロットに投入します。下方のホッパーは、出力スロットからアイテムを取り出します。また、燃料として使用できないアイテムは燃料スロットから取り出します。かまどの方を向いている横向きのホッパーは、燃料スロットにアイテムを投入します +• Ender chests: No interaction.=エンダーチェスト: 相互作用なし。 +• Other containers: Normal interaction.=その他のコンテナ: 通常の相互作用。 +Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.=ホッパーは、レッドストーン動力を供給すると無効化できます。無効化されたホッパーは、アイテムを移動させません。 +To place a hopper vertically, place it on the floor or a ceiling. To place it sideways, place it at the side of a block. Use the hopper to access its inventory.=ホッパーを縦に置く場合は、床または天井に設置します。横向きに設置する場合は、ブロックの横に設置します。ホッパーを使用すると、インベントリにアクセスできます。 +Disabled Hopper=無効化されたホッパー +Side Hopper=サイドホッパー +Disabled Side Hopper=無効化されたサイドホッパー +Inventory=インベントリ +5 inventory slots=5つのインベントリースロット +Collects items from above, moves items to container below=上からのアイテムを集め、下のコンテナに移動 +Can be disabled with redstone power=レッドストーン動力で無効化可能 diff --git a/mods/ITEMS/mcl_hoppers/mod.conf b/mods/ITEMS/mcl_hoppers/mod.conf index c89292f6b..639a5f59e 100644 --- a/mods/ITEMS/mcl_hoppers/mod.conf +++ b/mods/ITEMS/mcl_hoppers/mod.conf @@ -1,4 +1,4 @@ name = mcl_hoppers description = It's just a clone of Minecraft hoppers, functions nearly identical to them minus mesecons making them stop and the way they're placed. -depends = mcl_core, mcl_formspec, mcl_sounds, mcl_util +depends = mcl_core, mcl_formspec, mcl_sounds, mcl_util, mcl_dye optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_itemframes/README.txt b/mods/ITEMS/mcl_itemframes/README.txt index d9514a03b..c2756a1c9 100644 --- a/mods/ITEMS/mcl_itemframes/README.txt +++ b/mods/ITEMS/mcl_itemframes/README.txt @@ -1,4 +1,13 @@ -This mod is originally by Zeg9, but heavily modified for MineClone 2. +This mod has been rewritten and revamped by Michieal / Faerraven. Based on the code originally done by Zeg9, and then +heavily modified by the Mineclone 2 dev team. + +This mod now supports all the base item frame functions, like rotating the displayed item, which it didn't do before it +was rewritten. Additionally, Glow Frames have been added in, and item frames now has an API to allow new item frames to +be created in other modules. +Now requires the Screwdriver to have full functionality. + +The code is licenced under the standard MineClone 2 license for usage, with the requirement that this readme is +included in the code / module. Model created by 22i, licensed under the GNU GPLv3 . diff --git a/mods/ITEMS/mcl_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua index 364bffee6..553198c67 100644 --- a/mods/ITEMS/mcl_itemframes/init.lua +++ b/mods/ITEMS/mcl_itemframes/init.lua @@ -1,343 +1,40 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + local S = minetest.get_translator(minetest.get_current_modname()) -local VISUAL_SIZE = 0.3 +-- mcl_itemframes API +dofile(modpath .. "/item_frames_API.lua") -minetest.register_entity("mcl_itemframes:item",{ - hp_max = 1, - visual = "wielditem", - visual_size = {x=VISUAL_SIZE, y=VISUAL_SIZE}, - physical = false, - pointable = false, - textures = { "blank.png" }, - _texture = "blank.png", - _scale = 1, +-- actual api initialization. +mcl_itemframes.create_base_definitions() - on_activate = function(self, staticdata) - if staticdata and staticdata ~= "" then - local data = staticdata:split(";") - if data and data[1] and data[2] then - self._nodename = data[1] - self._texture = data[2] - if data[3] then - self._scale = data[3] - else - self._scale = 1 - end - end - end - if self._texture then - self.object:set_properties({ - textures={self._texture}, - visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale}, - }) - end - end, - get_staticdata = function(self) - if self._nodename and self._texture then - local ret = self._nodename .. ";" .. self._texture - if self._scale then - ret = ret .. ";" .. self._scale - end - return ret - end - return "" - end, +-- necessary to maintain compatibility amongst older versions. +mcl_itemframes.backwards_compatibility() - _update_texture = function(self) - if self._texture then - self.object:set_properties({ - textures={self._texture}, - visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale}, - }) - end - end, -}) - -minetest.register_entity("mcl_itemframes:map", { - initial_properties = { - visual = "upright_sprite", - visual_size = {x = 1, y = 1}, - pointable = false, - physical = false, - collide_with_objects = false, - textures = {"blank.png"}, - }, - on_activate = function(self, staticdata) - self.id = staticdata - self.object:set_properties({textures = {mcl_maps.load_map(self.id)}}) - end, - get_staticdata = function(self) - return self.id - end, -}) - - -local facedir = {} -facedir[0] = {x=0,y=0,z=1} -facedir[1] = {x=1,y=0,z=0} -facedir[2] = {x=0,y=0,z=-1} -facedir[3] = {x=-1,y=0,z=0} - -local remove_item_entity = function(pos, node) - if node.name == "mcl_itemframes:item_frame" then - for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do - local entity = obj:get_luaentity() - if entity and (entity.name == "mcl_itemframes:item" or entity.name == "mcl_itemframes:map") then - obj:remove() - end - end - end -end - -local update_item_entity = function(pos, node, param2) - remove_item_entity(pos, node) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local item = inv:get_stack("main", 1) - if not item:is_empty() then - if not param2 then - param2 = node.param2 - end - if node.name == "mcl_itemframes:item_frame" then - local posad = facedir[param2] - pos.x = pos.x + posad.x*6.5/16 - pos.y = pos.y + posad.y*6.5/16 - pos.z = pos.z + posad.z*6.5/16 - end - local yaw = math.pi*2 - param2 * math.pi/2 - local map_id = item:get_meta():get_string("mcl_maps:id") - if map_id == "" then - local e = minetest.add_entity(pos, "mcl_itemframes:item") - local lua = e:get_luaentity() - lua._nodename = node.name - local itemname = item:get_name() - if itemname == "" or itemname == nil then - lua._texture = "blank.png" - lua._scale = 1 - else - lua._texture = itemname - local def = minetest.registered_items[itemname] - lua._scale = def and def.wield_scale and def.wield_scale.x or 1 - end - lua:_update_texture() - if node.name == "mcl_itemframes:item_frame" then - e:set_yaw(yaw) - end - else - local e = minetest.add_entity(pos, "mcl_itemframes:map", map_id) - e:set_yaw(yaw) - end - end -end - -local drop_item = function(pos, node, meta, clicker) - local cname = "" - if clicker and clicker:is_player() then - cname = clicker:get_player_name() - end - if node.name == "mcl_itemframes:item_frame" and not minetest.is_creative_enabled(cname) then - local inv = meta:get_inventory() - local item = inv:get_stack("main", 1) - if not item:is_empty() then - minetest.add_item(pos, item) - end - end - meta:set_string("infotext", "") - remove_item_entity(pos, node) -end - -minetest.register_node("mcl_itemframes:item_frame",{ - description = S("Item Frame"), - _tt_help = S("Can hold an item"), - _doc_items_longdesc = S("Item frames are decorative blocks in which items can be placed."), - _doc_items_usagehelp = S("Just place any item on the item frame. Use the item frame again to retrieve the item."), - drawtype = "mesh", - is_ground_content = false, - mesh = "mcl_itemframes_itemframe1facedir.obj", - selection_box = { type = "fixed", fixed = {-6/16, -6/16, 7/16, 6/16, 6/16, 0.5} }, - collision_box = { type = "fixed", fixed = {-6/16, -6/16, 7/16, 6/16, 6/16, 0.5} }, - tiles = {"mcl_itemframes_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "default_wood.png", "mcl_itemframes_itemframe_background.png"}, - inventory_image = "mcl_itemframes_item_frame.png", - wield_image = "mcl_itemframes_item_frame.png", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - groups = { dig_immediate=3,deco_block=1,dig_by_piston=1,container=7,attached_node_facedir=1 }, - sounds = mcl_sounds.node_sound_defaults(), - node_placement_prediction = "", - on_timer = function(pos) - local inv = minetest.get_meta(pos):get_inventory() - local stack = inv:get_stack("main", 1) - local itemname = stack:get_name() - if minetest.get_item_group(itemname, "clock") > 0 then - local new_name = "mcl_clock:clock_" .. (mcl_worlds.clock_works(pos) and mcl_clock.old_time or mcl_clock.random_frame) - if itemname ~= new_name then - stack:set_name(new_name) - inv:set_stack("main", 1, stack) - local node = minetest.get_node(pos) - update_item_entity(pos, node, node.param2) - end - minetest.get_node_timer(pos):start(1.0) - end - end, - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - return itemstack - end - - -- Use pointed node's on_rightclick function first, if present - local node = minetest.get_node(pointed_thing.under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack - end - end - - return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under))) - end, - on_construct = function(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - inv:set_size("main", 1) - end, - on_rightclick = function(pos, node, clicker, itemstack) - if not itemstack then - return - end - local pname = clicker:get_player_name() - if minetest.is_protected(pos, pname) then - minetest.record_protection_violation(pos, pname) - return - end - local meta = minetest.get_meta(pos) - drop_item(pos, node, meta, clicker) - local inv = meta:get_inventory() - if itemstack:is_empty() then - remove_item_entity(pos, node) - meta:set_string("infotext", "") - inv:set_stack("main", 1, "") - return itemstack - end - local put_itemstack = ItemStack(itemstack) - put_itemstack:set_count(1) - local itemname = put_itemstack:get_name() - if minetest.get_item_group(itemname, "compass") > 0 then - put_itemstack:set_name(mcl_compass.get_compass_itemname(pos, minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2)), put_itemstack)) - end - if minetest.get_item_group(itemname, "clock") > 0 then - minetest.get_node_timer(pos):start(1.0) - end - inv:set_stack("main", 1, put_itemstack) - update_item_entity(pos, node) - -- Add node infotext when item has been named - local imeta = itemstack:get_meta() - local iname = imeta:get_string("name") - if iname then - meta:set_string("infotext", iname) - end - - if not minetest.is_creative_enabled(clicker:get_player_name()) then - itemstack:take_item() - end - return itemstack - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return count - end - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - on_destruct = function(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - drop_item(pos, node, meta) - end, - on_rotate = function(pos, node, user, mode, param2) - if mode == screwdriver.ROTATE_FACE then - -- Rotate face - --local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - - local objs = nil - if node.name == "mcl_itemframes:item_frame" then - objs = minetest.get_objects_inside_radius(pos, 0.5) - end - if objs then - for _, obj in ipairs(objs) do - if obj and obj:get_luaentity() and obj:get_luaentity().name == "mcl_itemframes:item" then - update_item_entity(pos, node, (node.param2+1) % 4) - break - end - end - end - return - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - end, -}) +-- Define the standard frames. +mcl_itemframes.create_custom_frame("false", "item_frame", false, + "mcl_itemframes_item_frame.png", mcl_colors.WHITE, "Can hold an item.", + "Item Frame", "") +mcl_itemframes.create_custom_frame("false", "glow_item_frame", true, + "mcl_itemframes_glow_item_frame.png", mcl_colors.WHITE, "Can hold an item and glows.", + "Glowing Item Frame", "") +-- Register the base frame's recipes. +-- was going to make it a specialized function, but minetest refuses to play nice. minetest.register_craft({ output = "mcl_itemframes:item_frame", recipe = { - {"mcl_core:stick", "mcl_core:stick", "mcl_core:stick"}, - {"mcl_core:stick", "mcl_mobitems:leather", "mcl_core:stick"}, - {"mcl_core:stick", "mcl_core:stick", "mcl_core:stick"}, + { "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" }, + { "mcl_core:stick", "mcl_mobitems:leather", "mcl_core:stick" }, + { "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" }, } }) -minetest.register_lbm({ - label = "Update legacy item frames", - name = "mcl_itemframes:update_legacy_item_frames", - nodenames = {"itemframes:frame"}, - action = function(pos, node) - -- Swap legacy node, then respawn entity - node.name = "mcl_itemframes:item_frame" - local meta = minetest.get_meta(pos) - local item = meta:get_string("item") - minetest.swap_node(pos, node) - if item ~= "" then - local itemstack = ItemStack(minetest.deserialize(meta:get_string("itemdata"))) - local inv = meta:get_inventory() - inv:set_size("main", 1) - if not itemstack:is_empty() then - inv:set_stack("main", 1, itemstack) - end - end - update_item_entity(pos, node) - end, +minetest.register_craft({ + type = "shapeless", + output = 'mcl_itemframes:glow_item_frame', + recipe = { 'mcl_mobitems:glow_ink_sac', 'mcl_itemframes:item_frame' }, }) --- FIXME: Item entities can get destroyed by /clearobjects -minetest.register_lbm({ - label = "Respawn item frame item entities", - name = "mcl_itemframes:respawn_entities", - nodenames = {"mcl_itemframes:item_frame"}, - run_at_every_load = true, - action = function(pos, node) - update_item_entity(pos, node) - end, -}) - -minetest.register_alias("itemframes:frame", "mcl_itemframes:item_frame") +mcl_itemframes.custom_register_lbm() diff --git a/mods/ITEMS/mcl_itemframes/item_frames_API.lua b/mods/ITEMS/mcl_itemframes/item_frames_API.lua new file mode 100644 index 000000000..231482800 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/item_frames_API.lua @@ -0,0 +1,889 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 10/26/22 1:16 AM +--- + +mcl_itemframes = {} +mcl_itemframes.item_frame_base = {} +mcl_itemframes.glow_frame_base = {} +mcl_itemframes.frames_registered = {} +mcl_itemframes.frames_registered.glowing = {} +mcl_itemframes.frames_registered.standard = {} + +-- Set to true to get all of the DEBUG messages. +mcl_itemframes.DEBUG = false + +if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] initialized.") +end + +local S = minetest.get_translator(minetest.get_current_modname()) +local table = table +local pairs = pairs + +if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] API initialized.") +end + +local VISUAL_SIZE = 0.3 +local facedir = {} +local pi = math.pi + +local glow_amount = 6 -- LIGHT_MAX is 15, but the items aren't supposed to be a light source. +local frame_item_base = {} +local map_item_base = {} + +local TIMER_INTERVAL = 40.0 + +-- Time to Fleckenstein! (it just sounds cool lol) + +--- self: the object to roll. +local function update_roll(self, pos) + + -- get the entity's metadata. + local meta = minetest.get_meta(pos) + + -- using an integer, as it's the number of 45 degree turns. ie, 0 to 7 + local current_roll = meta:get_int("roll", 0) + local new_roll = current_roll + 1 + + if new_roll == 8 then + new_roll = 0 + end + meta:set_int("roll", new_roll) + + local new_roll_deg = new_roll * 45 + + -- * `get_rotation()`: returns the rotation, a vector (radians) + local rot = self:get_rotation() + local Radians = 0 + + -- Radians = Degrees * (pi / 180) degrees to radian formula + -- Radian quick chart + -- One full revolution is equal to 2π rad (or) 360°. + -- 1° = 0.017453 radians and 1 rad = 57.2958°. + -- To convert an angle from degrees to radians, we multiply it by π/180°. + -- To convert an angle from radians to degrees, we multiply it by 180°/π. + + Radians = new_roll_deg * (pi / 180) + rot.z = Radians + + self:set_rotation(rot) + +end + +--- self: the object to roll. +--- faceDeg: 0-7, inclusive. +local function set_roll(self, faceDeg) + -- get the entity's metadata. + local meta = minetest.get_meta(self:get_pos()) + + -- using an integer, as it's the number of 45 degree turns. ie, 0 to 7 + local new_roll = faceDeg + + if new_roll >= 8 then + new_roll = 7 + end + if new_roll <= 0 then + new_roll = 0 + end + + meta:set_int("roll", new_roll) + + local new_roll_deg = new_roll * 45 + + -- * `get_rotation()`: returns the rotation, a vector (radians) + local rot = self:get_rotation() + local Radians = 0 + + -- Radians = Degrees * (pi / 180) degrees to radian formula + -- Radian quick chart + -- One full revolution is equal to 2π rad (or) 360°. + -- 1° = 0.017453 radians and 1 rad = 57.2958°. + -- To convert an angle from degrees to radians, we multiply it by π/180°. + -- To convert an angle from radians to degrees, we multiply it by 180°/π. + + Radians = new_roll_deg * (pi / 180) + + rot.z = Radians + + self:set_rotation(rot) +end + +local function update_map_texture (self, staticdata) + self.id = staticdata + local result = true + result = mcl_maps.load_map(self.id, function(texture) + -- will not crash even if self.object is invalid by now + -- update... quite possibly will screw up with each version of Minetest. >.< + if not texture then + minetest.log("error", "Failed to load the map texture using mcl_maps.") + end + + self.object:set_properties({ textures = { texture } }) + end) + if result ~= nil and result == false then + mintest.log("error", "[mcl_itemframes] Error setting up Map Item.") + end + +end + +local remove_item_entity = function(pos, node) + + local name_found = false + local found_name_to_use = "" + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + end + + if mcl_itemframes.DEBUG then + minetest.log("action", "mcl_itemframes] remove_item_entity: " .. found_name_to_use .. "'s displayed item.") + end + + -- node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" or + if node.name == found_name_to_use then + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do + local entity = obj:get_luaentity() + if entity then + -- remove old entities + if entity.name == "mcl_itemframes:item" or entity.name == "mcl_itemframes:glow_item" or entity.name == "mcl_itemframes:map" or entity.name == "mcl_itemframes:glow_map" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local item = inv:get_stack("main", 1) + if not item:is_empty() then + if (node.name == found_name_to_use) then + minetest.add_item(pos, item) + end + meta:set_string("infotext", "") + end + obj:remove() + end + if entity.name == found_name_to_use .. "_item" or entity.name == found_name_to_use .. "_map" then + if mcl_itemframes.DEBUG then + minetest.log("action", "mcl_itemframes] remove_item_entity: " .. entity.name .. "-- the item.") + end + obj:remove() + end + end + end + end +end + +mcl_itemframes.update_item_entity = function(pos, node, param2) + + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item:\nPosition: " .. dump(pos) .. "\nNode: " .. dump(node)) + end + + remove_item_entity(pos, node) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local item = inv:get_stack("main", 1) + + local name_found = false + local found_name_to_use = "" + local has_glow = false + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + has_glow = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + has_glow = false + found_name_to_use = v + break + end + end + end + + if name_found == false then + minetest.log("error", "[mcl_itemframes] Update_Generic_Item:\nFailed to find registered node:\nNode name - " .. node.name) + minetest.log("error", "[mcl_itemframes] Update_Generic_Item:\nRegistry definition:" .. dump(mcl_itemframes.frames_registered)) + return + end + + if not item:is_empty() then + -- update existing items placed. + if not param2 then + param2 = node.param2 + end + local pos_adj = facedir[param2] + + if node.name == found_name_to_use then + pos.x = pos.x + pos_adj.x * 6.5 / 16 + pos.y = pos.y + pos_adj.y * 6.5 / 16 + pos.z = pos.z + pos_adj.z * 6.5 / 16 + + if mcl_itemframes.DEBUG then + minetest.log("[mcl_itemframes] Update_Generic_Item:\nFound Name in Registry: " .. found_name_to_use) + end + end + local yaw = pi * 2 - param2 * pi / 2 + local map_id = item:get_meta():get_string("mcl_maps:id") + local map_id_entity = {} + local map_id_lua = {} + + local timer = minetest.get_node_timer(pos) + if map_id == "" then + -- handle regular items placed into custom frame. + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item:\nAdding entity: " .. node.name .. "_item") + end + + if node.name == found_name_to_use then + map_id_entity = minetest.add_entity(pos, node.name .. "_item") + else + local debug_string = "[mcl_itemframes] Update_Generic_Item:\nCouldn't find node name in registry: " + minetest.log("error", debug_string .. found_name_to_use "\nregistry: " .. dump(mcl_itemframes.frames_registered)) + return + end + + map_id_lua = map_id_entity:get_luaentity() + map_id_lua._nodename = node.name + + local itemname = item:get_name() + if itemname == "" or itemname == nil then + map_id_lua._texture = "blank.png" + map_id_lua._scale = 1 + + -- set up glow, as this is the default/initial clause on placement. + if has_glow then + map_id_lua.glow = glow_amount + end + + -- if there's nothing to display, then kill the timer. + if timer:is_started() == true then + timer:stop() + end + else + map_id_lua._texture = itemname + local def = minetest.registered_items[itemname] + map_id_lua._scale = def and def.wield_scale and def.wield_scale.x or 1 + + -- fix for /ClearObjects + if minetest.get_item_group(itemname, "clock") == 0 then + -- Do timer related stuff - but only if there is something to display... and it's not a clock. + if timer:is_started() == false then + timer:start(TIMER_INTERVAL) + else + timer:stop() + timer:start(TIMER_INTERVAL) + end + end + + end + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item: item's name: " .. itemname) + end + map_id_lua:_update_texture() + if node.name == found_name_to_use then + map_id_entity:set_yaw(yaw) + else + minetest.log("error", "[mcl_itemframes] Update_Generic_Item: Failed to set Display Item's yaw. " .. node.name) + end + else + -- handle map items placed into custom frame. + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item: Placing map in a " .. found_name_to_use .. " frame.") + end + + if node.name == found_name_to_use then + map_id_entity = minetest.add_entity(pos, found_name_to_use .. "_map", map_id) + map_id_entity:set_yaw(yaw) + else + minetest.log("error", "[mcl_itemframes] Update_Generic_Item: Failed to set Map Item in " .. found_name_to_use .. "'s frame.") + end + + -- give maps a refresh timer. + if timer:is_started() == false then + timer:start(TIMER_INTERVAL) + else + timer:stop() + timer:start(TIMER_INTERVAL) + end + + end + + -- finally, set the rotation (roll) of the displayed object. + local roll = meta:get_int("roll", 0) + set_roll(map_id_entity, roll) + end + +end + +function mcl_itemframes.drop_generic_item(pos, node, meta, clicker) + local name_found = false + local found_name_to_use = "" + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + end + + local cname = "" + if clicker and clicker:is_player() then + cname = clicker:get_player_name() + end + if not minetest.is_creative_enabled(cname) then + if (node.name == found_name_to_use) then + local inv = meta:get_inventory() + local item = inv:get_stack("main", 1) + if not item:is_empty() then + minetest.add_item(pos, item) + end + end + end + + meta:set_string("infotext", "") + remove_item_entity(pos, node) + +end + +--- reworked to set up the base item definitions. +function mcl_itemframes.create_base_item_entity() + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] create_item_entity.") + end + + --"mcl_itemframes:item", + frame_item_base = { + hp_max = 1, + visual = "wielditem", + visual_size = { x = VISUAL_SIZE, y = VISUAL_SIZE }, + physical = false, + pointable = false, + textures = { "blank.png" }, + _texture = "blank.png", + _scale = 1, + groups = { immortal = 1, }, + on_activate = function(self, staticdata) + if staticdata and staticdata ~= "" then + local data = staticdata:split(";") + if data and data[1] and data[2] then + self._nodename = data[1] + self._texture = data[2] + if data[3] then + self._scale = data[3] + else + self._scale = 1 + end + end + end + if self._texture then + self.object:set_properties({ + textures = { self._texture }, + visual_size = { x = VISUAL_SIZE / self._scale, y = VISUAL_SIZE / self._scale }, + }) + end + end, + get_staticdata = function(self) + if self._nodename and self._texture then + local ret = self._nodename .. ";" .. self._texture + if self._scale then + ret = ret .. ";" .. self._scale + end + return ret + end + return "" + end, + on_punch = function() return true end, + _update_texture = function(self) + if self._texture then + self.object:set_properties({ + textures = { self._texture }, + visual_size = { x = VISUAL_SIZE / self._scale, y = VISUAL_SIZE / self._scale }, + }) + end + end, + } + -- "mcl_itemframes:map", + map_item_base = { + initial_properties = { + visual = "upright_sprite", + visual_size = { x = 1, y = 1 }, + pointable = false, + physical = false, + collide_with_objects = false, + textures = { "blank.png" }, + }, + on_activate = function(self, staticdata) + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] map_item:on_activate.") + end + update_map_texture(self, staticdata) + end, + + get_staticdata = function(self) + return self.id + end, + } + +end + +function mcl_itemframes.create_custom_items(name, has_glow) + local custom_frame_item = table.copy(frame_item_base) + local custom_frame_map_item = table.copy(map_item_base) + if has_glow then + custom_frame_map_item.glow = glow_amount + custom_frame_item.glow = glow_amount + if mcl_itemframes.DEBUG then + minetest.log("action", "\n[mcl_itemframes] create_custom_item_entity: glow name: " .. name .. "_item") + minetest.log("action", "[mcl_itemframes] create_custom_item_entity: glow name: " .. name .. "_map\n") + end + else + if mcl_itemframes.DEBUG then + minetest.log("action", "\n[mcl_itemframes] create_custom_item_entity: name: " .. name .. "_item") + minetest.log("action", "[mcl_itemframes] create_custom_item_entity: name: " .. name .. "_map\n") + end + end + minetest.register_entity(":" .. name .. "_item", custom_frame_item) + minetest.register_entity(":" .. name .. "_map", custom_frame_map_item) +end + +function mcl_itemframes.update_frame_registry(modname, name, has_glow) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + local frame = name -- should only be called within the create_frames functions. + if has_glow == true then + table.insert(mcl_itemframes.frames_registered.glowing, frame) + else + table.insert(mcl_itemframes.frames_registered.standard, frame) + end + +end + +--- name: The name used to distinguish the item frame. Prepends "mcl_itemframes:" to the name. Example usage: +--- "glow_item_frame" creates a node named ":mcl_itemframes:glow_item_frame". +function mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, color, ttframe, description, inv_wield_image) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + if name == nil then + name = "" + end + + if name == "" then + minetest.log("error", "attempted to create an item frame WITHOUT a name!") + return + end + + if has_glow == nil or has_glow == "" then + has_glow = false + end + + if tiles == nil or tiles == "" then + minetest.log("error", "No textures passed to Create_Custom_Frame!! Exiting frame creation.") + return + end + + local working_name = "mcl_itemframes:" .. name + + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] create_custom_frame: " .. working_name) + minetest.log("action", "[mcl_itemframes] create_custom_frame - calling create_custom_items " .. working_name) + end + + -- make any special frame items. + mcl_itemframes.create_custom_items(working_name, has_glow) + + local custom_itemframe_definition = {} + + if has_glow == false then + custom_itemframe_definition = table.copy(mcl_itemframes.item_frame_base) + else + custom_itemframe_definition = table.copy(mcl_itemframes.glow_frame_base) + end + + if inv_wield_image ~= nil and inv_wield_image ~= "" then + custom_itemframe_definition.glow_frame_base.inventory_image = { "(" .. inv_wield_image .. "^[multiply:" .. color .. ")" } + custom_itemframe_definition.glow_frame_base.wield_image = { "(" .. inv_wield_image .. "^[multiply:" .. color .. ")" } + end + + custom_itemframe_definition.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + custom_itemframe_definition._tt_help = ttframe + custom_itemframe_definition.description = description + + minetest.register_node(":" .. working_name, custom_itemframe_definition) + + mcl_itemframes.update_frame_registry(modname, working_name, has_glow) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_itemframes:item_frame", "nodes", working_name) + end + +end + +function mcl_itemframes.custom_register_lbm() + + local registered_frame_nodenames = {} + + for i = 0, #mcl_itemframes.frames_registered.glowing do + table.insert(registered_frame_nodenames, mcl_itemframes.frames_registered.glowing[i]) + end + + for i = 0, #mcl_itemframes.frames_registered.standard do + table.insert(registered_frame_nodenames, mcl_itemframes.frames_registered.standard[i]) + end + + minetest.register_lbm({ + label = "Respawn item frame item entities", + name = "mcl_itemframes:respawn_entities", + nodenames = registered_frame_nodenames, + run_at_every_load = true, + action = function(pos, node) + mcl_itemframes.update_item_entity(pos, node) + end, + }) + +end + +local function register_frame_achievements() + + awards.register_achievement("mcl_itemframes:glowframe", { + title = S("Glow and Behold!"), + description = S("Craft a glow item frame."), + icon = "mcl_itemframes_glow_item_frame.png", + trigger = { + type = "craft", + item = "mcl_itemframes:glow_item_frame", + target = 1 + }, + type = "Advancement", + group = "Overworld", + }) + +end + +function mcl_itemframes.create_base_definitions() + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] create_base_definitions.") + end + + -- set up the facedir information. + facedir[0] = { x = 0, y = 0, z = 1 } + facedir[1] = { x = 1, y = 0, z = 0 } + facedir[2] = { x = 0, y = 0, z = -1 } + facedir[3] = { x = -1, y = 0, z = 0 } + + mcl_itemframes.item_frame_base = { + description = S("Item Frame"), + name = "mcl_itemframes:item_frame", + _tt_help = S("Can hold an item"), + _doc_items_longdesc = S("Item frames are decorative blocks in which items can be placed."), + _doc_items_usagehelp = S("Just place any item on the item frame. Use the item frame again to retrieve the item."), + drawtype = "mesh", + is_ground_content = false, + mesh = "mcl_itemframes_itemframe1facedir.obj", + selection_box = { type = "fixed", fixed = { -6 / 16, -6 / 16, 7 / 16, 6 / 16, 6 / 16, 0.5 } }, + collision_box = { type = "fixed", fixed = { -6 / 16, -6 / 16, 7 / 16, 6 / 16, 6 / 16, 0.5 } }, + tiles = { "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "default_wood.png", "mcl_itemframes_item_frame_back.png" }, + inventory_image = "mcl_itemframes_item_frame.png", + wield_image = "mcl_itemframes_item_frame.png", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + groups = { dig_immediate = 3, deco_block = 1, dig_by_piston = 1, container = 7, }, -- attached_node_facedir = 1 }, -- allows for more placement options. + sounds = mcl_sounds.node_sound_defaults(), + node_placement_prediction = "", + + on_timer = function(pos) + local inv = minetest.get_meta(pos):get_inventory() + local stack = inv:get_stack("main", 1) + local itemname = stack:get_name() + local node = {} + if minetest.get_item_group(itemname, "clock") > 0 then + local new_name = "mcl_clock:clock_" .. (mcl_worlds.clock_works(pos) and mcl_clock.old_time or mcl_clock.random_frame) + if itemname ~= new_name then + stack:set_name(new_name) + inv:set_stack("main", 1, stack) + node = minetest.get_node(pos) + mcl_itemframes.update_item_entity(pos, node, node.param2) + end + minetest.get_node_timer(pos):start(1.0) + else + node = minetest.get_node(pos) + mcl_itemframes.update_item_entity(pos, node, node.param2) + end + end, + + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local dir = vector.subtract(pointed_thing.under, pointed_thing.above) + local wdir = minetest.dir_to_wallmounted(dir) + + -- remove bottom and top of objects. + if wdir == 0 or wdir == 1 then + return itemstack + end + + -- Use pointed node's on_rightclick function first, if present + local node = minetest.get_node(pointed_thing.under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + + return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under))) + end, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 1) + end, + + on_rightclick = function(pos, node, clicker, itemstack) + if not itemstack then + return + end + local pname = clicker:get_player_name() + if minetest.is_protected(pos, pname) then + minetest.record_protection_violation(pos, pname) + return + end + local meta = minetest.get_meta(pos) + mcl_itemframes.drop_generic_item(pos, node, meta, clicker) + + local inv = meta:get_inventory() + if itemstack:is_empty() then + remove_item_entity(pos, node) + meta:set_string("infotext", "") + inv:set_stack("main", 1, "") + return itemstack + end + local put_itemstack = ItemStack(itemstack) + put_itemstack:set_count(1) + local itemname = put_itemstack:get_name() + if minetest.get_item_group(itemname, "compass") > 0 then + put_itemstack:set_name(mcl_compass.get_compass_itemname(pos, minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2)), put_itemstack)) + end + if minetest.get_item_group(itemname, "clock") > 0 then + minetest.get_node_timer(pos):start(1.0) + end + + inv:set_stack("main", 1, put_itemstack) + mcl_itemframes.update_item_entity(pos, node) + + -- Add node infotext when item has been named + local imeta = itemstack:get_meta() + local iname = imeta:get_string("name") + if iname then + meta:set_string("infotext", iname) + end + + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + return itemstack + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return count + end + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end + end, + + on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local node = minetest.get_node(pos) + + mcl_itemframes.drop_generic_item(pos, node, meta) + + end, + + on_rotate = function(pos, node, user, mode, param2) + --local meta = minetest.get_meta(pos) + local node = minetest.get_node(pos) + + local objs = nil + local name_found = false + local found_name_to_use = "" + name_found = false + found_name_to_use = "" + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + end + + if node.name == found_name_to_use then + objs = minetest.get_objects_inside_radius(pos, 0.5) + else + return -- short circuit if it's somehow not the right thing. + end + + if objs then + if mode == screwdriver.ROTATE_FACE or mode == screwdriver.ROTATE_AXIS then + for _, obj in ipairs(objs) do + if obj and obj:get_luaentity() then + local obj_name = obj:get_luaentity().name + if obj_name == found_name_to_use .. "_item" then + if mode == screwdriver.ROTATE_AXIS then + update_roll(obj, pos) + end + break + end + end + end + return false + end + end + end, + } + + -- make the base items for the base frames. + mcl_itemframes.create_base_item_entity() + + -- minetest.register_node("mcl_itemframes:item_frame", mcl_itemframes.item_frame_base) + + -- make glow frame from the base item_frame. + mcl_itemframes.glow_frame_base = table.copy(mcl_itemframes.item_frame_base) + mcl_itemframes.glow_frame_base.description = S("Glowing Item Frame") + mcl_itemframes.glow_frame_base._tt_help = S("Can hold an item and glows.") + mcl_itemframes.glow_frame_base.longdesc = S("Glowing item frames are decorative blocks in which items can be placed and made to glow.") + mcl_itemframes.glow_frame_base.tiles = { "mcl_itemframes_glow_item_frame.png" } + mcl_itemframes.glow_frame_base.inventory_image = "mcl_itemframes_glow_item_frame_item.png" + mcl_itemframes.glow_frame_base.wield_image = "mcl_itemframes_glow_item_frame.png" + mcl_itemframes.glow_frame_base.mesh = "mcl_itemframes_glow_item_frame.obj" + mcl_itemframes.glow_frame_base.glow = 1 --make the glow frames have some glow at night, but not enough to be a light source. + + -- set up the achievement for glow frames. + register_frame_achievements() + +end + +-- for compatibility: +function mcl_itemframes.backwards_compatibility () + minetest.register_lbm({ + label = "Update legacy item frames", + name = "mcl_itemframes:update_legacy_item_frames", + nodenames = { "itemframes:frame" }, + action = function(pos, node) + -- Swap legacy node, then respawn entity + node.name = "mcl_itemframes:item_frame" + local meta = minetest.get_meta(pos) + local item = meta:get_string("item") + minetest.swap_node(pos, node) + if item ~= "" then + local itemstack = ItemStack(minetest.deserialize(meta:get_string("itemdata"))) + local inv = meta:get_inventory() + inv:set_size("main", 1) + if not itemstack:is_empty() then + inv:set_stack("main", 1, itemstack) + end + end + mcl_itemframes.update_item_entity(pos, node) + end, + }) + minetest.register_alias("itemframes:frame", "mcl_itemframes:item_frame") + + -- adds backwards compatibility + minetest.register_alias("mcl_itemframes:item", "mcl_itemframes:item_frame_item") + minetest.register_alias("mcl_itemframes:map", "mcl_itemframes:item_frame_map") + minetest.register_alias("mcl_itemframes:glow_item", "mcl_itemframes:glow_item_frame_item") + minetest.register_alias("mcl_itemframes:glow_map", "mcl_itemframes:glow_item_frame_map") + + minetest.register_entity("mcl_itemframes:item", frame_item_base) + minetest.register_entity("mcl_itemframes:map", map_item_base) + minetest.register_entity("mcl_itemframes:glow_item", frame_item_base) + minetest.register_entity("mcl_itemframes:glow_map", map_item_base) + +end diff --git a/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt b/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt new file mode 100644 index 000000000..7510b15b5 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt @@ -0,0 +1,36 @@ +The item frames use case is a very specific one, but... in the event that there is need for a new item frame then that +is where this api will shine. + +As long as the api has been initialized (which it does in its own init.lua) then you really only need to call one +function. That function being mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, color, ttframe, +description, inv_wield_image). Note: unlike the Signs API, this API does not automatically create the recipe for you. + +Here's an explanation of create_custom_frame and an example of using it. + +This function is responsible for creating each frame, and handling the creation of its underlying entities. + +Parameters: +* modname: Used to make sure that a specific module is installed before running the code contained within. Set to "" or + false, if there's not a mod to check for. +* name: The name used to distinguish the item frame. Prepends "mcl_itemframes:" to the name. Example usage: + "glow_item_frame" creates a node named "mcl_itemframes:glow_item_frame". +* has_glow: Does the frame cause the item within to glow? true / false. +* tiles: The image files used for the item frame's object texturing. +* color: Colorizes the frame / wield / inventory image to a specific color. Use White (#FFFFFF) to ignore. +* ttframe: The tooltip to show for the frame. +* description: The frame's description. +* inv_wield_image: Optionally the image to use as the inventory and the wield image. Colorized. set to "" or nil to use + the default frame / glow frame images. Note: must be set if you want the inventory / wield image to be colored. + +example: +-- Register the Glow Frame +mcl_itemframes.create_custom_frame("false", "glow_item_frame", true, + "mcl_itemframes_glow_item_frame.png", mcl_colors.WHITE, "Glowing Item Frame", + "Can hold an item and glows.","") + +-- Register the Glow Frame's recipe +minetest.register_craft({ + type = "shapeless", + output = 'mcl_itemframes:glow_item_frame', + recipe = { 'mcl_mobitems:glow_ink_sac', 'mcl_itemframes:item_frame' }, +}) diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr index 07d7812f6..b9bf40e1a 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr @@ -1,5 +1,8 @@ # textdomain: mcl_itemframes -Item Frame=Rahmen -Item frames are decorative blocks in which items can be placed.=Rahmen sind dekorative Blöcke, in denen man Gegenstände platzieren kann. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Platzieren Sie einfach einen beliebigen Gegenstand in den Rahmen. Benutzen Sie den Rahmen erneut, um den Gegenstand zurück zu erhalten. -Can hold an item=Kann einen Gegenstand halten +Item Frame=Artikel Rahmen +Item frames are decorative blocks in which items can be placed.=Artikelrahmen sind dekorative Blöcke, in denen Artikel platziert werden können. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Platzieren Sie einfach einen beliebigen Gegenstand auf dem Gegenstandsrahmen. Verwenden Sie den Artikelrahmen erneut, um den Artikel abzurufen. +Can hold an item.=Kann einen Gegenstand halten. +Glowing Item Frame=Leuchtender Gegenstandsrahmen +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Leuchtende Gegenstandsrahmen sind dekorative Blöcke, in denen Gegenstände platziert und zum Leuchten gebracht werden können. +Can hold an item and glows.=Kann einen Gegenstand halten und leuchtet. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr index 0803234b0..d5c3aed71 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr @@ -1,5 +1,8 @@ # textdomain: mcl_itemframes -Item Frame=Marco +Item Frame=Cuadro de artículo Item frames are decorative blocks in which items can be placed.=Los marcos de elementos son bloques decorativos en los que se pueden colocar elementos. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Simplemente coloque cualquier artículo en el marco del artículo. Use el marco del artículo nuevamente para recuperar el artículo. - +Just place any item on the item frame. Use the item frame again to retrieve the item.=Simplemente coloque cualquier elemento en el marco del elemento. Use el marco del elemento nuevamente para recuperar el elemento. +Can hold an item.=Puede contener un artículo. +Glowing Item Frame=Marco de artículo brillante +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Los marcos de elementos brillantes son bloques decorativos en los que se pueden colocar elementos y hacer que brillen. +Can hold an item and glows.=Puede sostener un artículo y brilla. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr index 180c5555f..e847779f2 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr @@ -1,5 +1,8 @@ # textdomain: mcl_itemframes -Item Frame=Cadre -Item frames are decorative blocks in which items can be placed.=Les cadres sont des blocs décoratifs dans lesquels les objets peuvent être placés. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Placez simplement n'importe quel objet sur le cadre. Utilisez à nouveau le cadre décoré pour récupérer l'élément. -Can hold an item=Peut contenir un objet +Item Frame=Cadre de l'article +Item frames are decorative blocks in which items can be placed.=Les cadres d'objets sont des blocs décoratifs dans lesquels des objets peuvent être placés. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Placez simplement n'importe quel élément sur le cadre de l'élément. Utilisez à nouveau le cadre de l'objet pour récupérer l'objet. +Can hold an item.=Peut contenir un objet. +Glowing Item Frame=Cadre d'objet lumineux +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Les cadres d'objets lumineux sont des blocs décoratifs dans lesquels des objets peuvent être placés et rendus brillants. +Can hold an item and glows.=Peut contenir un objet et brille. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ja.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ja.tr new file mode 100644 index 000000000..daf21337f --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_itemframes +Item Frame=アイテムフレーム +Item frames are decorative blocks in which items can be placed.=アイテムフレームは、アイテムを配置することができる装飾ブロックです。 +Just place any item on the item frame. Use the item frame again to retrieve the item.=アイテムフレームに任意のアイテムを置くだけです。アイテムを取り出すには、再度アイテムフレームに触ります。 +Can hold an item=アイテムを保持可能 +Glow Item Frame=発光するアイテムフレーム +Glow item frames are decorative blocks in which items can be placed.=発光するアイテムフレームは、アイテムを配置することができる装飾ブロックです。 +Can hold an item and glows=アイテムを保持でき、発光する \ No newline at end of file diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr index 8de889471..87b83c27d 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr @@ -3,3 +3,10 @@ Item Frame=Ramka na przedmiot Item frames are decorative blocks in which items can be placed.=Ramki na przedmiot to dekoracyjne bloki w których można umieszczać przedmioty. Just place any item on the item frame. Use the item frame again to retrieve the item.=Umieść dowolny przedmiot w ramce. Użyj ramki ponownie aby odzyskać przedmiot. Can hold an item=Może przetrzymywać przedmiot +Item Frame=Rama przedmiotu +Item frames are decorative blocks in which items can be placed.=Ramki na przedmioty to klocki ozdobne, w których można umieszczać przedmioty. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Wystarczy umieścić dowolny przedmiot na ramie przedmiotu. Użyj ponownie ramki elementu, aby pobrać element. +Can hold an item.=Może pomieścić przedmiot. +Glowing Item Frame=Świecąca ramka na przedmiot +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Świecące ramki na przedmioty to ozdobne bloki, w których można umieścić przedmioty i sprawić, by świeciły. +Can hold an item and glows.=Może trzymać przedmiot i świeci. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr index 7d3d90cc4..bf9076815 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr @@ -3,3 +3,10 @@ Item Frame=Рамка Item frames are decorative blocks in which items can be placed.=Рамки это декоративные блоки, в которые можно помещать предметы. Just place any item on the item frame. Use the item frame again to retrieve the item.=Просто поместите в рамку любой предмет. Используйте рамку вновь, чтобы заполучить из неё предмет обратно. Can hold an item=Может хранить предмет +Item Frame=Рамка предмета +Item frames are decorative blocks in which items can be placed.=Рамки предметов — это декоративные блоки, в которые можно помещать предметы. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Просто поместите любой предмет на рамку предмета. Используйте рамку предмета снова, чтобы получить предмет. +Can hold an item.=Может держать предмет. +Glowing Item Frame=Светящаяся рамка предмета +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Светящиеся рамки предметов — это декоративные блоки, в которые можно помещать предметы и заставлять их светиться. +Can hold an item and glows.=Может держать предмет и светится. diff --git a/mods/ITEMS/mcl_itemframes/locale/template.txt b/mods/ITEMS/mcl_itemframes/locale/template.txt index bacbfaa69..87cd55c65 100644 --- a/mods/ITEMS/mcl_itemframes/locale/template.txt +++ b/mods/ITEMS/mcl_itemframes/locale/template.txt @@ -3,3 +3,6 @@ Item Frame= Item frames are decorative blocks in which items can be placed.= Just place any item on the item frame. Use the item frame again to retrieve the item.= Can hold an item= +Glow Item Frame= +Glow item frames are decorative blocks in which items can be placed.= +Can hold an item and glows= diff --git a/mods/ITEMS/mcl_itemframes/mod.conf b/mods/ITEMS/mcl_itemframes/mod.conf index ff09c3bcc..f9421e657 100644 --- a/mods/ITEMS/mcl_itemframes/mod.conf +++ b/mods/ITEMS/mcl_itemframes/mod.conf @@ -1,3 +1,2 @@ name = mcl_itemframes -depends = mcl_core, mcl_sounds, mcl_compass, mcl_maps -optional_depends = screwdriver +depends = mcl_core, mcl_sounds, mcl_compass, mcl_maps, screwdriver diff --git a/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj b/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj new file mode 100644 index 000000000..d0a5b0c5f --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj @@ -0,0 +1,156 @@ +# Blender v2.76 (sub 0) OBJ File: 'itemframe1facedir.blend' +# www.blender.org +mtllib itemframe1facedir.mtl +o right.frame_Cube.005 +v -0.313413 -0.313413 0.435326 +v -0.313413 0.313413 0.435326 +v -0.313413 -0.313413 0.498008 +v -0.313413 0.313413 0.498008 +v -0.376095 -0.313413 0.435326 +v -0.376095 0.313413 0.435326 +v -0.376095 -0.313413 0.498008 +v -0.376095 0.313413 0.498008 +vt 0.875000 0.812500 +vt 0.812500 0.812500 +vt 0.812500 0.187500 +vt 0.875000 0.187500 +vt 1.000000 0.812500 +vt 0.937500 0.812500 +vt 0.937500 0.187500 +vt 1.000000 0.187500 +vt -0.000000 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt -0.000000 1.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/1/2 8/2/2 7/3/2 3/4/2 +f 8/5/3 6/6/3 5/7/3 7/8/3 +f 6/1/4 2/2/4 1/3/4 5/4/4 +f 1/9/5 3/10/5 7/11/5 5/12/5 +f 6/9/6 8/10/6 4/11/6 2/12/6 +o left.frame_Cube.004 +v 0.376095 -0.313413 0.435326 +v 0.376095 0.313413 0.435326 +v 0.376095 -0.313413 0.498008 +v 0.376095 0.313413 0.498008 +v 0.313413 -0.313413 0.435326 +v 0.313413 0.313413 0.435326 +v 0.313413 -0.313413 0.498008 +v 0.313413 0.313413 0.498008 +vt 0.875000 0.812500 +vt 0.812500 0.812500 +vt 0.812500 0.187500 +vt 0.875000 0.187500 +vt 1.000000 0.812500 +vt 0.937500 0.812500 +vt 0.937500 0.187500 +vt 1.000000 0.187500 +vt -0.000000 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt -0.000000 1.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 10/13/7 12/14/7 11/15/7 9/16/7 +f 12/13/8 16/14/8 15/15/8 11/16/8 +f 16/17/9 14/18/9 13/19/9 15/20/9 +f 14/13/10 10/14/10 9/15/10 13/16/10 +f 9/21/11 11/22/11 15/23/11 13/24/11 +f 14/21/12 16/22/12 12/23/12 10/24/12 +o lower.frame_Cube.003 +v 0.376095 -0.376095 0.435326 +v 0.376095 -0.313413 0.435326 +v 0.376095 -0.376095 0.498008 +v 0.376095 -0.313413 0.498008 +v -0.376095 -0.376095 0.435326 +v -0.376095 -0.313413 0.435326 +v -0.376095 -0.376095 0.498008 +v -0.376095 -0.313413 0.498008 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.125000 +vt 0.187500 0.125000 +vt 0.875000 0.187500 +vt 0.875000 0.125000 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.875000 0.937500 +vt 0.875000 1.000000 +vt 0.125000 1.000000 +vt 0.125000 0.937500 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 18/25/13 20/26/13 19/27/13 17/28/13 +f 20/29/14 24/26/14 23/27/14 19/30/14 +f 24/29/15 22/31/15 21/32/15 23/30/15 +f 22/29/16 18/26/16 17/27/16 21/30/16 +f 17/33/17 19/34/17 23/35/17 21/36/17 +f 22/30/18 24/29/18 20/26/18 18/27/18 +o upper.frame_Cube.002 +v 0.376095 0.313413 0.435326 +v 0.376095 0.376095 0.435326 +v 0.376095 0.313413 0.498008 +v 0.376095 0.376095 0.498008 +v -0.376095 0.313413 0.435326 +v -0.376095 0.376095 0.435326 +v -0.376095 0.313413 0.498008 +v -0.376095 0.376095 0.498008 +vt 0.187500 0.875000 +vt 0.125000 0.875000 +vt 0.125000 0.812500 +vt 0.187500 0.812500 +vt 0.875000 0.875000 +vt 0.875000 0.812500 +vt 0.812500 0.875000 +vt 0.812500 0.812500 +vt 0.875000 0.937500 +vt 0.875000 1.000000 +vt 0.125000 1.000000 +vt 0.125000 0.937500 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 26/37/19 28/38/19 27/39/19 25/40/19 +f 28/41/20 32/38/20 31/39/20 27/42/20 +f 32/41/21 30/43/21 29/44/21 31/42/21 +f 30/41/22 26/38/22 25/39/22 29/42/22 +f 25/45/23 27/46/23 31/47/23 29/48/23 +f 30/48/24 32/38/24 28/41/24 26/45/24 +o background_Plane +v 0.313413 -0.313413 0.466667 +v -0.313413 -0.313413 0.466667 +v 0.313413 0.313413 0.466667 +v -0.313413 0.313413 0.466667 +vt 0.187500 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.812500 +vt 0.187500 0.812500 +vn -0.000000 0.000000 -1.000000 +usemtl None +s off +f 33/49/25 34/50/25 36/51/25 35/52/25 diff --git a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame.png b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame.png new file mode 100644 index 000000000..e83b4e060 Binary files /dev/null and b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame.png differ diff --git a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_border.png b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_border.png new file mode 100644 index 000000000..9062c679f Binary files /dev/null and b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_border.png differ diff --git a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_item.png b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_item.png new file mode 100644 index 000000000..e83b4e060 Binary files /dev/null and b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_glow_item_frame_item.png differ diff --git a/mods/ITEMS/mcl_jukebox/README.md b/mods/ITEMS/mcl_jukebox/README.md index bc261270a..6376362bb 100644 --- a/mods/ITEMS/mcl_jukebox/README.md +++ b/mods/ITEMS/mcl_jukebox/README.md @@ -10,7 +10,7 @@ to play. And that's it! `mcl_jukebox_track_2.ogg`: “The Energetic Rat (Jordach's Mix)” by SoundHelix (CC0) `mcl_jukebox_track_3.ogg`: “Eastern Feeling” by Jordach (CC0) `mcl_jukebox_track_4.ogg`: “Minetest” by Jordach (CC0) -`mcl_jukebox_track_5.ogg`: “Credit Roll (Jordach's HD Mix)” by Junichi Masuda (CC0) +`mcl_jukebox_track_5.ogg`: "Soaring over the sea" by mactonite http://ccmixter.org/files/mactonite/65379 (CC-BY) `mcl_jukebox_track_6.ogg`: “Winter Feeling" by Tom Peter (CC BY-SA 3.0) `mcl_jukebox_track_7.ogg`: “Synthgroove (Jordach's Mix)” by HeroOfTheWinds (CC0) `mcl_jukebox_track_8.ogg`: “The Clueless Frog (Jordach's Mix)” by SoundHelix (CC0) diff --git a/mods/ITEMS/mcl_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index 6c51a6c94..d817bdac7 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -234,7 +234,7 @@ mcl_jukebox.register_record("The Evil Sister (Jordach's Mix)", "SoundHelix", "13 mcl_jukebox.register_record("The Energetic Rat (Jordach's Mix)", "SoundHelix", "wait", "mcl_jukebox_record_wait.png", "mcl_jukebox_track_2") mcl_jukebox.register_record("Eastern Feeling", "Jordach", "blocks", "mcl_jukebox_record_blocks.png", "mcl_jukebox_track_3") mcl_jukebox.register_record("Minetest", "Jordach", "far", "mcl_jukebox_record_far.png", "mcl_jukebox_track_4") -mcl_jukebox.register_record("Credit Roll (Jordach's HD Mix)", "Junichi Masuda", "chirp", "mcl_jukebox_record_chirp.png", "mcl_jukebox_track_5") +mcl_jukebox.register_record("Soaring over the sea", "mactonite", "chirp", "mcl_jukebox_record_chirp.png", "mcl_jukebox_track_5") mcl_jukebox.register_record("Winter Feeling", "Tom Peter", "strad", "mcl_jukebox_record_strad.png", "mcl_jukebox_track_6") mcl_jukebox.register_record("Synthgroove (Jordach's Mix)", "HeroOfTheWinds", "mellohi", "mcl_jukebox_record_mellohi.png", "mcl_jukebox_track_7") mcl_jukebox.register_record("The Clueless Frog (Jordach's Mix)", "SoundHelix", "mall", "mcl_jukebox_record_mall.png", "mcl_jukebox_track_8") diff --git a/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ja.tr b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ja.tr new file mode 100644 index 000000000..7f62b5625 --- /dev/null +++ b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ja.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_jukebox +Music Disc=音楽ディスク +A music disc holds a single music track which can be used in a jukebox to play music.=音楽ディスクには1曲の音楽が収録されており、ジュークボックスで音楽を再生するのに使用できます。 +Place a music disc into an empty jukebox to play the music. Use the jukebox again to retrieve the music disc. The music can only be heard by you, not by other players.=空のジュークボックスに音楽ディスクを入れると、音楽が再生されます。再びジュークボックスを使用すると、音楽ディスクを取り出します。音楽は自分だけが聴くことができ、他のプレーヤーは聴くことができません。 +Music Disc=音楽ディスク +@1—@2=@1—@2 +Jukebox=ジュークボックス +Jukeboxes play music when they're supplied with a music disc.=ジュークボックスは、音楽ディスクが供給されると音楽を再生します。 +Place a music disc into an empty jukebox to insert the music disc and play music. If the jukebox already has a music disc, you will retrieve this music disc first. The music can only be heard by you, not by other players.=空のジュークボックスに音楽ディスクを入れると、音楽が再生されます。すでに音楽ディスクが入っている場合は、まずその音楽ディスクを取り出します。音楽は自分だけが聴くことができ、他のプレーヤーは聴くことができません。 +Now playing: @1—@2=再生中: @1—@2 +Uses music discs to play music=音楽再生に音楽ディスクを使用 diff --git a/mods/ITEMS/mcl_jukebox/sounds/mcl_jukebox_track_5.ogg b/mods/ITEMS/mcl_jukebox/sounds/mcl_jukebox_track_5.ogg index dcad499d9..0a635207c 100644 Binary files a/mods/ITEMS/mcl_jukebox/sounds/mcl_jukebox_track_5.ogg and b/mods/ITEMS/mcl_jukebox/sounds/mcl_jukebox_track_5.ogg differ diff --git a/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ja.tr b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ja.tr new file mode 100644 index 000000000..2d403d9d9 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ja.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_lanterns +Lantern=ランタン +Soul Lantern=魂のランタン +Lanterns are light sources which can be placed on the top or the bottom of most blocks.=ランタンは、ほとんどのブロックの上部または下部に配置できる光源です。 +Chain=鎖 +Chains are metallic decoration blocks.=鎖は金属製の装飾ブロックです。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_lanterns/register.lua b/mods/ITEMS/mcl_lanterns/register.lua index efdd1ed98..86305052b 100644 --- a/mods/ITEMS/mcl_lanterns/register.lua +++ b/mods/ITEMS/mcl_lanterns/register.lua @@ -23,4 +23,13 @@ minetest.register_craft({ {"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 +}) + +minetest.register_craft({ + output = "mcl_lanterns:soul_lantern_floor", + recipe = { + {"mcl_core:iron_nugget", "mcl_core:iron_nugget" , "mcl_core:iron_nugget"}, + {"mcl_core:iron_nugget", "mcl_blackstone:soul_torch" , "mcl_core:iron_nugget"}, + {"mcl_core:iron_nugget", "mcl_core:iron_nugget" , "mcl_core:iron_nugget"}, + }, +}) diff --git a/mods/ITEMS/mcl_lightning_rods/init.lua b/mods/ITEMS/mcl_lightning_rods/init.lua new file mode 100644 index 000000000..82e04db0c --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/init.lua @@ -0,0 +1,118 @@ +local S = minetest.get_translator("mcl_lightning_rods") + +---@type nodebox +local cbox = { + type = "fixed", + fixed = { + { -0.0625, -0.5, -0.0625, 0.0625, 0.25, 0.0625 }, + { -0.125, 0.25, -0.125, 0.125, 0.5, 0.125 }, + }, +} + +---@type node_definition +local rod_def = { + description = S("Lightning Rod"), + _doc_items_longdesc = S("A block that attracts lightning"), + tiles = { "mcl_lightning_rods_rod.png" }, + drawtype = "mesh", + mesh = "mcl_lightning_rods_rod.obj", + is_ground_content = false, + paramtype = "light", + paramtype2 = "facedir", + use_texture_alpha = "opaque", + groups = { pickaxey = 2, attracts_lightning = 1 }, + sounds = mcl_sounds.node_sound_metal_defaults(), + selection_box = cbox, + collision_box = cbox, + node_placement_prediction = "", + mesecons = { + receptor = { + state = mesecon.state.off, + rules = mesecon.rules.alldirs, + }, + }, + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local p0 = pointed_thing.under + local p1 = pointed_thing.above + local param2 = 0 + + local placer_pos = placer:get_pos() + if placer_pos then + param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos)) + end + + if p0.y - 1 == p1.y then + param2 = 20 + elseif p0.x - 1 == p1.x then + param2 = 16 + elseif p0.x + 1 == p1.x then + param2 = 12 + elseif p0.z - 1 == p1.z then + param2 = 8 + elseif p0.z + 1 == p1.z then + param2 = 4 + end + + return minetest.item_place(itemstack, placer, pointed_thing, param2) + end, + + _mcl_blast_resistance = 0, +} + +minetest.register_node("mcl_lightning_rods:rod", rod_def) + +local rod_def_a = table.copy(rod_def) + +rod_def_a.tiles = { "mcl_lightning_rods_rod.png^[brighten" } + +rod_def_a.groups.not_in_creative_inventory = 1 + +rod_def_a.mesecons = { + receptor = { + state = mesecon.state.on, + rules = mesecon.rules.alldirs, + }, +} + +rod_def_a.on_timer = function(pos, elapsed) + local node = minetest.get_node(pos) + + if node.name == "mcl_lightning_rods:rod_powered" then --has not been dug + minetest.set_node(pos, { name = "mcl_lightning_rods:rod" }) + mesecon.receptor_off(pos, mesecon.rules.alldirs) + end + + return false +end + +minetest.register_node("mcl_lightning_rods:rod_powered", rod_def_a) + + +lightning.register_on_strike(function(pos, pos2, objects) + local lr = minetest.find_node_near(pos, 128, { "group:attracts_lightning" }, true) + + if lr then + local node = minetest.get_node(lr) + + if node.name == "mcl_lightning_rods:rod" then + minetest.set_node(lr, { name = "mcl_lightning_rods:rod_powered" }) + mesecon.receptor_on(lr, mesecon.rules.alldirs) + minetest.get_node_timer(lr):start(0.4) + end + end + + return lr, nil +end) + +minetest.register_craft({ + output = "mcl_lightning_rods:rod", + recipe = { + { "", "mcl_copper:copper_ingot", "" }, + { "", "mcl_copper:copper_ingot", "" }, + { "", "mcl_copper:copper_ingot", "" }, + }, +}) diff --git a/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr new file mode 100644 index 000000000..8f99047f6 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_lightning_rods +Lightning Rod=Paratonnerre +A block that attracts lightning=Un bloc qui attire la foudre \ No newline at end of file diff --git a/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ja.tr b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ja.tr new file mode 100644 index 000000000..33376bf98 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_lightning_rods +Lightning Rod=避雷針 +A block that attracts lightning=雷を引きつけるブロック \ No newline at end of file diff --git a/mods/ITEMS/mcl_lightning_rods/locale/template.txt b/mods/ITEMS/mcl_lightning_rods/locale/template.txt new file mode 100644 index 000000000..5b2bbbcd2 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: mcl_lightning_rods +Lightning Rod= +A block that attracts lightning= \ No newline at end of file diff --git a/mods/ITEMS/mcl_lightning_rods/mod.conf b/mods/ITEMS/mcl_lightning_rods/mod.conf new file mode 100644 index 000000000..dd30d7aa7 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/mod.conf @@ -0,0 +1,3 @@ +name = mcl_lightning_rods +author = cora +depends = mcl_sounds, lightning, mesecons diff --git a/mods/ITEMS/mcl_lightning_rods/models/mcl_lightning_rods_rod.obj b/mods/ITEMS/mcl_lightning_rods/models/mcl_lightning_rods_rod.obj new file mode 100644 index 000000000..7870fc5bd --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/models/mcl_lightning_rods_rod.obj @@ -0,0 +1,90 @@ +# Blender 3.3.1 +# www.blender.org +o Cube +v -0.062500 -0.500000 0.062500 +v -0.062500 0.250000 0.062500 +v -0.062500 -0.500000 -0.062500 +v -0.062500 0.250000 -0.062500 +v 0.062500 -0.500000 0.062500 +v 0.062500 0.250000 0.062500 +v 0.062500 -0.500000 -0.062500 +v 0.062500 0.250000 -0.062500 +v -0.125000 0.250000 0.125000 +v -0.125000 0.250000 -0.125000 +v 0.125000 0.250000 -0.125000 +v 0.125000 0.250000 0.125000 +v -0.125000 0.500000 0.125000 +v -0.125000 0.500000 -0.125000 +v 0.125000 0.500000 -0.125000 +v 0.125000 0.500000 0.125000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vt 0.000000 0.750000 +vt 0.125000 0.750000 +vt 0.062500 0.937500 +vt 0.000000 0.000000 +vt 0.125000 0.000000 +vt 0.187500 0.812500 +vt 0.062500 0.937500 +vt 0.125000 0.750000 +vt -0.000000 0.750000 +vt 0.062500 0.812500 +vt 0.125000 0.000000 +vt 0.000000 -0.000000 +vt 0.062500 0.812500 +vt 0.187500 0.937500 +vt 0.125000 0.750000 +vt -0.000000 0.750000 +vt 0.187500 0.937500 +vt 0.125000 -0.000000 +vt 0.000000 -0.000000 +vt 0.062500 0.812500 +vt 0.187500 0.937500 +vt 0.125000 0.750000 +vt 0.000000 0.750000 +vt 0.187500 0.812500 +vt 0.125000 -0.000000 +vt -0.000000 0.000000 +vt 0.187500 0.812500 +vt 0.062500 0.937500 +vt 0.000000 1.000000 +vt 0.250000 0.750000 +vt -0.000000 0.750000 +vt 0.250025 0.999950 +vt -0.000000 0.750000 +vt 0.250000 0.750000 +vt 0.250000 0.750000 +vt 0.000000 1.000000 +vt -0.000000 0.750000 +vt 0.000000 0.750000 +vt 0.250000 1.000000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt -0.000000 1.000000 +vt 0.250000 0.750000 +vt 0.000100 0.999900 +vt 0.250000 1.000000 +vt 0.250000 1.000000 +vt 0.000000 0.750000 +vt 0.000100 0.999900 +vt 0.000000 1.000000 +vt 0.250000 1.000000 +s 0 +f 1/1/1 2/4/1 4/11/1 3/8/1 +f 3/9/2 4/12/2 8/25/2 7/22/2 +f 7/23/3 8/26/3 6/18/3 5/15/3 +f 5/16/4 6/19/4 2/5/4 1/2/4 +f 3/10/5 7/24/5 5/17/5 1/3/5 +f 8/27/5 4/13/5 10/33/5 11/35/5 +f 12/38/3 11/35/3 15/46/3 16/49/3 +f 6/20/5 8/28/5 11/36/5 12/38/5 +f 4/14/5 2/6/5 9/30/5 10/32/5 +f 2/7/5 6/21/5 12/39/5 9/29/5 +f 15/47/6 14/43/6 13/41/6 16/49/6 +f 10/33/1 9/30/1 13/41/1 14/44/1 +f 9/31/4 12/40/4 16/50/4 13/42/4 +f 11/37/2 10/34/2 14/45/2 15/48/2 diff --git a/mods/ITEMS/mcl_lightning_rods/textures/mcl_lightning_rods_rod.png b/mods/ITEMS/mcl_lightning_rods/textures/mcl_lightning_rods_rod.png new file mode 100644 index 000000000..355b2bd01 Binary files /dev/null and b/mods/ITEMS/mcl_lightning_rods/textures/mcl_lightning_rods_rod.png differ diff --git a/mods/ITEMS/mcl_loom/README.md b/mods/ITEMS/mcl_loom/README.md index 08ee0dea3..e91bad8fd 100644 --- a/mods/ITEMS/mcl_loom/README.md +++ b/mods/ITEMS/mcl_loom/README.md @@ -10,4 +10,10 @@ LGPLv2.1 License of media ---------------- -See the main MineClone 2 README.md file. \ No newline at end of file + +loom_bottom.png +loom_front.png +loom_side.png +loom_top.png +License: CC BY-SA 4.0 +Author: MrRar diff --git a/mods/ITEMS/mcl_loom/init.lua b/mods/ITEMS/mcl_loom/init.lua index 6126a5d39..19be8d58b 100644 --- a/mods/ITEMS/mcl_loom/init.lua +++ b/mods/ITEMS/mcl_loom/init.lua @@ -8,11 +8,13 @@ minetest.register_node("mcl_loom:loom", { tiles = { "loom_top.png", "loom_bottom.png", "loom_side.png", "loom_side.png", - "loom_front.png", "loom_front.png" + "loom_side.png", "loom_front.png" }, paramtype2 = "facedir", - groups = {choppy=1, deco_block=1, material_wood=1, flammable=1} - }) + groups = { axey = 2, handy = 1, deco_block = 1, material_wood = 1, flammable = 1 }, + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5 +}) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_loom/locale/mcl_loom.fr.tr b/mods/ITEMS/mcl_loom/locale/mcl_loom.fr.tr new file mode 100644 index 000000000..410099428 --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/mcl_loom.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_loom +Loom=Métier à tisser +Used to create banner designs=Utilisé pour créer des motifs de bannières +This is the shepherd villager's work station. It is used to create banner designs.=Ceci est le poste de travail du villageois berger. Il est utilisé pour créer des motifs de bannière. \ No newline at end of file diff --git a/mods/ITEMS/mcl_loom/locale/mcl_loom.ja.tr b/mods/ITEMS/mcl_loom/locale/mcl_loom.ja.tr new file mode 100644 index 000000000..8e5e8b076 --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/mcl_loom.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_loom +Loom=機織り機 +Used to create banner designs=旗のデザイン作成に使用 +This is the shepherd villager's work station. It is used to create banner designs.=羊飼いの村人の職場です。旗のデザイン作成に使用します。 diff --git a/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr b/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr new file mode 100644 index 000000000..2442f76d5 --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_loom +Loom=Ткацкий станок +Used to create banner designs=Позволяет создавать узоры на флаге +This is the shepherd villager's work station. It is used to create banner designs.=Это рабочее место пастуха. Позволяет создавать узоры на флаге diff --git a/mods/ITEMS/mcl_loom/locale/template.txt b/mods/ITEMS/mcl_loom/locale/template.txt new file mode 100644 index 000000000..31905ea02 --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: mcl_loom +Loom= +Used to create banner designs= +This is the shepherd villager's work station. It is used to create banner designs.= diff --git a/mods/ITEMS/mcl_loom/textures/loom_bottom.png b/mods/ITEMS/mcl_loom/textures/loom_bottom.png index 835d36fca..bf4e7c0c5 100644 Binary files a/mods/ITEMS/mcl_loom/textures/loom_bottom.png and b/mods/ITEMS/mcl_loom/textures/loom_bottom.png differ diff --git a/mods/ITEMS/mcl_loom/textures/loom_bottom1.png b/mods/ITEMS/mcl_loom/textures/loom_bottom1.png deleted file mode 100644 index f5dfe8189..000000000 Binary files a/mods/ITEMS/mcl_loom/textures/loom_bottom1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_loom/textures/loom_front.png b/mods/ITEMS/mcl_loom/textures/loom_front.png index ba1aebc80..83191e649 100644 Binary files a/mods/ITEMS/mcl_loom/textures/loom_front.png and b/mods/ITEMS/mcl_loom/textures/loom_front.png differ diff --git a/mods/ITEMS/mcl_loom/textures/loom_front1.png b/mods/ITEMS/mcl_loom/textures/loom_front1.png deleted file mode 100644 index 411e51891..000000000 Binary files a/mods/ITEMS/mcl_loom/textures/loom_front1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_loom/textures/loom_side.png b/mods/ITEMS/mcl_loom/textures/loom_side.png index bbeaeb6d8..3e64107c7 100644 Binary files a/mods/ITEMS/mcl_loom/textures/loom_side.png and b/mods/ITEMS/mcl_loom/textures/loom_side.png differ diff --git a/mods/ITEMS/mcl_loom/textures/loom_side1.png b/mods/ITEMS/mcl_loom/textures/loom_side1.png deleted file mode 100644 index baf1aed5d..000000000 Binary files a/mods/ITEMS/mcl_loom/textures/loom_side1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_loom/textures/loom_top.png b/mods/ITEMS/mcl_loom/textures/loom_top.png index af980f3c1..cf0c1e3eb 100644 Binary files a/mods/ITEMS/mcl_loom/textures/loom_top.png and b/mods/ITEMS/mcl_loom/textures/loom_top.png differ diff --git a/mods/ITEMS/mcl_loom/textures/loom_top1.png b/mods/ITEMS/mcl_loom/textures/loom_top1.png deleted file mode 100644 index febcb864d..000000000 Binary files a/mods/ITEMS/mcl_loom/textures/loom_top1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_mangrove/init.lua b/mods/ITEMS/mcl_mangrove/init.lua new file mode 100644 index 000000000..410da28d4 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/init.lua @@ -0,0 +1,563 @@ +local S = minetest.get_translator("mcl_mangrove") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local propagule_allowed_nodes = { + "mcl_core:dirt", + "mcl_core:coarse_dirt", + "mcl_core:dirt_with_grass", + "mcl_core:podzol", + "mcl_core:mycelium", + "mcl_lush_caves:rooted_dirt", + "mcl_lush_caves:moss", + "mcl_farming:soil", + "mcl_farming:soil_wet", + "mcl_core:clay", + "mcl_mud:mud", +} +local propagule_water_nodes = {"mcl_mud:mud","mcl_core:dirt","mcl_core:coarse_dirt","mcl_core:clay"} + --"mcl_lush_caves:moss","mcl_lush_caves:rooted_dirt + +local function get_drops(fortune_level) + local apple_chances = {200, 180, 160, 120, 40} + local stick_chances = {50, 45, 30, 35, 10} + local sapling_chances = {20, 16, 12, 10} + return { + max_items = 1, + items = { + { + items = {"mcl_mangrove:propagule"}, + rarity = sapling_chances[fortune_level + 1] or sapling_chances[fortune_level] + }, + { + items = {"mcl_core:stick 1"}, + rarity = stick_chances[fortune_level + 1] + }, + { + items = {"mcl_core:stick 2"}, + rarity = stick_chances[fortune_level + 1] + }, + { + items = {"mcl_core:apple"}, + rarity = apple_chances[fortune_level + 1] + } + } + } +end + +minetest.register_node("mcl_mangrove:mangrove_tree", { + description = S("Mangrove Wood"), + _doc_items_longdesc = S("The trunk of a Mangrove tree."), + _doc_items_hidden = false, + tiles = {"mcl_mangrove_log_top.png", "mcl_mangrove_log_top.png", "mcl_mangrove_log.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + after_destruct = mcl_core.update_leaves, + 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(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_mangrove:mangrove_stripped_trunk", +}) +minetest.register_node("mcl_mangrove:mangrove_tree_bark", { + description = S("Mangrove Bark"), + _doc_items_longdesc = S("The bark of a Mangrove tree."), + _doc_items_hidden = false, + tiles = {"mcl_mangrove_log.png", "mcl_mangrove_log.png", "mcl_mangrove_log.png"}, + paramtype2 = "facedir", + 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_place = mcl_util.rotate_axis, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_mangrove:mangrove_stripped_bark", +}) + +minetest.register_node("mcl_mangrove:mangrove_wood", { + description = S("Mangrove Wood Planks"), + _doc_items_longdesc = doc.sub.items.temp.build, + _doc_items_hidden = false, + tiles = {"mcl_mangrove_planks.png"}, + + is_ground_content = false, + groups = {handy=1,axey=1, flammable=3,wood=1,building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=20}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 2, +}) + +local l_def = { + description = S("Mangrove Leaves"), + _doc_items_longdesc = S("mangrove leaves are grown from mangrove trees."), + _doc_items_hidden = false, + drawtype = "allfaces_optional", + waving = 2, + place_param2 = 1, -- Prevent leafdecay for placed nodes + tiles = {"mcl_mangrove_leaves.png"}, + paramtype = "light", + groups = { + handy = 1, hoey = 1, shearsy = 1, swordy = 1, dig_by_piston = 1, + flammable = 2, fire_encouragement = 30, fire_flammability = 60, + leaves = 1, deco_block = 1, compostability = 30 + }, + drop = get_drops(0), + _mcl_shears_drop = true, + sounds = mcl_sounds.node_sound_leaves_defaults(), + _mcl_blast_resistance = 0.2, + _mcl_hardness = 0.2, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { get_drops(1), get_drops(2), get_drops(3), get_drops(4) }, +} + +minetest.register_node("mcl_mangrove:mangroveleaves", l_def) + +local o_def = table.copy(l_def) +o_def._doc_items_create_entry = false +o_def.place_param2 = nil +o_def.groups.not_in_creative_inventory = 1 +o_def.groups.orphan_leaves = 1 +o_def._mcl_shears_drop = {"mcl_mangrove:mangroveleaves"} +o_def._mcl_silk_touch_drop = {"mcl_mangrove:mangroveleaves"} + +minetest.register_node("mcl_mangrove:mangroveleaves_orphan", o_def) + +minetest.register_node("mcl_mangrove:mangrove_stripped_trunk", { + description = S("Stripped Mangrove Wood"), + _doc_items_longdesc = S("The stripped wood of a Mangrove tree"), + _doc_items_hidden = false, + tiles ={"mcl_stripped_mangrove_log_top.png","mcl_stripped_mangrove_log_side.png",}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + 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 = mcl_util.rotate_axis_and_place, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) +minetest.register_node("mcl_mangrove:mangrove_stripped_bark", { + description = S("Stripped Mangrove Bark"), + _doc_items_longdesc = S("The stripped bark of a Mangrove tree"), + _doc_items_hidden = false, + tiles ={"mcl_stripped_mangrove_log_side.png","mcl_stripped_mangrove_log_side.png",}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + 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 = mcl_util.rotate_axis_and_place, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_mangrove:mangrove_roots", { + description = S("Mangrove Roots"), + _doc_items_longdesc = S("Mangrove roots are decorative blocks that form as part of mangrove trees."), + _doc_items_hidden = false, + waving = 0, + place_param2 = 1, -- Prevent leafdecay for placed nodes + tiles = { + "mcl_mangrove_roots_top.png", + "mcl_mangrove_roots_side.png", + "mcl_mangrove_roots_side.png", + }, + paramtype = "light", + drawtype = "allfaces_optional", + groups = { + handy = 1, hoey = 1, shearsy = 1, axey = 1, swordy = 1, dig_by_piston = 0, + flammable = 10, fire_encouragement = 30, fire_flammability = 60, + deco_block = 1, compostability = 30 + }, + drop = "mcl_mangrove:mangrove_roots", + _mcl_shears_drop = true, + sounds = mcl_sounds.node_sound_leaves_defaults(), + _mcl_blast_resistance = 0.7, + _mcl_hardness = 0.7, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { "mcl_mangrove:mangrove_roots 1", "mcl_mangrove:mangrove_roots 2", "mcl_mangrove:mangrove_roots 3", "mcl_mangrove:mangrove_roots 4" }, +}) + +minetest.register_node("mcl_mangrove:propagule", { + description = S("Mangrove Propagule"), + _tt_help = S("Needs soil and light to grow"), + _doc_items_longdesc = S("When placed on soil (such as dirt) and exposed to light, an propagule will grow into an mangrove after some time."), + _doc_items_hidden = false, + drawtype = "plantlike", + waving = 1, + visual_scale = 1.0, + tiles = {"mcl_mangrove_propagule_item.png"}, + inventory_image = "mcl_mangrove_propagule_item.png", + wield_image = "mcl_mangrove_propagule_item.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-5/16, -0.5, -5/16, 5/16, 0.5, 5/16} + }, + groups = { + plant = 1, sapling = 1, non_mycelium_plant = 1, attached_node = 1, + deco_block = 1, dig_immediate = 3, dig_by_water = 0, dig_by_piston = 1, + destroy_by_lava_flow = 1, compostability = 30 + }, + sounds = mcl_sounds.node_sound_leaves_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_int("stage", 0) + end, + node_placement_prediction = "", + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + on_place = mcl_util.generate_on_place_plant_function(function(place_pos, place_node,stack) + local under = vector.offset(place_pos,0,-1,0) + local snn = minetest.get_node_or_nil(under).name + if not snn then return false end + if table.indexof(propagule_allowed_nodes,snn) ~= -1 then + local n = minetest.get_node(place_pos) + if minetest.get_item_group(n.name,"water") > 0 and table.indexof(propagule_water_nodes,snn) ~= -1 then + minetest.set_node(under,{name="mcl_mangrove:propagule_"..snn:split(":")[2]}) + stack:take_item() + return stack + end + return true + end + end) +}) + +minetest.register_node("mcl_mangrove:hanging_propagule_1", { + description = S("Hanging Propagule"), + _tt_help = S("Grows on Mangrove leaves"), + _doc_items_longdesc = "", + _doc_items_usagehelp = "", + groups = { + plant = 1, not_in_creative_inventory=1, non_mycelium_plant = 1, + deco_block = 1, dig_immediate = 3, dig_by_water = 0, dig_by_piston = 1, + destroy_by_lava_flow = 1, compostability = 30 + }, + paramtype = "light", + paramtype2 = "", + on_rotate = false, + walkable = false, + drop = "mcl_mangrove:propagule", + use_texture_alpha = "clip", + drawtype = 'mesh', + mesh = 'propagule_hanging.obj', + selection_box = { + type = "fixed", + fixed = { + {-0.125, -0.5, -0.125, 0.125, 0.5, 0.125}, -- Base + }, + }, + tiles = {"mcl_mangrove_propagule_hanging.png"}, + inventory_image = "mcl_mangrove_propagule.png", + wield_image = "mcl_mangrove_propagule.png", +}) +local propagule_rooted_nodes = {} +for _,root in pairs(propagule_water_nodes) do + local r = root:split(":")[2] + local def = minetest.registered_nodes[root] + local tx = def.tiles + local n = "mcl_mangrove:propagule_"..r + table.insert(propagule_rooted_nodes,n) + minetest.register_node(n, { + drawtype = "plantlike_rooted", + paramtype = "light", + place_param2 = 1, + tiles = tx, + special_tiles = { { name = "mcl_mangrove_propagule_item.png" } }, + inventory_image = "mcl_mangrove_propagule_item.png", + wield_image = "mcl_mangrove_propagule.png", + selection_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, 0.5, -0.5, 0.5, 1.0, 0.5 }, + } + }, + groups = { + plant = 1, sapling = 1, non_mycelium_plant = 1, attached_node = 1,not_in_creative_inventory=1, + deco_block = 1, dig_immediate = 3, dig_by_piston = 1, + destroy_by_lava_flow = 1, compostability = 30 + }, + sounds = mcl_sounds.node_sound_leaves_defaults(), + drop = "mcl_mangrove:propagule", + node_placement_prediction = "", + node_dig_prediction = "", + after_dig_node = function(pos) + minetest.set_node(pos, {name=root}) + end, + _mcl_hardness = 0, + _mcl_blast_resistance = 0, + _mcl_silk_touch_drop = true, + }) + +end + + +mcl_flowerpots.register_potted_flower("mcl_mangrove:propagule", { + name = "propagule", + desc = S("Mangrove Propagule"), + image = "mcl_mangrove_propagule.png", +}) + +local water_tex = "default_water_source_animated.png^[verticalframe:16:0" + +local wlroots = { + description = S("water logged mangrove roots"), + _doc_items_entry_name = S("water logged mangrove roots"), + _doc_items_longdesc = + S("Mangrove roots are decorative blocks that form as part of mangrove trees.").."\n\n".. + S("Mangrove roots, despite being a full block, can be waterlogged and do not flow water out").."\n\n".. + S("These cannot be crafted yet only occure when get in contact of water."), + _doc_items_hidden = false, + tiles = { + {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} + }, + special_tiles = { + -- New-style water source material (mostly unused) + { + name="default_water_source_animated.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}, + backface_culling = false, + } + }, + overlay_tiles = { + "mcl_mangrove_roots_top.png", + "mcl_mangrove_roots_side.png", + "mcl_mangrove_roots_side.png", + }, + sounds = mcl_sounds.node_sound_water_defaults(), + drawtype = "allfaces_optional", + use_texture_alpha = "blend", + is_ground_content = false, + paramtype = "light", + walkable = true, + pointable = true, + diggable = true, + buildable_to = false, + liquids_pointable = true, + drop = "mcl_mangrove:mangrove_roots", + groups = { + handy = 1, hoey = 1, water=3, liquid=3, puts_out_fire=1, dig_by_piston = 1, deco_block = 1, not_in_creative_inventory=1 }, + _mcl_blast_resistance = 100, + _mcl_hardness = -1, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode + after_dig_node = function(pos) + local node = minetest.get_node(pos) + if minetest.get_item_group(node.name, "water") == 0 then + minetest.set_node(pos, {name="mcl_core:water_source"}) + end + end, +} +local rwlroots = table.copy(wlroots) +-- FIXME luacheck complains that this is a repeated definition of water_tex. +-- Maybe the tiles definition below should be replaced with the animated tile +-- definition as per above? +water_tex = "default_river_water_source_animated.png^[verticalframe:16:0" +rwlroots.tiles = { + "("..water_tex..")^mcl_mangrove_roots_top.png", + "("..water_tex..")^mcl_mangrove_roots_side.png", + "("..water_tex..")^mcl_mangrove_roots_side.png", +} + +minetest.register_node("mcl_mangrove:water_logged_roots", wlroots) +minetest.register_node("mcl_mangrove:river_water_logged_roots",rwlroots) + +minetest.register_node("mcl_mangrove:mangrove_mud_roots", { + description = S("Muddy Mangrove Roots"), + _tt_help = S("crafted with Mud and Mangrove roots"), + _doc_items_longdesc = S("Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it."), + tiles = { + "mcl_mud.png^mcl_mangrove_roots_top.png", + "mcl_mud.png^mcl_mangrove_roots_side.png", + "mcl_mud.png^mcl_mangrove_roots_side.png", + }, + is_ground_content = true, + groups = {handy = 1, shovely = 1, axey = 1, building_block = 1}, + sounds = mcl_sounds.node_sound_sand_defaults(), + _mcl_blast_resistance = 0.7, + _mcl_hardness = 0.7, +}) + +mcl_doors:register_door("mcl_mangrove:mangrove_door", { + description = S("Mangrove Door"), + _doc_items_longdesc = S("Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal."), + _doc_items_usagehelp = S("To open or close a wooden door, rightclick it or supply its lower half with a redstone signal."), + inventory_image = "mcl_mangrove_doors.png", + groups = {handy=1,axey=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = {"mcl_mangrove_door_bottom.png", "mcl_doors_door_mangrove_side_lower.png"}, + tiles_top = {"mcl_mangrove_door_top.png", "mcl_doors_door_mangrove_side_upper.png"}, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_doors:register_trapdoor("mcl_mangrove:mangrove_trapdoor", { + description = S("Mangrove Trapdoor"), + _doc_items_longdesc = S("Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder."), + _doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."), + tile_front = "mcl_mangrove_trapdoor.png", + tile_side = "mcl_mangrove_planks.png", + wield_image = "mcl_mangrove_trapdoor.png", + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_fences.register_fence_and_fence_gate( + "mangrove_wood_fence", + S("Mangrove Wood Fence"), + S("Mangrove Wood Fence Gate"), + "mcl_mangrove_fence.png", + {handy=1,axey=1, flammable=2,fence_wood=1, fire_encouragement=5, fire_flammability=20}, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + {"group:fence_wood"}, + mcl_sounds.node_sound_wood_defaults(), "mcl_mangrove_mangrove_wood_fence_gate_open", "mcl_mangrove_mangrove_wood_fence_gate_close", 1, 1, + "mcl_mangrove_fence_gate.png") + +mcl_stairs.register_stair("mangrove_wood", "mcl_mangrove:mangrove_wood", + {handy=1,axey=1, flammable=3,wood_stairs=1, material_wood=1, fire_encouragement=5, fire_flammability=20}, + {"mcl_mangrove_planks.png"}, + S("Mangrove Wood Stairs"), + mcl_sounds.node_sound_wood_defaults(), 3, 2, + "woodlike") + +mcl_stairs.register_slab("mangrove_wood", "mcl_mangrove:mangrove_wood", + {handy=1,axey=1, flammable=3,wood_slab=1, material_wood=1, fire_encouragement=5, fire_flammability=20}, + {"mcl_mangrove_planks.png"}, + S("Mangrove Wood Slab"), + mcl_sounds.node_sound_wood_defaults(), 3, 2, + S("Double Mangrove Wood Slab")) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_tree_bark 3", + recipe = { + { "mcl_mangrove:mangrove_tree", "mcl_mangrove:mangrove_tree" }, + { "mcl_mangrove:mangrove_tree", "mcl_mangrove:mangrove_tree" }, + } +}) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_mud_roots", + recipe = { + {"mcl_mangrove:mangrove_roots", "mcl_mud:mud",}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_mangrove:mangrove_door", + burntime = 15, +}) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_door 3", + recipe = { + {"mcl_mangrove:mangrove_wood", "mcl_mangrove:mangrove_wood"}, + {"mcl_mangrove:mangrove_wood", "mcl_mangrove:mangrove_wood"}, + {"mcl_mangrove:mangrove_wood", "mcl_mangrove:mangrove_wood"}, + } +}) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_trapdoor 2", + recipe = { + {"mcl_mangrove:mangrove_wood","mcl_mangrove:mangrove_wood","mcl_mangrove:mangrove_wood"}, + {"mcl_mangrove:mangrove_wood","mcl_mangrove:mangrove_wood","mcl_mangrove:mangrove_wood"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_mangrove:mangrove_trapdoor", + burntime = 15, +}) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood_fence_gate", + recipe = { + {"mcl_core:stick", "mcl_mangrove:mangrove_wood", "mcl_core:stick"}, + {"mcl_core:stick", "mcl_mangrove:mangrove_wood", "mcl_core:stick"}, + } + }) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood_fence 3", + recipe = { + {"mcl_mangrove:mangrove_wood", "mcl_core:stick", "mcl_mangrove:mangrove_wood"}, + {"mcl_mangrove:mangrove_wood", "mcl_core:stick", "mcl_mangrove:mangrove_wood"}, + } + }) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood 4", + recipe = { + {"mcl_mangrove:mangrove_tree"}, + } + }) + +minetest.register_craft({ + type = "fuel", + recipe = "group:fence_wood", + burntime = 15, +}) + +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +minetest.register_abm({ + label = "Waterlog mangrove roots", + nodenames = {"mcl_mangrove:mangrove_roots"}, + neighbors = {"group:water"}, + interval = 5, + chance = 5, + action = function(pos,value) + for _,v in pairs(adjacents) do + local n = minetest.get_node(vector.add(pos,v)).name + if minetest.get_item_group(n,"water") > 0 then + if n:find("river") then + minetest.swap_node(pos,{name="mcl_mangrove:river_water_logged_roots"}) + return + else + minetest.swap_node(pos,{name="mcl_mangrove:water_logged_roots"}) + return + end + end + end + end +}) + +local abm_nodes = table.copy(propagule_rooted_nodes) +table.insert(abm_nodes,"mcl_mangrove:propagule") +minetest.register_abm({ + label = "Mangrove_tree_growth", + nodenames = abm_nodes, + interval = 30, + chance = 5, + action = function(pos,node) + local pr = PseudoRandom(pos.x+pos.y+pos.z) + local r = pr:next(1,5) + local path = modpath .."/schematics/mcl_mangrove_tree_"..tostring(r)..".mts" + local w = 5 + local h = 10 + local fp = true + pos.y = pos.y - 1 + if table.indexof(propagule_rooted_nodes,node.name) ~= -1 then + local nn = minetest.find_nodes_in_area(vector.offset(pos,0,-1,0),vector.offset(pos,0,h,0),{"group:water","air"}) + if #nn >= h then + minetest.place_schematic(pos, path, "random", function() + local nnv = minetest.find_nodes_in_area(vector.offset(pos,-5,-1,-5),vector.offset(pos,5,h/2,5),{"mcl_core:vine"}) + minetest.bulk_set_node(nnv,{"air"}) + end, true, "place_center_x, place_center_z") + end + return + end + if r > 3 then h = 18 end + if mcl_core.check_growth_width(pos,w,h) then + minetest.place_schematic(pos, path, "random", nil, true, "place_center_x, place_center_z") + end +end +}) diff --git a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr new file mode 100644 index 000000000..d5a2bb74e --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_mangrove +Mangrove Wood=Bûche de Palétuvier +The trunk of a Mangrove tree.=Le tronc d'un Palétuvier. +Mangrove Bark=Bois de Palétuvier +The bark of a Mangrove tree.=L'écorce d'un Palétuvier. +Mangrove Wood Planks=Planches de Palétuvier +Mangrove Leaves=Feuilles de Palétuvier +mangrove leaves are grown from mangrove trees.=les feuilles de palétuvier poussent sur les palétuviers. +Stripped Mangrove Wood=Bûche de Palétuvier Ecorcée +The stripped wood of a Mangrove tree=La bûche écorcée d'un palétuvier +Stripped Mangrove Bark=Bois de Palétuvier Ecorcé +The stripped bark of a Mangrove tree=Le bois écorcé d'un palétuvier +Mangrove Roots=Racines de Palétuvier +Mangrove roots are decorative blocks that form as part of mangrove trees.=Les racines de palétuvier sont des blocs décoratifs qui font partie des palétuviers. +Mangrove Propagule=Propagule de Palétuvier +Needs soil and light to grow=A besoin de terre et de lumière pour pousser +When placed on soil (such as dirt) and exposed to light, an propagule will grow into an mangrove after some time.=Lorsque placé sur la terre et exposée à la lumière, une propagule pousera en palétuvier après un certain temps. +Hanging Propagule=Propagule suspendue +Grows on Mangrove leaves=Pousse sur les feuilles de Palétuvier +water logged mangrove roots=racines de palétuvier immergées +Mangrove roots, despite being a full block, can be waterlogged and do not flow water out=Les racines de palétuvier sont un bloc plein mais qui peut être immergé et ne remplace pas l'eau. +These cannot be crafted yet only occure when get in contact of water.=Elles ne peuvent être fabriquées mais se forment au contact de l'eau. +Muddy Mangrove Roots=Racines de Palétuvier Boueuses +crafted with Mud and Mangrove roots=fabriqué avec de la Boue et des racines de Palétuvier +Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it.=Les Racines de Palétuvier Boueuses sont un bloc du marécage de la mangrove. Il noie un joueur à l'intérieur. +Mangrove Door=Porte en Palétuvier +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Les portes en bois sont des barrières hautes à 2 blocs qui peuvent être ouvertes ou fermées à la main et par un signal redstone. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Pour ouvrir ou fermer une porte en bois, faites un clic droit dessus ou fournissez à sa moitié inférieure un signal redstone. +Mangrove Trapdoor=Trappe en Palétuvier +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Les trappes de bois sont des barrières horizontales qui peuvent être ouvertes et fermées à la main ou avec un signal redstone. Elles occupent la partie haut ou bas d'un bloc, selon la manière dont elles ont été placées. +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Pour ouvrir et fermer la trappe, la cliquer droit ou lui envoyer un signal redstone. +Mangrove Wood Fence=Barrière de Palétuvier +Mangrove Wood Fence Gate=Portillion de Palétuvier +Mangrove Wood Stairs=Escalier en Bois de Palétuvier +Mangrove Wood Slab=Dalle en Bois de Palétuvier +Double Mangrove Wood Slab=Double Dalle en Bois de Palétuvier diff --git a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr new file mode 100644 index 000000000..142495e92 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_mangrove +Mangrove Wood=マングローブの木 +The trunk of a Mangrove tree.=マングローブの樹幹部分です。 +Mangrove Bark=マングローブの樹皮 +The bark of a Mangrove tree.=マングローブの木の樹皮です。 +Mangrove Wood Planks=マングローブの板材 +Mangrove Leaves=マングローブの葉 +mangrove leaves are grown from mangrove trees.=マングローブの葉は、マングローブの木から育ちます。 +Stripped Mangrove Wood=樹皮を剥いだマングローブの木 +The stripped wood of a Mangrove tree=剥き身となったマングローブの木 +Stripped Mangrove Bark=剥がされたマングローブの樹皮 +The stripped bark of a Mangrove tree=マングローブの木から剥がされた樹皮 +Mangrove Roots=マングローブの根 +Mangrove roots are decorative blocks that form as part of mangrove trees.=マングローブの根は、マングローブの木の一部として形成される装飾ブロックです。 +Mangrove Propagule=マングローブの芽 +Needs soil and light to grow=生育に必要なのは土と光 +When placed on soil (such as dirt) and exposed to light, an propagule will grow into an mangrove after some time.=土壌(土など)の上に置き、光を当てると、しばらくのちマングローブに成長します。 +Hanging Propagule=芽 +Grows on Mangrove leaves=マングローブの葉に生育 +water logged mangrove roots=水没したマングローブの根 +Mangrove roots, despite being a full block, can be waterlogged and do not flow water out=マングローブの根は、フルブロックであるにもかかわらず水没することがあり、水が流出しない +These cannot be crafted yet only occure when get in contact of water.=これはクラフトできないものの、水と接触したときだけ発生します。 +Muddy Mangrove Roots=泥に塗れたマングローブの根 +crafted with Mud and Mangrove roots=泥とマングローブの根で作られたもの +Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it.=泥に塗れたマングローブの根は、マングローブの沼地から1ブロックの場所にあります。 +Mangrove Door=マングローブのドア +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=木製のドアは、高さ2ブロックの障壁で、手やレッドストーンの信号で開閉できます。 +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=木製のドアを開閉するには、右クリックするか、下半分にレッドストーン信号を供給してください。 +Mangrove Trapdoor=マングローブのトラップドア +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=木製のトラップドアは、手やレッドストーンの信号で開閉できる水平障壁です。配置の仕方によって、ブロックの上部または下部を占めます。開いているときは、梯子のようによじ登ることができます。 +To open or close the trapdoor, rightclick it or send a redstone signal to it.=トラップドアを開閉するには、トラップドアを右クリックするか、レッドストーン信号を送信してください。 +Mangrove Wood Fence=マングローブのフェンス +Mangrove Wood Fence Gate=マングローブのフェンスゲート +Mangrove Wood Stairs=マングローブの階段 +Mangrove Wood Slab=マングローブのスラブ +Double Mangrove Wood Slab=マングローブの2重スラブ diff --git a/mods/ITEMS/mcl_mangrove/locale/template.txt b/mods/ITEMS/mcl_mangrove/locale/template.txt new file mode 100644 index 000000000..7e0a25450 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/locale/template.txt @@ -0,0 +1,36 @@ +# textdomain: mcl_mangrove +Mangrove Wood= +The trunk of a Mangrove tree.= +Mangrove Bark= +The bark of a Mangrove tree.= +Mangrove Wood Planks= +Mangrove Leaves= +mangrove leaves are grown from mangrove trees.= +Stripped Mangrove Wood= +The stripped wood of a Mangrove tree= +Stripped Mangrove Bark= +The stripped bark of a Mangrove tree= +Mangrove Roots= +Mangrove roots are decorative blocks that form as part of mangrove trees.= +Mangrove Propagule= +Needs soil and light to grow= +When placed on soil (such as dirt) and exposed to light, an propagule will grow into an mangrove after some time.= +Hanging Propagule= +Grows on Mangrove leaves= +water logged mangrove roots= +Mangrove roots, despite being a full block, can be waterlogged and do not flow water out= +These cannot be crafted yet only occure when get in contact of water.= +Muddy Mangrove Roots= +crafted with Mud and Mangrove roots= +Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it.= +Mangrove Door= +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.= +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.= +Mangrove Trapdoor= +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.= +To open or close the trapdoor, rightclick it or send a redstone signal to it.= +Mangrove Wood Fence= +Mangrove Wood Fence Gate= +Mangrove Wood Stairs= +Mangrove Wood Slab= +Double Mangrove Wood Slab= diff --git a/mods/ITEMS/mcl_mangrove/mod.conf b/mods/ITEMS/mcl_mangrove/mod.conf new file mode 100644 index 000000000..fb71efbf8 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/mod.conf @@ -0,0 +1,3 @@ +name = mcl_mangrove +author = thunder1035 +depends = mcl_core, mcl_doors, mcl_stairs, mcl_walls, mclx_fences, mcl_boats, mcl_flowerpots, mcl_mud, mcl_util diff --git a/mods/ITEMS/mcl_mangrove/models/propagule.obj b/mods/ITEMS/mcl_mangrove/models/propagule.obj new file mode 100644 index 000000000..598573020 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/models/propagule.obj @@ -0,0 +1,73 @@ +# Blender v3.1.2 OBJ File: 'propagule.blend' +# www.blender.org +mtllib propagule.mtl +o Plane +v 0.500000 0.499931 0.499931 +v 0.500000 -0.499931 0.499931 +v 0.500000 0.499931 -0.499931 +v 0.500000 -0.499931 -0.499931 +v -0.500000 0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 0.500000 -0.500000 +v -0.500000 0.500000 -0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v -0.347329 1.500000 0.359670 +v 0.347329 1.500000 -0.359670 +v 0.347329 0.500000 -0.359670 +v -0.347329 0.500000 0.359670 +v -0.359670 1.500000 -0.347329 +v 0.359670 1.500000 0.347329 +v 0.359670 0.500000 0.347329 +v -0.359670 0.500000 -0.347329 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499987 +vt 0.000000 0.499987 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499868 +vt 0.000000 0.499868 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499868 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499868 +vt 0.000000 0.499868 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499868 +vt 0.000000 0.499868 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.499985 +vt 0.000000 0.499985 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.499985 +vt 0.000000 0.499985 +vn 1.0000 0.0000 0.0000 +vn -0.5774 0.5774 0.5774 +vn 0.0000 0.7071 0.7071 +vn 0.0000 0.7071 -0.7071 +vn -0.5774 0.5774 -0.5774 +vn -0.7071 0.0000 -0.7071 +vn -0.7071 -0.0000 0.7071 +vn 0.0000 0.0000 -1.0000 +vn -0.0000 -0.0000 1.0000 +vn -0.7193 0.0000 -0.6947 +vn 0.6947 0.0000 -0.7193 +usemtl default_dirt.png.001 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +s 1 +f 5/5/2 6/6/3 7/7/4 8/8/5 +f 9/9/6 10/10/7 5/11/2 8/8/5 +f 11/12/8 9/13/6 8/14/5 7/15/4 +f 10/16/7 12/17/9 6/18/3 5/19/2 +usemtl mcl_mangrove_propagule.png.001 +f 13/20/10 14/21/10 15/22/10 16/23/10 +f 17/24/11 18/25/11 19/26/11 20/27/11 diff --git a/mods/ITEMS/mcl_mangrove/models/propagule_hanging.obj b/mods/ITEMS/mcl_mangrove/models/propagule_hanging.obj new file mode 100644 index 000000000..0a8be50d0 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/models/propagule_hanging.obj @@ -0,0 +1,975 @@ +# Blender v3.1.2 OBJ File: 'propagule_hanging.blend' +# www.blender.org +mtllib propagule_hanging.mtl +o plant +v 0.000000 0.470112 0.000000 +v 0.000000 -0.529888 0.000000 +v 0.000000 -0.529888 0.000000 +v 0.000000 0.470112 0.000000 +v 0.000000 -0.029888 0.000000 +v 0.000000 -0.029888 0.000000 +v 0.000000 -0.279888 0.000000 +v 0.000000 0.220112 0.000000 +v 0.000000 -0.279888 0.000000 +v 0.000000 0.220112 0.000000 +v -0.086832 0.470112 0.089918 +v 0.086832 -0.529888 -0.089917 +v 0.089917 -0.529888 0.086832 +v -0.089918 0.470112 -0.086832 +v 0.000000 -0.404888 0.000000 +v 0.000000 0.095112 0.000000 +v 0.089917 -0.029888 0.086832 +v 0.000000 -0.404888 0.000000 +v 0.000000 0.095112 0.000000 +v 0.086832 -0.029888 -0.089917 +v 0.086832 0.470112 -0.089917 +v -0.086832 -0.529888 0.089917 +v -0.089917 -0.529888 -0.086832 +v 0.089917 0.470112 0.086832 +v 0.000000 -0.154888 0.000000 +v 0.000000 0.345112 0.000000 +v -0.089917 -0.029888 -0.086832 +v 0.000000 -0.154888 0.000000 +v 0.000000 0.345112 0.000000 +v -0.086832 -0.029888 0.089918 +v 0.086832 0.220112 -0.089917 +v -0.086832 0.220112 0.089918 +v -0.086832 -0.279888 0.089917 +v 0.089917 0.220112 0.086832 +v -0.089918 0.220112 -0.086832 +v -0.089917 -0.279888 -0.086832 +v 0.089917 -0.279888 0.086832 +v 0.086832 -0.279888 -0.089917 +v 0.086832 -0.154888 -0.089917 +v 0.086832 -0.404888 -0.089917 +v 0.089917 -0.154888 0.086832 +v 0.089917 -0.404888 0.086832 +v -0.089917 -0.154888 -0.086832 +v -0.089918 0.345112 -0.086832 +v 0.089917 0.345112 0.086832 +v 0.089917 0.095112 0.086832 +v -0.086832 -0.154888 0.089918 +v -0.086832 0.345112 0.089918 +v 0.086832 0.345112 -0.089917 +v 0.086832 0.095112 -0.089917 +v -0.086832 0.095112 0.089918 +v -0.086832 -0.404888 0.089917 +v -0.089917 0.095112 -0.086832 +v -0.089917 -0.404888 -0.086832 +v -0.043416 0.470112 0.044959 +v 0.043416 -0.529888 -0.044959 +v 0.044959 -0.529888 0.043416 +v -0.044959 0.470112 -0.043416 +v 0.000000 -0.467388 0.000000 +v 0.000000 0.032612 0.000000 +v 0.044959 -0.029888 0.043416 +v 0.000000 -0.467388 0.000000 +v 0.000000 0.032612 0.000000 +v 0.043416 -0.029888 -0.044959 +v 0.000000 -0.217388 0.000000 +v 0.000000 0.282612 0.000000 +v 0.000000 -0.217388 0.000000 +v 0.000000 0.282612 0.000000 +v 0.043416 0.220112 -0.044959 +v 0.044959 0.220112 0.043416 +v 0.044959 -0.279888 0.043416 +v 0.043416 -0.279888 -0.044959 +v 0.000000 -0.342388 0.000000 +v 0.000000 0.157612 0.000000 +v 0.000000 -0.342388 0.000000 +v 0.000000 0.157612 0.000000 +v 0.043416 0.470112 -0.044959 +v -0.043416 -0.529888 0.044959 +v -0.044959 -0.529888 -0.043416 +v 0.044959 0.470112 0.043416 +v 0.000000 -0.092388 0.000000 +v 0.000000 0.407612 0.000000 +v -0.044959 -0.029888 -0.043416 +v 0.000000 -0.092388 0.000000 +v 0.000000 0.407612 0.000000 +v -0.043416 -0.029888 0.044959 +v -0.043416 0.220112 0.044959 +v -0.043416 -0.279888 0.044959 +v -0.044959 0.220112 -0.043416 +v -0.044959 -0.279888 -0.043416 +v 0.086832 -0.217388 -0.089917 +v 0.086832 -0.092388 -0.089917 +v 0.043416 -0.154888 -0.044959 +v 0.086832 -0.467388 -0.089917 +v 0.086832 -0.342388 -0.089917 +v 0.043416 -0.404888 -0.044959 +v 0.089917 -0.217388 0.086832 +v 0.089917 -0.092388 0.086832 +v 0.044959 -0.154888 0.043416 +v 0.089917 -0.467388 0.086832 +v 0.089917 -0.342388 0.086832 +v 0.044959 -0.404888 0.043416 +v -0.089917 -0.217388 -0.086832 +v -0.089917 -0.092388 -0.086832 +v -0.044959 -0.154888 -0.043416 +v -0.089918 0.282612 -0.086832 +v -0.089918 0.407612 -0.086832 +v -0.044959 0.345112 -0.043416 +v 0.089917 0.282612 0.086832 +v 0.089917 0.407612 0.086832 +v 0.044959 0.345112 0.043416 +v 0.089917 0.032612 0.086832 +v 0.089917 0.157612 0.086832 +v 0.044959 0.095112 0.043416 +v -0.086832 -0.217388 0.089917 +v -0.086832 -0.092388 0.089918 +v -0.043416 -0.154888 0.044959 +v -0.086832 0.282612 0.089918 +v -0.086832 0.407612 0.089918 +v -0.043416 0.345112 0.044959 +v 0.086832 0.282612 -0.089917 +v 0.086832 0.407612 -0.089917 +v 0.043416 0.345112 -0.044959 +v 0.086832 0.032612 -0.089917 +v 0.086832 0.157612 -0.089917 +v 0.043416 0.095112 -0.044959 +v -0.086832 0.032612 0.089918 +v -0.086832 0.157612 0.089918 +v -0.043416 0.095112 0.044959 +v -0.086832 -0.467388 0.089917 +v -0.086832 -0.342388 0.089917 +v -0.043416 -0.404888 0.044959 +v -0.089917 0.032612 -0.086832 +v -0.089917 0.157612 -0.086832 +v -0.044959 0.095112 -0.043416 +v -0.089917 -0.467388 -0.086832 +v -0.089917 -0.342388 -0.086832 +v -0.044959 -0.404888 -0.043416 +v -0.044959 -0.342388 -0.043416 +v -0.044959 0.157612 -0.043416 +v -0.043416 -0.342388 0.044959 +v -0.043416 0.157612 0.044959 +v 0.043416 0.157612 -0.044959 +v 0.043416 0.032612 -0.044959 +v 0.043416 0.407612 -0.044959 +v 0.043416 0.282612 -0.044959 +v -0.043416 0.407612 0.044959 +v -0.043416 -0.092388 0.044959 +v 0.044959 0.157612 0.043416 +v 0.044959 0.032612 0.043416 +v 0.044959 0.407612 0.043416 +v 0.044959 0.282612 0.043416 +v -0.044959 0.407612 -0.043416 +v -0.044959 -0.092388 -0.043416 +v 0.044959 -0.342388 0.043416 +v 0.044959 -0.467388 0.043416 +v 0.044959 -0.092388 0.043416 +v 0.044959 -0.217388 0.043416 +v 0.043416 -0.342388 -0.044959 +v 0.043416 -0.467388 -0.044959 +v 0.043416 -0.092388 -0.044959 +v 0.043416 -0.217388 -0.044959 +v -0.044959 -0.217388 -0.043416 +v -0.044959 0.282612 -0.043416 +v -0.043416 -0.217388 0.044959 +v -0.043416 0.282612 0.044959 +v -0.043416 0.032612 0.044959 +v -0.043416 -0.467388 0.044959 +v -0.044959 0.032612 -0.043416 +v -0.044959 -0.467388 -0.043416 +vt 0.218362 0.406348 +vt 0.250401 0.406348 +vt 0.250401 0.376797 +vt 0.218362 0.376797 +vt 0.218362 0.657596 +vt 0.250401 0.657596 +vt 0.250401 0.626276 +vt 0.218362 0.626276 +vt 0.218362 0.406348 +vt 0.250401 0.406348 +vt 0.250401 0.376797 +vt 0.218362 0.376797 +vt 0.218362 0.657596 +vt 0.250401 0.657596 +vt 0.250401 0.626276 +vt 0.218362 0.626276 +vt 0.218362 0.784719 +vt 0.250401 0.784719 +vt 0.250401 0.751554 +vt 0.218362 0.751554 +vt 0.218362 0.532933 +vt 0.250401 0.532933 +vt 0.250401 0.502229 +vt 0.218362 0.502229 +vt 0.218362 0.784719 +vt 0.250401 0.784719 +vt 0.250401 0.751554 +vt 0.218362 0.751554 +vt 0.218362 0.532933 +vt 0.250401 0.532933 +vt 0.250401 0.502229 +vt 0.218362 0.502229 +vt 0.282961 0.532934 +vt 0.315521 0.532934 +vt 0.315521 0.502229 +vt 0.282961 0.502229 +vt 0.282961 0.594957 +vt 0.315521 0.594957 +vt 0.315521 0.563638 +vt 0.282961 0.563638 +vt 0.282961 0.406348 +vt 0.315521 0.406348 +vt 0.315521 0.376797 +vt 0.282961 0.376797 +vt 0.282961 0.469065 +vt 0.315521 0.469065 +vt 0.315521 0.435900 +vt 0.282961 0.435900 +vt 0.282961 0.532934 +vt 0.315521 0.532934 +vt 0.315521 0.502229 +vt 0.282961 0.502229 +vt 0.282961 0.594957 +vt 0.315521 0.594957 +vt 0.315521 0.563638 +vt 0.282961 0.563638 +vt 0.282961 0.406348 +vt 0.315521 0.406348 +vt 0.315521 0.376797 +vt 0.282961 0.376797 +vt 0.282961 0.469065 +vt 0.315521 0.469065 +vt 0.315521 0.435900 +vt 0.282961 0.435900 +vt 0.218362 0.594957 +vt 0.250401 0.594957 +vt 0.250401 0.563638 +vt 0.218362 0.563638 +vt 0.466901 0.935330 +vt 0.498940 0.935330 +vt 0.498940 0.875712 +vt 0.466901 0.875712 +vt 0.282961 0.784719 +vt 0.315521 0.784719 +vt 0.315521 0.751554 +vt 0.282961 0.751554 +vt 0.531500 0.935330 +vt 0.564060 0.935330 +vt 0.564060 0.875712 +vt 0.531500 0.875712 +vt 0.282961 0.657596 +vt 0.315521 0.657596 +vt 0.315521 0.626276 +vt 0.282961 0.626276 +vt 0.282961 0.720234 +vt 0.315521 0.720234 +vt 0.315521 0.688915 +vt 0.282961 0.688915 +vt 0.218362 0.594957 +vt 0.250401 0.594957 +vt 0.250401 0.563638 +vt 0.218362 0.563638 +vt 0.466901 0.935330 +vt 0.498940 0.935330 +vt 0.498940 0.875712 +vt 0.466901 0.875712 +vt 0.282961 0.784719 +vt 0.315521 0.784719 +vt 0.315521 0.751554 +vt 0.282961 0.751554 +vt 0.531500 0.935330 +vt 0.564060 0.935330 +vt 0.564060 0.875712 +vt 0.531500 0.875712 +vt 0.282961 0.657596 +vt 0.315521 0.657596 +vt 0.315521 0.626276 +vt 0.282961 0.626276 +vt 0.282961 0.720234 +vt 0.315521 0.720234 +vt 0.315521 0.688915 +vt 0.282961 0.688915 +vt 0.218362 0.720234 +vt 0.250401 0.720234 +vt 0.250401 0.688915 +vt 0.218362 0.688915 +vt 0.218362 0.469064 +vt 0.250401 0.469064 +vt 0.250401 0.435900 +vt 0.218362 0.435900 +vt 0.218362 0.720234 +vt 0.250401 0.720234 +vt 0.250401 0.688915 +vt 0.218362 0.688915 +vt 0.218362 0.469064 +vt 0.250401 0.469064 +vt 0.250401 0.435900 +vt 0.218362 0.435900 +vt 0.186322 0.469064 +vt 0.186322 0.435900 +vt 0.186322 0.502229 +vt 0.186322 0.720234 +vt 0.186322 0.688915 +vt 0.186322 0.751554 +vt 0.186322 0.469064 +vt 0.186322 0.435900 +vt 0.186322 0.502229 +vt 0.186322 0.720234 +vt 0.186322 0.688915 +vt 0.186322 0.751554 +vt 0.498940 0.998640 +vt 0.531500 0.998640 +vt 0.564060 0.998640 +vt 0.250401 0.817883 +vt 0.282961 0.817883 +vt 0.315521 0.817883 +vt 0.434861 0.935330 +vt 0.434861 0.875712 +vt 0.434861 0.998640 +vt 0.466901 0.998640 +vt 0.186322 0.594957 +vt 0.186322 0.563638 +vt 0.186322 0.626276 +vt 0.498940 0.998640 +vt 0.531500 0.998640 +vt 0.564060 0.998640 +vt 0.250401 0.817883 +vt 0.282961 0.817883 +vt 0.315521 0.817883 +vt 0.434861 0.935330 +vt 0.434861 0.875712 +vt 0.434861 0.998640 +vt 0.466901 0.998640 +vt 0.186322 0.594957 +vt 0.186322 0.563638 +vt 0.186322 0.626276 +vt 0.186322 0.532933 +vt 0.186322 0.784719 +vt 0.186322 0.817883 +vt 0.218362 0.817883 +vt 0.186322 0.532933 +vt 0.186322 0.784719 +vt 0.186322 0.817883 +vt 0.218362 0.817883 +vt 0.186322 0.657596 +vt 0.186322 0.406348 +vt 0.186322 0.376797 +vt 0.186322 0.657596 +vt 0.186322 0.406348 +vt 0.186322 0.376797 +vn 0.6947 0.0000 -0.7193 +vn -0.7193 0.0000 -0.6947 +usemtl mcl_flowers_tallgrass.png +s 1 +f 170/1/1 59/2/1 3/3/1 79/4/1 +f 169/5/1 60/6/1 5/7/1 83/8/1 +f 168/9/2 62/10/2 2/11/2 78/12/2 +f 167/13/2 63/14/2 6/15/2 86/16/2 +f 166/17/2 68/18/2 10/19/2 87/20/2 +f 165/21/2 67/22/2 9/23/2 88/24/2 +f 164/25/1 66/26/1 8/27/1 89/28/1 +f 163/29/1 65/30/1 7/31/1 90/32/1 +f 162/33/2 91/34/2 38/35/2 72/36/2 +f 161/37/2 92/38/2 39/39/2 93/40/2 +f 160/41/2 94/42/2 12/43/2 56/44/2 +f 159/45/2 95/46/2 40/47/2 96/48/2 +f 158/49/1 97/50/1 37/51/1 71/52/1 +f 157/53/1 98/54/1 41/55/1 99/56/1 +f 156/57/1 100/58/1 13/59/1 57/60/1 +f 155/61/1 101/62/1 42/63/1 102/64/1 +f 154/65/1 81/66/1 25/67/1 105/68/1 +f 153/69/1 82/70/1 26/71/1 108/72/1 +f 152/73/1 109/74/1 34/75/1 70/76/1 +f 151/77/1 110/78/1 45/79/1 111/80/1 +f 150/81/1 112/82/1 17/83/1 61/84/1 +f 149/85/1 113/86/1 46/87/1 114/88/1 +f 148/89/2 84/90/2 28/91/2 117/92/2 +f 147/93/2 85/94/2 29/95/2 120/96/2 +f 146/97/2 121/98/2 31/99/2 69/100/2 +f 145/101/2 122/102/2 49/103/2 123/104/2 +f 144/105/2 124/106/2 20/107/2 64/108/2 +f 143/109/2 125/110/2 50/111/2 126/112/2 +f 142/113/2 76/114/2 19/115/2 129/116/2 +f 141/117/2 75/118/2 18/119/2 132/120/2 +f 140/121/1 74/122/1 16/123/1 135/124/1 +f 139/125/1 73/126/1 15/127/1 138/128/1 +f 137/129/1 139/125/1 138/128/1 54/130/1 +f 36/131/1 90/32/1 139/125/1 137/129/1 +f 90/32/1 7/31/1 73/126/1 139/125/1 +f 134/132/1 140/121/1 135/124/1 53/133/1 +f 35/134/1 89/28/1 140/121/1 134/132/1 +f 89/28/1 8/27/1 74/122/1 140/121/1 +f 131/135/2 141/117/2 132/120/2 52/136/2 +f 33/137/2 88/24/2 141/117/2 131/135/2 +f 88/24/2 9/23/2 75/118/2 141/117/2 +f 128/138/2 142/113/2 129/116/2 51/139/2 +f 32/140/2 87/20/2 142/113/2 128/138/2 +f 87/20/2 10/19/2 76/114/2 142/113/2 +f 76/114/2 143/109/2 126/112/2 19/115/2 +f 10/19/2 69/100/2 143/109/2 76/114/2 +f 69/100/2 31/99/2 125/110/2 143/109/2 +f 63/14/2 144/105/2 64/108/2 6/15/2 +f 19/115/2 126/112/2 144/105/2 63/14/2 +f 126/112/2 50/111/2 124/106/2 144/105/2 +f 85/94/2 145/101/2 123/104/2 29/95/2 +f 1/141/2 77/142/2 145/101/2 85/94/2 +f 77/142/2 21/143/2 122/102/2 145/101/2 +f 68/18/2 146/97/2 69/100/2 10/19/2 +f 29/144/2 123/145/2 146/97/2 68/18/2 +f 123/145/2 49/146/2 121/98/2 146/97/2 +f 119/147/2 147/93/2 120/96/2 48/148/2 +f 11/149/2 55/150/2 147/93/2 119/147/2 +f 55/150/2 1/141/2 85/94/2 147/93/2 +f 116/151/2 148/89/2 117/92/2 47/152/2 +f 30/153/2 86/16/2 148/89/2 116/151/2 +f 86/16/2 6/15/2 84/90/2 148/89/2 +f 74/122/1 149/85/1 114/88/1 16/123/1 +f 8/27/1 70/76/1 149/85/1 74/122/1 +f 70/76/1 34/75/1 113/86/1 149/85/1 +f 60/6/1 150/81/1 61/84/1 5/7/1 +f 16/123/1 114/88/1 150/81/1 60/6/1 +f 114/88/1 46/87/1 112/82/1 150/81/1 +f 82/70/1 151/77/1 111/80/1 26/71/1 +f 4/154/1 80/155/1 151/77/1 82/70/1 +f 80/155/1 24/156/1 110/78/1 151/77/1 +f 66/26/1 152/73/1 70/76/1 8/27/1 +f 26/157/1 111/158/1 152/73/1 66/26/1 +f 111/158/1 45/159/1 109/74/1 152/73/1 +f 107/160/1 153/69/1 108/72/1 44/161/1 +f 14/162/1 58/163/1 153/69/1 107/160/1 +f 58/163/1 4/154/1 82/70/1 153/69/1 +f 104/164/1 154/65/1 105/68/1 43/165/1 +f 27/166/1 83/8/1 154/65/1 104/164/1 +f 83/8/1 5/7/1 81/66/1 154/65/1 +f 73/126/1 155/61/1 102/64/1 15/127/1 +f 7/31/1 71/52/1 155/61/1 73/126/1 +f 71/52/1 37/51/1 101/62/1 155/61/1 +f 59/2/1 156/57/1 57/60/1 3/3/1 +f 15/127/1 102/64/1 156/57/1 59/2/1 +f 102/64/1 42/63/1 100/58/1 156/57/1 +f 81/66/1 157/53/1 99/56/1 25/67/1 +f 5/7/1 61/84/1 157/53/1 81/66/1 +f 61/84/1 17/83/1 98/54/1 157/53/1 +f 65/30/1 158/49/1 71/52/1 7/31/1 +f 25/67/1 99/56/1 158/49/1 65/30/1 +f 99/56/1 41/55/1 97/50/1 158/49/1 +f 75/118/2 159/45/2 96/48/2 18/119/2 +f 9/23/2 72/36/2 159/45/2 75/118/2 +f 72/36/2 38/35/2 95/46/2 159/45/2 +f 62/10/2 160/41/2 56/44/2 2/11/2 +f 18/119/2 96/48/2 160/41/2 62/10/2 +f 96/48/2 40/47/2 94/42/2 160/41/2 +f 84/90/2 161/37/2 93/40/2 28/91/2 +f 6/15/2 64/108/2 161/37/2 84/90/2 +f 64/108/2 20/107/2 92/38/2 161/37/2 +f 67/22/2 162/33/2 72/36/2 9/23/2 +f 28/91/2 93/40/2 162/33/2 67/22/2 +f 93/40/2 39/39/2 91/34/2 162/33/2 +f 103/167/1 163/29/1 90/32/1 36/131/1 +f 43/165/1 105/68/1 163/29/1 103/167/1 +f 105/68/1 25/67/1 65/30/1 163/29/1 +f 106/168/1 164/25/1 89/28/1 35/134/1 +f 44/169/1 108/170/1 164/25/1 106/168/1 +f 108/170/1 26/157/1 66/26/1 164/25/1 +f 115/171/2 165/21/2 88/24/2 33/137/2 +f 47/152/2 117/92/2 165/21/2 115/171/2 +f 117/92/2 28/91/2 67/22/2 165/21/2 +f 118/172/2 166/17/2 87/20/2 32/140/2 +f 48/173/2 120/174/2 166/17/2 118/172/2 +f 120/174/2 29/144/2 68/18/2 166/17/2 +f 127/175/2 167/13/2 86/16/2 30/153/2 +f 51/139/2 129/116/2 167/13/2 127/175/2 +f 129/116/2 19/115/2 63/14/2 167/13/2 +f 130/176/2 168/9/2 78/12/2 22/177/2 +f 52/136/2 132/120/2 168/9/2 130/176/2 +f 132/120/2 18/119/2 62/10/2 168/9/2 +f 133/178/1 169/5/1 83/8/1 27/166/1 +f 53/133/1 135/124/1 169/5/1 133/178/1 +f 135/124/1 16/123/1 60/6/1 169/5/1 +f 136/179/1 170/1/1 79/4/1 23/180/1 +f 54/130/1 138/128/1 170/1/1 136/179/1 +f 138/128/1 15/127/1 59/2/1 170/1/1 +o plant_test +v -0.000842 0.420173 0.000152 +v -0.000842 0.420173 0.000152 +v 0.190595 0.340629 0.003494 +v 0.002500 0.340629 -0.191284 +v -0.192278 0.340629 -0.003189 +v -0.004183 0.340629 0.191589 +v 0.094876 0.380401 0.001823 +v 0.193936 0.340629 -0.187943 +v 0.187253 0.340629 0.194930 +v 0.000829 0.380401 -0.095566 +v -0.188937 0.340629 -0.194626 +v 0.193936 0.340629 -0.187943 +v -0.096560 0.380401 -0.001519 +v -0.195620 0.340629 0.188247 +v -0.188937 0.340629 -0.194626 +v -0.002513 0.380401 0.095870 +v 0.187253 0.340629 0.194930 +v -0.195620 0.340629 0.188247 +v 0.188924 0.380401 0.099212 +v -0.099901 0.380401 0.189918 +v -0.190607 0.380401 -0.098907 +v 0.098218 0.380401 -0.189613 +v 0.091535 0.380401 0.193259 +v 0.192265 0.380401 -0.092225 +v -0.093219 0.380401 -0.192955 +v -0.193949 0.380401 0.092529 +vt 0.373047 0.821932 +vt 0.500000 0.821932 +vt 0.500000 0.691073 +vt 0.373047 0.691073 +vt 0.312500 0.821932 +vt 0.500000 0.821932 +vt 0.500000 0.691073 +vt 0.312500 0.691073 +vt 0.312500 0.821932 +vt 0.500000 0.821932 +vt 0.500000 0.691073 +vt 0.312500 0.691073 +vt 0.312500 0.821932 +vt 0.500000 0.821932 +vt 0.500000 0.691073 +vt 0.312500 0.691073 +vt 0.701172 0.821932 +vt 0.701172 0.691073 +vt 0.623047 0.821932 +vt 0.623047 0.691073 +vt 0.623047 0.821932 +vt 0.623047 0.691073 +vt 0.623047 0.821932 +vt 0.623047 0.691073 +vn 0.0067 -0.9235 -0.3836 +vn 0.3836 -0.9235 0.0067 +vn -0.0067 -0.9235 0.3836 +vn -0.3836 -0.9235 -0.0067 +usemtl mcl_ocean_bubble_coral_fan.png +s 1 +f 187/181/3 176/182/3 186/183/3 189/184/3 +f 184/185/4 175/186/4 183/187/4 190/188/4 +f 181/189/5 174/190/5 180/191/5 191/192/5 +f 178/193/6 173/194/6 177/195/6 192/196/6 +f 173/194/6 179/197/6 193/198/6 177/195/6 +f 174/190/5 182/199/5 194/200/5 180/191/5 +f 175/186/4 185/201/4 195/202/4 183/187/4 +f 176/182/3 188/203/3 196/204/3 186/183/3 +l 177 171 +l 180 172 +l 183 171 +l 186 172 +o Cube +v -0.093808 0.196026 0.093233 +v -0.093808 0.390929 0.093233 +v -0.093808 0.196026 -0.093233 +v -0.093808 0.390929 -0.093233 +v 0.093808 0.196026 0.093233 +v 0.093808 0.390929 0.093233 +v 0.093808 0.196026 -0.093233 +v 0.093808 0.390929 -0.093233 +v -0.093808 0.196026 0.000000 +v -0.093808 0.290470 0.093233 +v -0.093808 0.390929 0.000000 +v -0.093808 0.290470 -0.093233 +v -0.000000 0.196026 -0.093233 +v -0.000000 0.390929 -0.093233 +v 0.093808 0.290470 -0.093233 +v 0.093808 0.196026 0.000000 +v 0.093808 0.390929 0.000000 +v 0.093808 0.290470 0.093233 +v -0.000000 0.196026 0.093233 +v -0.000000 0.390929 0.093233 +v -0.000000 0.390929 0.000000 +v -0.000000 0.196026 0.000000 +v -0.000000 0.290470 0.093233 +v 0.093808 0.290470 0.000000 +v -0.000000 0.290470 -0.093233 +v -0.093808 0.290470 0.000000 +v -0.093808 0.196026 0.092775 +v -0.093808 0.290971 0.093233 +v -0.093808 0.390929 -0.092775 +v -0.093808 0.197014 -0.093233 +v -0.092974 0.196026 -0.093233 +v 0.092974 0.390929 -0.093233 +v 0.093808 0.197014 -0.093233 +v 0.093808 0.196026 -0.092775 +v 0.093808 0.390929 0.092775 +v 0.093808 0.197014 0.093233 +v 0.092974 0.196026 0.093233 +v -0.092974 0.390929 0.093233 +v -0.093808 0.196026 -0.092775 +v -0.093808 0.197014 0.093233 +v -0.093808 0.390929 0.092775 +v -0.093808 0.290971 -0.093233 +v 0.092974 0.196026 -0.093233 +v -0.092974 0.390929 -0.093233 +v 0.093808 0.290971 -0.093233 +v 0.093808 0.196026 0.092775 +v 0.093808 0.390929 -0.092775 +v 0.093808 0.290971 0.093233 +v -0.092974 0.196026 0.093233 +v 0.092974 0.390929 0.093233 +v -0.000000 0.390929 0.092775 +v -0.000000 0.390929 -0.092775 +v 0.092974 0.390929 0.000000 +v -0.092974 0.390929 0.000000 +v -0.000000 0.196026 0.092775 +v -0.000000 0.196026 -0.092775 +v -0.092974 0.196026 0.000000 +v 0.092974 0.196026 0.000000 +v -0.092974 0.290470 0.093233 +v 0.092974 0.290470 0.093233 +v -0.000000 0.197014 0.093233 +v -0.000000 0.290971 0.093233 +v 0.093808 0.290470 0.092775 +v 0.093808 0.290470 -0.092775 +v 0.093808 0.197014 0.000000 +v 0.093808 0.290971 0.000000 +v 0.092974 0.290470 -0.093233 +v -0.092974 0.290470 -0.093233 +v -0.000000 0.197014 -0.093233 +v -0.000000 0.290971 -0.093233 +v -0.093808 0.290470 -0.092775 +v -0.093808 0.290470 0.092775 +v -0.093808 0.197014 0.000000 +v -0.093808 0.290971 0.000000 +v -0.093808 0.290971 0.092775 +v -0.093808 0.197014 0.092775 +v -0.093808 0.197014 -0.092775 +v -0.092974 0.290971 -0.093233 +v -0.092974 0.197014 -0.093233 +v 0.092974 0.197014 -0.093233 +v 0.093808 0.290971 -0.092775 +v 0.093808 0.197014 -0.092775 +v 0.093808 0.197014 0.092775 +v 0.092974 0.290971 0.093233 +v 0.092974 0.197014 0.093233 +v -0.092974 0.197014 0.093233 +v 0.092974 0.196026 -0.092775 +v -0.092974 0.196026 -0.092775 +v -0.092974 0.196026 0.092775 +v -0.092974 0.390929 -0.092775 +v 0.092974 0.390929 -0.092775 +v 0.092974 0.390929 0.092775 +v -0.092974 0.390929 0.092775 +v 0.092974 0.196026 0.092775 +v -0.092974 0.290971 0.093233 +v 0.093808 0.290971 0.092775 +v 0.092974 0.290971 -0.093233 +v -0.093808 0.290971 -0.092775 +vt 0.502042 0.373047 +vt 0.564542 0.373047 +vt 0.564542 0.435547 +vt 0.502042 0.435547 +vt 0.502042 0.437500 +vt 0.564542 0.437500 +vt 0.564542 0.500000 +vt 0.502042 0.500000 +vt 0.502042 0.687500 +vt 0.564542 0.687500 +vt 0.564542 0.750000 +vt 0.502042 0.750000 +vt 0.066619 0.765683 +vt 0.129119 0.765683 +vt 0.129119 0.879860 +vt 0.066619 0.879860 +vt 0.436154 0.687500 +vt 0.436520 0.687500 +vt 0.436520 0.750000 +vt 0.436154 0.750000 +vt 0.000020 0.937269 +vt 0.124039 0.937269 +vt 0.124039 0.999769 +vt 0.000020 0.999769 +vt 0.000020 0.937269 +vt 0.124039 0.937269 +vt 0.124039 0.999769 +vt 0.000020 0.999769 +vt 0.000957 0.875000 +vt 0.124977 0.875000 +vt 0.124977 0.937500 +vt 0.000957 0.937500 +vt 0.000020 0.812269 +vt 0.124039 0.812269 +vt 0.124039 0.874769 +vt 0.000020 0.874769 +vt 0.000596 0.374981 +vt 0.124500 0.374981 +vt 0.124500 0.437481 +vt 0.000596 0.437481 +vt 0.000577 0.250031 +vt 0.126692 0.250031 +vt 0.126692 0.376511 +vt 0.000577 0.376511 +vt 0.436154 0.562500 +vt 0.436520 0.562500 +vt 0.436520 0.625000 +vt 0.436154 0.625000 +vt 0.063596 0.765683 +vt 0.064577 0.765683 +vt 0.064577 0.879860 +vt 0.063596 0.879860 +vt 0.065922 0.760824 +vt 0.066902 0.760824 +vt 0.066902 0.823324 +vt 0.065922 0.823324 +vt 0.066496 0.688477 +vt 0.128996 0.688477 +vt 0.128996 0.815430 +vt 0.066496 0.815430 +vt 0.499020 0.687500 +vt 0.500000 0.687500 +vt 0.500000 0.750000 +vt 0.499020 0.750000 +vt 0.065922 0.687500 +vt 0.066902 0.687500 +vt 0.066902 0.750000 +vt 0.065922 0.750000 +vt 0.064542 0.687500 +vt 0.127042 0.687500 +vt 0.127042 0.812500 +vt 0.064542 0.812500 +vt 0.499020 0.437500 +vt 0.500000 0.437500 +vt 0.500000 0.500000 +vt 0.499020 0.500000 +vt 0.065426 0.740234 +vt 0.066406 0.740234 +vt 0.066406 0.802734 +vt 0.065426 0.802734 +vt 0.066496 0.689453 +vt 0.128996 0.689453 +vt 0.128996 0.814453 +vt 0.066496 0.814453 +vt 0.499020 0.373047 +vt 0.500000 0.373047 +vt 0.500000 0.435547 +vt 0.499020 0.435547 +vt 0.065922 0.690000 +vt 0.066902 0.690000 +vt 0.066902 0.752500 +vt 0.065922 0.752500 +vt 0.064542 0.690000 +vt 0.127042 0.690000 +vt 0.127042 0.815000 +vt 0.064542 0.815000 +vt 0.068945 0.690000 +vt 0.068945 0.752500 +vt 0.500000 0.308594 +vt 0.502042 0.308594 +vt 0.502042 0.371094 +vt 0.500000 0.371094 +vt 0.564542 0.308594 +vt 0.564542 0.371094 +vt -0.000980 0.690000 +vt 0.061520 0.690000 +vt 0.061520 0.815000 +vt -0.000980 0.815000 +vt 0.436520 0.308594 +vt 0.499020 0.308594 +vt 0.499020 0.371094 +vt 0.436520 0.371094 +vt 0.436520 0.373047 +vt 0.436520 0.435547 +vt 0.061520 0.877500 +vt -0.000980 0.877500 +vt 0.066902 0.815000 +vt 0.065922 0.815000 +vt 0.068449 0.740234 +vt 0.068449 0.802734 +vt 0.502042 0.312500 +vt 0.500000 0.312500 +vt 0.502042 0.689453 +vt 0.564542 0.689453 +vt 0.564542 0.751953 +vt 0.502042 0.751953 +vt 0.000973 0.689453 +vt 0.063473 0.689453 +vt 0.063473 0.814453 +vt 0.000973 0.814453 +vt 0.436520 0.689453 +vt 0.499020 0.689453 +vt 0.499020 0.751953 +vt 0.436520 0.751953 +vt 0.499020 0.312500 +vt 0.436520 0.437500 +vt 0.436520 0.500000 +vt 0.063473 0.876953 +vt 0.000973 0.876953 +vt 0.066406 0.865234 +vt 0.065426 0.865234 +vt 0.068945 0.687500 +vt 0.068945 0.750000 +vt 0.502042 0.562500 +vt 0.500000 0.562500 +vt 0.564542 0.562500 +vt -0.000980 0.687500 +vt 0.061520 0.687500 +vt 0.061520 0.812500 +vt -0.000980 0.812500 +vt 0.499020 0.562500 +vt 0.061520 0.875000 +vt -0.000980 0.875000 +vt 0.066902 0.812500 +vt 0.065922 0.812500 +vt 0.068945 0.760824 +vt 0.068945 0.823324 +vt 0.502042 0.812500 +vt 0.500000 0.812500 +vt 0.564542 0.812500 +vt 0.000973 0.688477 +vt 0.063473 0.688477 +vt 0.063473 0.815430 +vt 0.000973 0.815430 +vt 0.499020 0.812500 +vt 0.436520 0.812500 +vt 0.001096 0.765683 +vt 0.001096 0.879860 +vt 0.063473 0.879883 +vt 0.000973 0.879883 +vt 0.000577 0.250031 +vt 0.000577 0.376511 +vt 0.499769 0.500000 +vt 0.436154 0.500000 +vt 0.499769 0.562500 +vt 0.124500 0.249981 +vt 0.000596 0.312481 +vt 0.124500 0.312481 +vt 0.499769 0.500000 +vt 0.436154 0.500000 +vt 0.436154 0.562500 +vt 0.499769 0.562500 +vt 0.124500 0.374981 +vt 0.124500 0.437481 +vt 0.126692 0.439011 +vt 0.000577 0.439011 +vt 0.000957 0.875000 +vt 0.000957 0.937500 +vt 0.564430 0.500000 +vt 0.501930 0.500000 +vt 0.501930 0.562500 +vt 0.564430 0.562500 +vt 0.564430 0.500000 +vt 0.564430 0.562500 +vt 0.501930 0.562500 +vt 0.501930 0.625000 +vt 0.564542 0.625000 +vt 0.501930 0.500000 +vt 0.501930 0.687500 +vt 0.501930 0.750000 +vt 0.124977 1.000000 +vt 0.000957 1.000000 +vt 0.000957 1.000000 +vt 0.000596 0.374981 +vt 0.000596 0.437481 +vt 0.000577 0.439011 +vt 0.128996 0.879883 +vt 0.066496 0.879883 +vt 0.068945 0.812500 +vt 0.127042 0.875000 +vt 0.064542 0.875000 +vt 0.068449 0.865234 +vt 0.128996 0.876953 +vt 0.066496 0.876953 +vt 0.068945 0.815000 +vt 0.127042 0.877500 +vt 0.064542 0.877500 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material +s off +f 294/205/7 225/206/7 200/207/7 238/208/7 +f 293/209/8 228/210/8 204/211/8 241/212/8 +f 292/213/9 231/214/9 202/215/9 244/216/9 +f 291/217/10 234/218/10 198/219/10 224/220/10 +f 290/221/11 242/222/11 201/223/11 233/224/11 +f 289/225/12 237/226/12 198/227/12 234/228/12 +f 288/229/12 247/230/12 216/231/12 246/232/12 +f 287/233/12 248/234/12 217/235/12 249/236/12 +f 286/237/12 225/238/12 207/239/12 250/240/12 +f 285/241/11 251/242/11 215/243/11 245/244/11 +f 284/245/11 252/246/11 218/247/11 253/248/11 +f 283/249/11 230/250/11 212/251/11 254/252/11 +f 282/253/10 255/254/10 206/255/10 236/256/10 +f 281/257/10 256/258/10 219/259/10 257/260/10 +f 280/261/10 246/262/10 216/263/10 258/264/10 +f 279/265/9 259/266/9 214/267/9 232/268/9 +f 278/269/9 260/270/9 220/271/9 261/272/9 +f 277/273/9 243/274/9 213/275/9 262/276/9 +f 276/277/8 263/278/8 211/279/8 229/280/8 +f 275/281/8 264/282/8 221/283/8 265/284/8 +f 274/285/8 240/286/8 210/287/8 266/288/8 +f 273/289/7 267/290/7 208/291/7 226/292/7 +f 272/293/7 268/294/7 222/295/7 269/296/7 +f 271/297/7 237/298/7 207/299/7 270/300/7 +f 268/294/7 271/301/7 270/302/7 222/295/7 +f 206/303/7 224/304/7 271/305/7 268/306/7 +f 224/304/7 198/307/7 237/308/7 271/305/7 +f 223/309/7 272/310/7 269/311/7 205/312/7 +f 197/313/7 236/314/7 272/315/7 223/316/7 +f 236/314/7 206/303/7 268/306/7 272/315/7 +f 235/317/7 273/289/7 226/292/7 199/318/7 +f 205/312/7 269/311/7 273/319/7 235/320/7 +f 269/296/7 222/295/7 267/321/7 273/322/7 +f 264/282/8 274/323/8 266/324/8 221/283/8 +f 208/291/8 238/208/8 274/325/8 264/326/8 +f 238/327/8 200/328/8 240/329/8 274/330/8 +f 227/331/8 275/332/8 265/333/8 209/334/8 +f 199/335/8 226/336/8 275/337/8 227/338/8 +f 226/292/8 208/291/8 264/326/8 275/339/8 +f 239/340/8 276/277/8 229/280/8 203/341/8 +f 209/334/8 265/333/8 276/342/8 239/343/8 +f 265/284/8 221/283/8 263/344/8 276/345/8 +f 260/270/9 277/346/9 262/347/9 220/271/9 +f 211/279/9 241/212/9 277/348/9 260/349/9 +f 241/212/9 204/211/9 243/350/9 277/348/9 +f 230/351/9 278/352/9 261/353/9 212/354/9 +f 203/341/9 229/280/9 278/355/9 230/250/9 +f 229/280/9 211/279/9 260/349/9 278/355/9 +f 242/222/9 279/265/9 232/268/9 201/223/9 +f 212/354/9 261/353/9 279/356/9 242/357/9 +f 261/272/9 220/271/9 259/358/9 279/359/9 +f 256/258/10 280/360/10 258/361/10 219/259/10 +f 214/267/10 244/216/10 280/362/10 256/363/10 +f 244/216/10 202/215/10 246/364/10 280/362/10 +f 233/365/10 281/366/10 257/367/10 215/368/10 +f 201/223/10 232/268/10 281/369/10 233/370/10 +f 232/268/10 214/267/10 256/363/10 281/369/10 +f 245/371/10 282/253/10 236/256/10 197/372/10 +f 215/368/10 257/367/10 282/373/10 245/374/10 +f 257/260/10 219/259/10 255/254/10 282/253/10 +f 252/246/11 283/375/11 254/376/11 218/247/11 +f 209/377/11 239/378/11 283/249/11 252/379/11 +f 239/378/11 203/341/11 230/250/11 283/249/11 +f 235/380/11 284/245/11 253/381/11 205/382/11 +f 199/383/11 227/384/11 284/385/11 235/386/11 +f 227/384/11 209/377/11 252/379/11 284/385/11 +f 223/387/11 285/241/11 245/244/11 197/388/11 +f 205/382/11 253/381/11 285/241/11 223/387/11 +f 253/248/11 218/247/11 251/389/11 285/390/11 +f 248/234/12 286/391/12 250/392/12 217/235/12 +f 210/393/12 240/394/12 286/395/12 248/396/12 +f 240/394/12 200/397/12 225/398/12 286/395/12 +f 243/350/12 287/399/12 249/400/12 213/401/12 +f 204/211/12 228/402/12 287/399/12 243/350/12 +f 228/402/12 210/393/12 248/396/12 287/399/12 +f 231/214/12 288/403/12 246/404/12 202/215/12 +f 213/401/12 249/400/12 288/403/12 231/214/12 +f 249/236/12 217/235/12 247/405/12 288/406/12 +f 247/230/12 289/225/12 234/228/12 216/231/12 +f 217/235/12 250/392/12 289/407/12 247/405/12 +f 250/240/12 207/239/12 237/226/12 289/225/12 +f 251/242/11 290/408/11 233/409/11 215/243/11 +f 218/247/11 254/376/11 290/410/11 251/389/11 +f 254/252/11 212/251/11 242/222/11 290/221/11 +f 255/254/10 291/217/10 224/220/10 206/255/10 +f 219/259/10 258/361/10 291/217/10 255/254/10 +f 258/264/10 216/263/10 234/411/10 291/412/10 +f 259/266/9 292/213/9 244/216/9 214/267/9 +f 220/271/9 262/347/9 292/413/9 259/358/9 +f 262/276/9 213/275/9 231/414/9 292/415/9 +f 263/278/8 293/209/8 241/212/8 211/279/8 +f 221/283/8 266/324/8 293/416/8 263/344/8 +f 266/288/8 210/287/8 228/417/8 293/418/8 +f 267/290/7 294/205/7 238/208/7 208/291/7 +f 222/295/7 270/302/7 294/419/7 267/321/7 +f 270/300/7 207/299/7 225/420/7 294/421/7 diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_bee_nest.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_bee_nest.mts new file mode 100644 index 000000000..630117463 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_bee_nest.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_1.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_1.mts new file mode 100644 index 000000000..68e66e425 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_1.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_2.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_2.mts new file mode 100644 index 000000000..5307d7d32 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_2.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_3.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_3.mts new file mode 100644 index 000000000..96e3f0e66 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_3.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_4.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_4.mts new file mode 100644 index 000000000..46f3e3b59 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_4.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_5.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_5.mts new file mode 100644 index 000000000..35e3ed120 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_5.mts differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_doors_door_mangrove_side_lower.png b/mods/ITEMS/mcl_mangrove/textures/mcl_doors_door_mangrove_side_lower.png new file mode 100644 index 000000000..9a217e1ae Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_doors_door_mangrove_side_lower.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_doors_door_mangrove_side_upper.png b/mods/ITEMS/mcl_mangrove/textures/mcl_doors_door_mangrove_side_upper.png new file mode 100644 index 000000000..2b27f4aeb Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_doors_door_mangrove_side_upper.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_door_bottom.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_door_bottom.png new file mode 100644 index 000000000..91c2df8b8 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_door_bottom.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_door_top.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_door_top.png new file mode 100644 index 000000000..8691b0f93 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_door_top.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_doors.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_doors.png new file mode 100644 index 000000000..1f495d997 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_doors.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_fence.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_fence.png new file mode 100644 index 000000000..47943496f Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_fence.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_fence_gate.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_fence_gate.png new file mode 100644 index 000000000..47943496f Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_fence_gate.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_leaves.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_leaves.png new file mode 100644 index 000000000..cae97fdb4 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_leaves.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_log.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_log.png new file mode 100644 index 000000000..fdbc0e949 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_log.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_log_top.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_log_top.png new file mode 100644 index 000000000..aa8906485 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_log_top.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_planks.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_planks.png new file mode 100644 index 000000000..47943496f Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_planks.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule.png new file mode 100644 index 000000000..f2f67dbdc Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule_hanging.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule_hanging.png new file mode 100644 index 000000000..25c603021 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule_hanging.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule_item.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule_item.png new file mode 100644 index 000000000..a6bb0233c Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_propagule_item.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_roots_side.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_roots_side.png new file mode 100644 index 000000000..f0409f2dc Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_roots_side.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_roots_top.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_roots_top.png new file mode 100644 index 000000000..8ed132253 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_roots_top.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_trapdoor.png b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_trapdoor.png new file mode 100644 index 000000000..ea50c5a5f Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_mangrove_trapdoor.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_stripped_mangrove_log_side.png b/mods/ITEMS/mcl_mangrove/textures/mcl_stripped_mangrove_log_side.png new file mode 100644 index 000000000..cb9ac10ac Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_stripped_mangrove_log_side.png differ diff --git a/mods/ITEMS/mcl_mangrove/textures/mcl_stripped_mangrove_log_top.png b/mods/ITEMS/mcl_mangrove/textures/mcl_stripped_mangrove_log_top.png new file mode 100644 index 000000000..da228d4be Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/textures/mcl_stripped_mangrove_log_top.png differ diff --git a/mods/ITEMS/mcl_maps/init.lua b/mods/ITEMS/mcl_maps/init.lua index 450d8fbad..84f4019ea 100644 --- a/mods/ITEMS/mcl_maps/init.lua +++ b/mods/ITEMS/mcl_maps/init.lua @@ -62,7 +62,7 @@ function mcl_maps.create_map(pos) local emin, emax = vm:read_from_map(minp, maxp) local data = vm:get_data() local param2data = vm:get_param2_data() - local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + local area = VoxelArea:new({ MinEdge = emin, MaxEdge = emax }) local pixels = {} local last_heightmap for x = 1, 128 do @@ -94,7 +94,7 @@ function mcl_maps.create_map(pos) end if def.palette then local palette = palettes[texture] - color = palette and {palette = palette} + color = palette and { palette = palette } else color = texture_colors[texture] end @@ -129,7 +129,7 @@ function mcl_maps.create_map(pos) end heightmap[z] = height or minp.y pixels[z] = pixels[z] or {} - pixels[z][x] = color or {0, 0, 0} + pixels[z][x] = color or { 0, 0, 0 } end last_heightmap = heightmap end @@ -139,29 +139,45 @@ function mcl_maps.create_map(pos) return itemstack end -function mcl_maps.load_map(id) +function mcl_maps.load_map(id, callback) if id == "" or creating_maps[id] then - return + return false end local texture = "mcl_maps_map_texture_" .. id .. ".tga" + local result = true + if not loaded_maps[id] then if not minetest.features.dynamic_add_media_table then -- minetest.dynamic_add_media() blocks in -- Minetest 5.3 and 5.4 until media loads loaded_maps[id] = true - dynamic_add_media(map_textures_path .. texture, function() end) + result = dynamic_add_media(map_textures_path .. texture, function() + end) + if callback then + callback(texture) + end else -- minetest.dynamic_add_media() never blocks -- in Minetest 5.5, callback runs after load - dynamic_add_media(map_textures_path .. texture, function() + result = dynamic_add_media(map_textures_path .. texture, function() loaded_maps[id] = true + if callback then + callback(texture) + end end) end end + if result == false then + return false + end + if loaded_maps[id] then + if callback then + callback(texture) + end return texture end end @@ -210,7 +226,7 @@ local filled_def = { _doc_items_usagehelp = S("Hold the map in your hand. This will display a map on your screen."), inventory_image = "mcl_maps_map_filled.png^(mcl_maps_map_filled_markings.png^[colorize:#000000)", stack_max = 64, - groups = {not_in_creative_inventory = 1, filled_map = 1, tool = 1}, + groups = { not_in_creative_inventory = 1, filled_map = 1, tool = 1 }, } minetest.register_craftitem("mcl_maps:filled_map", filled_def) @@ -218,24 +234,39 @@ minetest.register_craftitem("mcl_maps:filled_map", filled_def) local filled_wield_def = table.copy(filled_def) filled_wield_def.use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false filled_wield_def.visual_scale = 1 -filled_wield_def.wield_scale = {x = 1, y = 1, z = 1} +filled_wield_def.wield_scale = { x = 1, y = 1, z = 1 } filled_wield_def.paramtype = "light" filled_wield_def.drawtype = "mesh" filled_wield_def.node_placement_prediction = "" filled_wield_def.range = minetest.registered_items[""].range filled_wield_def.on_place = mcl_util.call_on_rightclick +filled_wield_def._mcl_wieldview_item = "mcl_maps:filled_map" -for _, texture in pairs(mcl_skins.list) do - local def = table.copy(filled_wield_def) - def.tiles = {texture .. ".png"} - def.mesh = "mcl_meshhand.b3d" - def._mcl_hand_id = texture - minetest.register_node("mcl_maps:filled_map_" .. texture, def) +local mcl_skins_enabled = minetest.global_exists("mcl_skins") - local female_def = table.copy(def) - female_def.mesh = "mcl_meshhand_female.b3d" - female_def._mcl_hand_id = texture .. "_female" - minetest.register_node("mcl_maps:filled_map_" .. texture .. "_female", female_def) +if mcl_skins_enabled then + -- Generate a node for every skin + local list = mcl_skins.get_skin_list() + for _, skin in pairs(list) do + if skin.slim_arms then + local female = table.copy(filled_wield_def) + female._mcl_hand_id = skin.id + female.mesh = "mcl_meshhand_female.b3d" + female.tiles = { skin.texture } + minetest.register_node("mcl_maps:filled_map_" .. skin.id, female) + else + local male = table.copy(filled_wield_def) + male._mcl_hand_id = skin.id + male.mesh = "mcl_meshhand.b3d" + male.tiles = { skin.texture } + minetest.register_node("mcl_maps:filled_map_" .. skin.id, male) + end + end +else + filled_wield_def._mcl_hand_id = "hand" + filled_wield_def.mesh = "mcl_meshhand.b3d" + filled_wield_def.tiles = { "character.png" } + minetest.register_node("mcl_maps:filled_map_hand", filled_wield_def) end local old_add_item = minetest.add_item @@ -268,7 +299,7 @@ minetest.register_craft({ minetest.register_craft({ type = "shapeless", output = "mcl_maps:filled_map 2", - recipe = {"group:filled_map", "mcl_maps:empty_map"}, + recipe = { "group:filled_map", "mcl_maps:empty_map" }, }) local function on_craft(itemstack, player, old_craft_grid, craft_inv) @@ -292,13 +323,13 @@ minetest.register_on_joinplayer(function(player) local map_def = { hud_elem_type = "image", text = "blank.png", - position = {x = 0.75, y = 0.8}, - alignment = {x = 0, y = -1}, - offset = {x = 0, y = 0}, - scale = {x = 2, y = 2}, + position = { x = 0.75, y = 0.8 }, + alignment = { x = 0, y = -1 }, + offset = { x = 0, y = 0 }, + scale = { x = 2, y = 2 }, } local marker_def = table.copy(map_def) - marker_def.alignment = {x = 0, y = 0} + marker_def.alignment = { x = 0, y = 0 } huds[player] = { map = player:hud_add(map_def), marker = player:hud_add(marker_def), @@ -358,7 +389,7 @@ minetest.register_globalstep(function(dtime) end player:hud_change(hud.marker, "text", marker) - player:hud_change(hud.marker, "offset", {x = (6 - 140 / 2 + pos.x - minp.x) * 2, y = (6 - 140 + maxp.z - pos.z) * 2}) + player:hud_change(hud.marker, "offset", { x = (6 - 140 / 2 + pos.x - minp.x) * 2, y = (6 - 140 + maxp.z - pos.z) * 2 }) elseif maps[player] then player:hud_change(hud.map, "text", "blank.png") player:hud_change(hud.marker, "text", "blank.png") diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.ja.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.ja.tr new file mode 100644 index 000000000..a521f3eba --- /dev/null +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_maps +Empty Map=白紙の地図 +Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=白紙の地図は地図として使えませんが、スタックしたり、使える地図に変えられます。 +Rightclick to create a filled map (which can't be stacked anymore).=右クリックで塗りつぶしたマップを作成します(スタックはできなくなります)。 +Map=地図 +Shows a map image.=地図画像を表示します。 +When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=作成すると、その付近の地図が画像として保存され、地図をかざすといつでも見ることができます。 +Hold the map in your hand. This will display a map on your screen.=地図を手に持ってください。これで画面に地図が表示されます。 diff --git a/mods/ITEMS/mcl_mobitems/init.lua b/mods/ITEMS/mcl_mobitems/init.lua index 6b3c9bec4..357762645 100644 --- a/mods/ITEMS/mcl_mobitems/init.lua +++ b/mods/ITEMS/mcl_mobitems/init.lua @@ -181,6 +181,14 @@ minetest.register_craftitem("mcl_mobitems:bone", { _mcl_toollike_wield = true, }) +minetest.register_craftitem("mcl_mobitems:ink_sac", { + description = S("Squid Ink Sac"), + _doc_items_longdesc = S("This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye."), + inventory_image = "mcl_mobitems_ink_sac.png", + stack_max = 64, + groups = { craftitem = 1 }, +}) + minetest.register_craftitem("mcl_mobitems:string",{ description = S("String"), _doc_items_longdesc = S("Strings are used in crafting."), @@ -321,12 +329,41 @@ minetest.register_tool("mcl_mobitems:carrot_on_a_stick", { _tt_help = S("Lets you ride a saddled pig"), _doc_items_longdesc = S("A carrot on a stick can be used on saddled pigs to ride them."), _doc_items_usagehelp = S("Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick."), - wield_image = "mcl_mobitems_carrot_on_a_stick.png", + wield_image = "mcl_mobitems_carrot_on_a_stick.png^[transformFY^[transformR90", inventory_image = "mcl_mobitems_carrot_on_a_stick.png", groups = { transport = 1 }, _mcl_toollike_wield = true, }) +minetest.register_tool("mcl_mobitems:warped_fungus_on_a_stick", { + description = S("Warped fungus on a Stick"), + _tt_help = S("Lets you ride a strider"), + _doc_items_longdesc = S("A warped fungus on a stick can be used on saddled striders to ride them."), + _doc_items_usagehelp = S("Place it on a saddled strider to mount it. You can now ride the strider like a horse. Striders will also walk towards you when you just wield the carrot on a stick."), + wield_image = "mcl_mobitems_warped_fungus_on_a_stick.png^[transformFY^[transformR90", + inventory_image = "mcl_mobitems_warped_fungus_on_a_stick.png", + groups = { transport = 1 }, + _mcl_toollike_wield = true, +}) + +minetest.register_craftitem("mcl_mobitems:nautilus_shell", { + description = S("Nautilus Shell"), + _tt_help = S("Used to craft a conduit"), + _doc_items_longdesc = S("The Nautilus Shell is used to craft a conduit. They can be obtained by fishing or killing a drowned that is wielding a shell."), + inventory_image = "mcl_mobitems_nautilus_shell.png", + groups = { craftitem=1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:heart_of_the_sea", { + description = S("Heart of the Sea"), + _tt_help = S("Used to craft a conduit"), + _doc_items_longdesc = S("The Heart of the Sea is used to craft a conduit. They can be obtained by finding them in a buried treasure chest."), + inventory_image = "mcl_mobitems_heart_of_the_sea.png", + groups = { craftitem=1 }, + stack_max = 64, +}) + local horse_armor_use = S("Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.") minetest.register_craftitem("mcl_mobitems:iron_horse_armor", { @@ -372,6 +409,15 @@ minetest.register_alias("mobs_mc:iron_horse_armor", "mcl_mobitems:iron_horse_arm minetest.register_alias("mobs_mc:gold_horse_armor", "mcl_mobitems:gold_horse_armor") minetest.register_alias("mobs_mc:diamond_horse_armor", "mcl_mobitems:diamond_horse_armor") +minetest.register_craftitem("mcl_mobitems:glow_ink_sac", { + description = S("Glow Ink Sac"), + _doc_items_longdesc = S("Use it to craft the Glow Item Frame."), + _doc_items_usagehelp = S("Use the Glow Ink Sac and the normal Item Frame to craft the Glow Item Frame."), + inventory_image = "extra_mobs_glow_ink_sac.png", + groups = { craftitem = 1 }, +}) + + ----------- -- Crafting ----------- @@ -423,6 +469,22 @@ minetest.register_craft({ }, }) +minetest.register_craft({ + output = "mcl_mobitems:warped_fungus_on_a_stick", + recipe = { + { "mcl_fishing:fishing_rod", "", }, + { "", "mcl_crimson:warped_fungus" }, + }, +}) + +minetest.register_craft({ + output = "mcl_mobitems:warped_fungus_on_a_stick", + recipe = { + { "","mcl_fishing:fishing_rod", }, + { "mcl_crimson:warped_fungus", "" }, + }, +}) + minetest.register_craft({ type = "shapeless", output = "mcl_mobitems:magma_cream", diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.de.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.de.tr index f9a0aaf50..c1278ad36 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.de.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.de.tr @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.=Halten Sie den Knochen in der Nähe von Wölfen, um sie anzulocken. Benutzen Sie die „Platzieren“-Taste auf dem Wolf, um ihm den Knochen zu geben und ihn zu zähmen. Sie können dem gezähmten Wolf Befehle erteilen, indem Sie die „Platzieren“-Taste auf ihm benutzen. +Squid Ink Sac=Tintenbeutel +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.=Dieser Gegenstand wird von toten Tintenfischen abgeworfen. Tintenbeutel können benutzt werden, um Buch und Feder oder schwarzen Farbstoff zu fertigen. + String=Faden Strings are used in crafting.=Fäden sind nützlich in der Fertigung. Blaze Rod=Lohenrute diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.es.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.es.tr index 9b149788a..1add14030 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.es.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.es.tr @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.=Empuña el hueso cerca de los lobos para atraerlos. Usa la tecla "Colocar" en el lobo para darle un hueso y domesticarlo. Luego puede dar órdenes al lobo domesticado utilizando la tecla "Colocar". +Squid Ink Sac=Saco de tinta +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.= + String=Cuerda Strings are used in crafting.=Las cuerdas se usan en la elaboración. Blaze Rod=Vara de blaze diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr index 8353054ab..09b7ea70b 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.=Maniez l'os près des loups pour les attirer. Utilisez la touche «Placer» sur le loup pour lui donner un os et l'apprivoiser. Vous pouvez ensuite donner des commandes au loup apprivoisé en utilisant la touche "Placer" sur celui-ci. +Squid Ink Sac=Poche d'encre +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.= + String=Ficelle Strings are used in crafting.=Les ficelles sont utilisées dans l'artisanat. Blaze Rod=Bâton de Blaze @@ -93,6 +96,12 @@ A carrot on a stick can be used on saddled pigs to ride them.=Une carotte sur un Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick.=Placez-le sur un cochon sellé pour le monter. Vous pouvez maintenant monter le cochon comme un cheval. Les porcs marcheront également vers vous lorsque vous brandirez la carotte sur un bâton. +Nautilus Shell=Coquille de nautile +Used to craft a conduit=Utilisé pour fabriquer un conduit. +The Nautilus Shell is used to craft a conduit. They can be obtained by fishing or killing a drowned that is wielding a shell.=La Coquille de nautile est utilisée pour fabriquer un conduit. Elles peuvent être obtenues en pêchant ou en tuant un noyé qui tient une coquille. +Heart of the Sea=Coeur de la Mer +The Heart of the Sea is used to craft a conduit. They can be obtained by finding them in a buried treasure chest.=Le Coeur de la Mer est utilisé pour fabriquer un conduit. Il peut être obtenu dans un coffre au trésor enterré. + Iron Horse Armor=Armure de cheval en fer Iron horse armor can be worn by horses to increase their protection from harm a bit.=L'armure de cheval en fer peut être portée par les chevaux pour augmenter un peu leur protection contre les dommages. Golden Horse Armor=Armure de cheval en or diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ja.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ja.tr new file mode 100644 index 000000000..f5d18c7f1 --- /dev/null +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ja.tr @@ -0,0 +1,108 @@ +# textdomain: mcl_mobitems +Rotten Flesh=腐った肉 +80% chance of food poisoning=80%の確率で食中毒 + +Yuck! This piece of flesh clearly has seen better days. If you're really desperate, you can eat it to restore a few hunger points, but there's a 80% chance it causes food poisoning, which increases your hunger for a while.=ウッ この肉片は明らかに期限切れです。あなたが差し迫っているというのなら、食べて空腹を紛らわせるのもアリですが、八割方 食中りを起こし、しばらくは空腹感が増します。 + +Raw Mutton=生の羊肉 + +Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will greatly increase its nutritional value.=生の羊の肉なので、安全に食べられます。調理することで栄養価は格段にアップします。 + +Cooked Mutton=ジンギスカン +Cooked mutton is the cooked flesh from a sheep and is used as food.=ジンギスカンは羊の肉を調理したもので、食用です。 +Raw Beef=生の牛肉 + +Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly increase its nutritional value.=生の牛の肉なので、安全に食べられます。調理することで栄養価が大幅にアップします。 + +Steak=ステーキ +Steak is cooked beef from cows and can be eaten.=ステーキは牛肉を調理したもので、食べることができます。 +Raw Chicken=生の鶏肉 +30% chance of food poisoning=30%の確率で食中毒 + +Raw chicken is a food item which is not safe to consume. You can eat it to restore a few hunger points, but there's a 30% chance to suffer from food poisoning, which increases your hunger rate for a while. Cooking raw chicken will make it safe to eat and increases its nutritional value.=生の鶏肉は、安全に摂取できない食品です。食べると空腹度が少し回復しますが、30%の確率で食中毒になり、しばらくの間は空腹感が増します。生の鶏肉を調理すると、安全に食べることができ、栄養価も高まります。 + +Cooked Chicken=ヤキトリ +A cooked chicken is a healthy food item which can be eaten.=ヤキトリは、食べても大丈夫なヘルシー食品です。 +Raw Porkchop=生の豚肉 + +A raw porkchop is the flesh from a pig and can be eaten safely. Cooking it will greatly increase its nutritional value.=生の豚の肉なので、安全に食べられます。調理することで栄養価が大幅にアップします。 + +Cooked Porkchop=チャーシュー +Cooked porkchop is the cooked flesh of a pig and is used as food.=チャーシューは豚の肉を調理したもので、食用です。 +Raw Rabbit=生の兎肉 + +Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it will increase its nutritional value.=死んだウサギ由来の食材です。安全に食べられます。調理することで栄養価が上がります。 + +Cooked Rabbit=ウサギの丸焼き +This is a food item which can be eaten.=これは食料品です。 +Milk=牛乳 +Removes all status effects=全ステータス効果を除去 + +Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will remove all status effects, but restores no hunger points.=牛乳はとてもさわやかで、バケツを牛に使うことで採れます。これを飲むと全てのステータス効果を除去しますが、お腹は満たせません。 + +Use the placement key to drink the milk.=配置キーを使うと、牛乳を飲みます。 +Spider Eye=クモの目 +Poisonous=有毒 + +Spider eyes are used mainly in crafting. If you're really desperate, you can eat a spider eye, but it will poison you briefly.=クモの目は主にクラフトに使われます。あなたがどうしようもなく過酷なら、食べることもできます…が、早い話これは毒です。 + +Bone=骨 + +Bones can be used to tame wolves so they will protect you. They are also useful as a crafting ingredient.=骨は、オオカミがあなたを守ってくれるよう馴らすために使えます。また、クラフトの材料としても有用です。 + +Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.=骨をオオカミの近くで振り、引き付けます。オオカミに「設置」キーを使うと、骨を与えて手なずけられます。手なずけたオオカミに「設置」キーを使えば、オオカミに号令が出せます。 + +String=糸 +Strings are used in crafting.=糸はクラフトに使えます。 +Blaze Rod=ブレイズロッド +This is a crafting component dropped from dead blazes.=これは死んだブレイズから落ちた、クラフトの構成材です。 +Blaze Powder=ブレイズパウダー +This item is mainly used for crafting.=このアイテムは主にクラフトに使われます。 +Magma Cream=マグマクリーム +Magma cream is a crafting component.=マグマクリームはクラフトの構成材です。 +Ghast Tear=ガストの涙 +Place this item in an item frame as decoration.=これをアイテムフレームに入れれば、飾りになります。 +Nether Star=ネザースター + +A nether star is dropped when the Wither dies. Place it in an item frame to show the world how hardcore you are! Or just as decoration.=ネザースターは、ウィザーが死んだ時にドロップします。アイテムフレームに入れれば、あなたのハードコアぶりを世界にアピールできます! あるいはただの飾りです。 + +Leather=革 +Leather is a versatile crafting component.=革は、多用途なクラフトの構成材です。 +Feather=羽 +Feathers are used in crafting and are dropped from chickens.=羽は、クラフトに使うもので、ニワトリからドロップします。 +Rabbit Hide=ウサギの皮 +Rabbit hide is used to create leather.=ウサギの皮は、革の原料として使われます。 +Rabbit's Foot=ウサギの足 +Must be your lucky day! Place this item in an item frame for decoration.=ラッキーデーに違いない! これはアイテムフレームに入れて飾ってください。 +Saddle=鞍 +Can be placed on animals to ride them=動物に被せて騎乗可能 +Saddles can be put on some animals in order to mount them.=動物によっては、鞍を装着して騎乗できます。 + +Use the placement key with the saddle in your hand to try to put on the saddle. Saddles fit on horses, mules, donkeys and pigs. Horses, mules and donkeys need to be tamed first, otherwise they'll reject the saddle. Saddled animals can be mounted by using the placement key on them again.=鞍を手にした状態で配置キーを使い、装着させてみましょう。鞍はウマ、ラバ、ロバ、ブタにフィットします。ウマ、ラバ、ロバは先に手なずけておかないと、鞍を拒んでしまいます。鞍をつけた動物には、もう一度配置キーを使えば騎乗できます。 + +Rabbit Stew=ラビットシチュー +Rabbit stew is a very nutricious food item.=ラビットシチューは、とても栄養豊富な食品です。 +Shulker Shell=シュルカーの殻 +Shulker shells are used in crafting. They are dropped from dead shulkers.=シュルカーの殻はクラフトに使われます。それは死んだシュルカーからドロップされます。 +Slimeball=スライムボール +Slimeballs are used in crafting. They are dropped from slimes.=スライムボールはクラフトに使われます。それはスライムからドロップされます。 +Gunpowder=火薬 +Carrot on a Stick=ニンジン付きの棒 +Lets you ride a saddled pig=鞍をつけたブタに乗れる +A carrot on a stick can be used on saddled pigs to ride them.=ニンジン付きの棒を使えば、鞍をつけたブタに騎乗できます。 + +Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick.=鞍をつけたブタの上にそれを掲げます。 これで、ブタに騎乗できること馬のごとしです。 ニンジン付きの棒を振るうだけでも、ブタはあなたに向かって歩いてきます。 + +Nautilus Shell=オウムガイの殻 +Used to craft a conduit=コンジットのクラフトに使用可 +The Nautilus Shell is used to craft a conduit. They can be obtained by fishing or killing a drowned that is wielding a shell.=オウムガイの殻は、コンジットをクラフトするのに使えます。 釣りをするか、貝を振り回しているドラウンドを殺ると入手できます。 +Heart of the Sea=海洋の心 +The Heart of the Sea is used to craft a conduit. They can be obtained by finding them in a buried treasure chest.=海洋の心は、コンジットをクラフトするのに使えます。 それは埋められた宝箱の中から見つけることで入手できます。 + +Iron Horse Armor=鉄の馬鎧 +Iron horse armor can be worn by horses to increase their protection from harm a bit.=鉄の馬鎧は、ウマに装着することで、危害から守る力を少し高めることができます。 +Golden Horse Armor=金の馬鎧 +Golden horse armor can be worn by horses to increase their protection from harm.=金の馬鎧は、ウマに装着することで、危害から守る力を高めることができます。 +Diamond Horse Armor=ダイヤモンドの馬鎧 +Diamond horse armor can be worn by horses to greatly increase their protection from harm.=ダイヤモンドの馬鎧は、ウマに装着することで、危害から守る力を大幅に高めることができます。 +Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=ウマに被せると、馬鎧を着せることができます。ロバとラバには、馬鎧を着せられません。 diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr index dd78a692f..a58bfb474 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr @@ -53,6 +53,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.=Trzymaj kość w pobliżu wilków aby je zwabić. Użyj przycisku "Umieść" na wilku aby dać mu kość i go oswoić. Możesz wtedy wydawać polecenia oswojonemu wilkowi klikając przycisk "Umieść" na nim. +Squid Ink Sac=Torbiel z atramentem +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.= + String=Nić Strings are used in crafting.=Nić jest użyteczna w wytwarzaniu. Blaze Rod=Płomienna różdżka diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr index 64f73618c..4e3fc020b 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.=Положите кость рядом с волками, чтобы привлечь их. Используйте клавишу “Разместить” на волке, чтобы дать ему кость и приручить его. Вы можете командовать приручёнными волками с помощью клавиши “Разместить”. +Squid Ink Sac=Чернильный мешок +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.= + String=Нити Strings are used in crafting.=Нити используются для крафтинга Blaze Rod=Огненный стержень diff --git a/mods/ITEMS/mcl_mobitems/locale/template.txt b/mods/ITEMS/mcl_mobitems/locale/template.txt index a3066dd1b..f26ab52d7 100644 --- a/mods/ITEMS/mcl_mobitems/locale/template.txt +++ b/mods/ITEMS/mcl_mobitems/locale/template.txt @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.= +Squid Ink Sac= +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.= + String= Strings are used in crafting.= Blaze Rod= @@ -93,6 +96,12 @@ A carrot on a stick can be used on saddled pigs to ride them.= Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick.= +Nautilus Shell= +Used to craft a conduit= +The Nautilus Shell is used to craft a conduit. They can be obtained by fishing or killing a drowned that is wielding a shell.= +Heart of the Sea= +The Heart of the Sea is used to craft a conduit. They can be obtained by finding them in a buried treasure chest.= + Iron Horse Armor= Iron horse armor can be worn by horses to increase their protection from harm a bit.= Golden Horse Armor= diff --git a/mods/ITEMS/mcl_mobitems/textures/extra_mobs_glow_ink_sac.png b/mods/ITEMS/mcl_mobitems/textures/extra_mobs_glow_ink_sac.png new file mode 100644 index 000000000..6628e6abb Binary files /dev/null and b/mods/ITEMS/mcl_mobitems/textures/extra_mobs_glow_ink_sac.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_heart_of_the_sea.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_heart_of_the_sea.png new file mode 100644 index 000000000..b55893963 Binary files /dev/null and b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_heart_of_the_sea.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_heart_of_the_sea_split.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_heart_of_the_sea_split.png new file mode 100644 index 000000000..4f6affbf1 Binary files /dev/null and b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_heart_of_the_sea_split.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_ink_sac.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_ink_sac.png new file mode 100644 index 000000000..95a8df4ad Binary files /dev/null and b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_ink_sac.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_nautilus_shell.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_nautilus_shell.png new file mode 100644 index 000000000..aa415508d Binary files /dev/null and b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_nautilus_shell.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_warped_fungus_on_a_stick.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_warped_fungus_on_a_stick.png new file mode 100644 index 000000000..9f20bf787 Binary files /dev/null and b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_warped_fungus_on_a_stick.png differ diff --git a/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ja.tr b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ja.tr new file mode 100644 index 000000000..e80806c5d --- /dev/null +++ b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_mobspawners +Mob Spawner=モブスポナー +A mob spawner regularily causes mobs to appear around it while a player is nearby. Some mob spawners are disabled while in light.=モブスポナーは、プレイヤーが近くにいる間、定期的にその周りにモブを出現させます。 一部のモブスポナーは、照らされていると無効化します。 +If you have a spawn egg, you can use it to change the mob to spawn. Just place the item on the mob spawner. Player-set mob spawners always spawn mobs regardless of the light level.=スポーンエッグを持っていれば、それを使ってスポーンするモブを変更できます。アイテムをモブスポナーに置くだけです。プレイヤーが設定したモブスポナーは、光量に関係なく常にモブをスポーンします。 +Makes mobs appear=モブを出現させる diff --git a/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ja.tr b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ja.tr new file mode 100644 index 000000000..5c88cc5be --- /dev/null +++ b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ja.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_monster_eggs +An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart.=虫喰いブロックは、壊れるとそこからシルバーフィッシュが飛び出してきます。見た目は通常のブロックと同じです。 +Infested Stone=虫喰い石 +Infested Cobblestone=虫喰い丸石 +Infested Stone Bricks=虫喰い石レンガ +Infested Cracked Stone Bricks=ひび割れた虫喰い石レンガ +Infested Mossy Stone Bricks=苔むした虫喰い石レンガ +Infested Chiseled Stone Bricks=模様入り虫喰い石レンガ +Hides a silverfish=シルバーフィッシュを隠す diff --git a/mods/ITEMS/mcl_mud/README.txt b/mods/ITEMS/mcl_mud/README.txt new file mode 100644 index 000000000..fe0a3f91c --- /dev/null +++ b/mods/ITEMS/mcl_mud/README.txt @@ -0,0 +1,21 @@ +License of Code +---------------- + +Author: TheRandomLegoBrick +License: GPLv3 +See https://www.gnu.org/licenses/gpl-3.0.en.html for further information + + +License of Media (textures & sounds) +------------------------------------- + +Author: TheRandomLegoBrick +Liscense: CC0 1.0 Universal (CC0 1.0) +Files: + mud_footsteps.ogg + mud_place_dug.ogg + mcl_mud_bricks.png + mcl_mud_packed_mud.png + mcl_mud.png + +See https://creativecommons.org/publicdomain/zero/1.0/legalcode for further information \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/init.lua b/mods/ITEMS/mcl_mud/init.lua new file mode 100644 index 000000000..64ff36c09 --- /dev/null +++ b/mods/ITEMS/mcl_mud/init.lua @@ -0,0 +1,65 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_node("mcl_mud:mud", { + description = S("Mud"), + _doc_items_longdesc = S("Mud is a decorative block that generates in mangrove swamps. Mud can also be obtained by using water bottles on dirt or coarse dirt."), + _doc_items_hidden = false, + tiles = {"mcl_mud.png"}, + is_ground_content = true, + sounds = { + footstep = {name="mud_footsteps", gain=1}, + dug = {name="mud_place_dug", gain=1}, + place = {name="mud_place_dug", gain=1}, + }, + groups = {handy=1, shovely=1, enderman_takable=1, grass_block=1, soil_sugarcane=1, building_block=1}, + _mcl_blast_resistance = 0.5, + _mcl_hardness = 0.5, + collision_box = { + type = "fixed", + fixed = { + {-8 / 16, -8 / 16, -8 / 16, 8 / 16, 6 / 16, 8 / 16}, + }, + }, +}) + +minetest.register_node("mcl_mud:packed_mud", { + description = S("Packed Mud"), + _doc_items_longdesc = S("Packed mud is a decorative block used to craft mud bricks."), + _doc_items_hidden = false, + tiles = {"mcl_mud_packed_mud.png"}, + groups = {handy=1, pickaxey=1, building_block=1}, + sounds = mcl_sounds.node_sound_dirt_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 1, +}) + +minetest.register_node("mcl_mud:mud_bricks", { + description = S("Mud Bricks"), + _doc_items_longdesc = S("Decorative block crafted from packed mud."), + _doc_items_hidden = false, + tiles = {"mcl_mud_bricks.png"}, + groups = {handy=1, pickaxey=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 1.5, +}) + +-- packed mud +minetest.register_craft({ + type = "shapeless", + output = "mcl_mud:packed_mud", + recipe = { + "mcl_mud:mud", + "mcl_farming:wheat_item", + } +}) + +-- mud bricks +minetest.register_craft({ + type = "shaped", + output = "mcl_mud:mud_bricks 4", + recipe = { + {"mcl_mud:packed_mud", "mcl_mud:packed_mud"}, + {"mcl_mud:packed_mud", "mcl_mud:packed_mud"} + } +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/locale/mcl_mud.fr.tr b/mods/ITEMS/mcl_mud/locale/mcl_mud.fr.tr new file mode 100644 index 000000000..e79f5afe9 --- /dev/null +++ b/mods/ITEMS/mcl_mud/locale/mcl_mud.fr.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_mud +Mud=Boue +Mud is a decorative block that generates in mangrove swamps. Mud can also be obtained by using water bottles on dirt or coarse dirt.=La boue est un bloc décoratif généré dans les marécages mangrove. La boue peut aussi être obtenue en utilisant des bouteilles d'eau sur de la terre ou de la terre stérile. +Packed Mud=Boue Compactée +Packed mud is a decorative block used to craft mud bricks.=La boue compactée est un bloc décoratif utilisé pour fabriquer des briques de boue. +Mud Bricks=Briques de Boue +Decorative block crafted from packed mud.=Bloc décoratif fabriqué à partir de boue compactée. \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/locale/mcl_mud.ja.tr b/mods/ITEMS/mcl_mud/locale/mcl_mud.ja.tr new file mode 100644 index 000000000..3c4eba845 --- /dev/null +++ b/mods/ITEMS/mcl_mud/locale/mcl_mud.ja.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_mud +Mud=泥 +Mud is a decorative block that generates in mangrove swamps. Mud can also be obtained by using water bottles on dirt or coarse dirt.=泥は、マングローブの湿地に発生する装飾ブロックです。泥は、土や粗い土の上に水入り瓶を使っても得られます。 +Packed Mud=固めた泥 +Packed mud is a decorative block used to craft mud bricks.=固めた泥は、泥レンガを作るための装飾ブロックです。 +Mud Bricks=泥レンガ +Decorative block crafted from packed mud.=固めた泥で作った装飾ブロックです。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/locale/template.txt b/mods/ITEMS/mcl_mud/locale/template.txt new file mode 100644 index 000000000..a42019d1c --- /dev/null +++ b/mods/ITEMS/mcl_mud/locale/template.txt @@ -0,0 +1,7 @@ +# textdomain: mcl_mud +Mud= +Mud is a decorative block that generates in mangrove swamps. Mud can also be obtained by using water bottles on dirt or coarse dirt.= +Packed Mud= +Packed mud is a decorative block used to craft mud bricks.= +Mud Bricks= +Decorative block crafted from packed mud.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/mod.conf b/mods/ITEMS/mcl_mud/mod.conf new file mode 100644 index 000000000..70f48ef1e --- /dev/null +++ b/mods/ITEMS/mcl_mud/mod.conf @@ -0,0 +1,4 @@ +name = mcl_mud +author = TheRandomLegoBrick +description = Adds various mud blocks. +depends = mcl_sounds \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/sounds/mud_footsteps.ogg b/mods/ITEMS/mcl_mud/sounds/mud_footsteps.ogg new file mode 100644 index 000000000..e18c93965 Binary files /dev/null and b/mods/ITEMS/mcl_mud/sounds/mud_footsteps.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_water_footstep.4.ogg b/mods/ITEMS/mcl_mud/sounds/mud_place_dug.ogg similarity index 60% rename from mods/CORE/mcl_sounds/sounds/default_water_footstep.4.ogg rename to mods/ITEMS/mcl_mud/sounds/mud_place_dug.ogg index 6f1eab824..5a93ca14a 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_water_footstep.4.ogg and b/mods/ITEMS/mcl_mud/sounds/mud_place_dug.ogg differ diff --git a/mods/ITEMS/mcl_mud/textures/mcl_mud.png b/mods/ITEMS/mcl_mud/textures/mcl_mud.png new file mode 100644 index 000000000..629831124 Binary files /dev/null and b/mods/ITEMS/mcl_mud/textures/mcl_mud.png differ diff --git a/mods/ITEMS/mcl_mud/textures/mcl_mud_bricks.png b/mods/ITEMS/mcl_mud/textures/mcl_mud_bricks.png new file mode 100644 index 000000000..c102118e7 Binary files /dev/null and b/mods/ITEMS/mcl_mud/textures/mcl_mud_bricks.png differ diff --git a/mods/ITEMS/mcl_mud/textures/mcl_mud_packed_mud.png b/mods/ITEMS/mcl_mud/textures/mcl_mud_packed_mud.png new file mode 100644 index 000000000..5e335e97e Binary files /dev/null and b/mods/ITEMS/mcl_mud/textures/mcl_mud_packed_mud.png differ diff --git a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ja.tr b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ja.tr new file mode 100644 index 000000000..c0dd56daf --- /dev/null +++ b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ja.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_mushrooms +This decorative block is like a huge mushroom stem, but with the stem texture on all sides.=巨大なキノコの柄のような装飾ブロックですが、四方に柄のテクスチャが施されています。 +Huge red mushroom blocks are the cap parts of huge red mushrooms. It consists of a red skin and can have pores on each of its sides.=巨大な赤色キノコのブロックは、巨大な赤色キノコのキャップ部分です。赤色の皮からなり、各面に孔口を持つこともあります。 +The stem part of a huge red mushroom.=巨大な赤色キノコの柄の部分。 +Huge Red Mushroom Block=巨大な赤色キノコのブロック +Huge Red Mushroom Stem=巨大な赤色キノコの柄 +Huge Red Mushroom All-Faces Stem=巨大な赤色キノコの柄(全面) +Huge brown mushroom blocks are the cap parts of huge brown mushrooms. It consists of a brown skin and can have pores on each of its sides.=巨大な茶色キノコのブロックは、巨大な茶色キノコのキャップ部分です。茶色の皮からなり、各面に孔口を持つこともあります。 +The stem part of a huge brown mushroom.=巨大な茶色キノコの柄の部分。 +Huge Brown Mushroom Block=巨大な茶色キノコのブロック +Huge Brown Mushroom Stem=巨大な茶色キノコの柄 +Huge Brown Mushroom All-Faces Stem=巨大な茶色キノコの柄(全面) +Brown mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.=茶色キノコは、暗闇の中で成長し広がる菌類ですが、光に弱いという特徴があります。食用には適しませんが、食品に加工することはできます。 +Red mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.=赤色キノコは、暗闇で中で成長し広がる菌類ですが、光に弱いという特徴があります。食用には適しませんが、食品に加工することはできます。 +A single mushroom of this species will slowly spread over time towards a random solid opaque block with a light level of 12 or lower in a 3×3×3 cube around the mushroom. It stops spreading when there are 5 or more mushrooms of the same species within an area of 9×3×9 blocks around the mushroom.=この種のキノコは、キノコの周囲の3×3×3キューブ内にある光度12以下のランダムな不透明固体ブロックに向かって、時間経過と共にゆっくりと広がっていきます。キノコの周囲9×3×9ブロックの範囲に同じ種のキノコが5個以上あると、拡散を止めます。 +Mushrooms will eventually uproot at a light level of 12 or higher. On mycelium or podzol, they survive and spread at any light level.=キノコは、光量が12以上になると根こそぎになります。菌糸体やポドゾルの上では、どのような光量でも生き残り、広がっていきます。 +This mushroom can be placed on mycelium and podzol at any light level. It can also be placed on blocks which are both solid and opaque, as long as the light level at daytime is not higher than 12.=このキノコは、どんな光量でも菌糸体やポドゾルの上に置けます。また、昼間の光量が12以下であれば、固体や不透明なブロックの上にも置くことができます。 +Brown Mushroom=茶色キノコ +Red Mushroom=赤色キノコ +Mushroom Stew=キノコシチュー +Mushroom stew is a healthy soup which can be consumed to restore some hunger points.=キノコシチューは、満腹度を満たすために食べられるヘルシースープです。 +By placing huge mushroom blocks of the same species next to each other, the sides that touch each other will turn into pores permanently.=同種の巨大なキノコのブロックを隣り合わせに置くことで、接した面が永久に孔口になります。 +Grows on podzol, mycelium and other blocks=ポドゾル、菌糸体、その他のブロックに生育 +Spreads in darkness=暗闇の中で拡散 diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 2d8def90d..d300df5fd 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -51,6 +51,34 @@ minetest.register_node("mcl_nether:quartz_ore", { _mcl_fortune_drop = mcl_core.fortune_drop_ore }) +minetest.register_node("mcl_nether:ancient_debris", { + description = S("Ancient Debris"), + _doc_items_longdesc = S("Ancient debris can be found in the nether and is very very rare."), + stack_max = 64, + tiles = {"mcl_nether_ancient_debris_top.png", "mcl_nether_ancient_debris_side.png"}, + is_ground_content = true, + groups = {pickaxey=4, building_block=1, material_stone=1, xp=0}, + drop = "mcl_nether:ancient_debris", + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 1200, + _mcl_hardness = 30, + _mcl_silk_touch_drop = true +}) + +minetest.register_node("mcl_nether:netheriteblock", { + description = S("Netherite Block"), + _doc_items_longdesc = S("Netherite block is very hard and can be made of 9 netherite ingots."), + stack_max = 64, + tiles = {"mcl_nether_netheriteblock.png"}, + is_ground_content = true, + groups = { pickaxey=4, building_block=1, material_stone=1, xp = 0, fire_immune=1 }, + drop = "mcl_nether:netheriteblock", + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 1200, + _mcl_hardness = 50, + _mcl_silk_touch_drop = true, +}) + -- For eternal fire on top of netherrack and magma blocks -- (this code does not require a dependency on mcl_fire) local function eternal_after_destruct(pos, oldnode) @@ -251,6 +279,22 @@ minetest.register_craftitem("mcl_nether:quartz", { groups = { craftitem = 1 }, }) +minetest.register_craftitem("mcl_nether:netherite_scrap", { + description = S("Netherite Scrap"), + _doc_items_longdesc = S("Netherite scrap is a crafting ingredient for netherite ingots."), + inventory_image = "mcl_nether_netherite_scrap.png", + stack_max = 64, + groups = { craftitem = 1, fire_immune=1 }, +}) + +minetest.register_craftitem("mcl_nether:netherite_ingot", { + description = S("Netherite Ingot"), + _doc_items_longdesc = S("Netherite ingots can be used with a smithing table to upgrade items to netherite."), + inventory_image = "mcl_nether_netherite_ingot.png", + stack_max = 64, + groups = { craftitem = 1, fire_immune=1 }, +}) + minetest.register_craftitem("mcl_nether:netherbrick", { description = S("Nether Brick"), _doc_items_longdesc = S("Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences."), @@ -266,6 +310,13 @@ minetest.register_craft({ cooktime = 10, }) +minetest.register_craft({ + type = "cooking", + output = "mcl_nether:netherite_scrap", + recipe = "mcl_nether:ancient_debris", + cooktime = 10, +}) + minetest.register_craft({ output = "mcl_nether:quartz_block", recipe = { @@ -337,5 +388,32 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = "mcl_nether:netherite_ingot", + recipe = { + {"mcl_nether:netherite_scrap", "mcl_nether:netherite_scrap", "mcl_nether:netherite_scrap"}, + {"mcl_nether:netherite_scrap", "mcl_core:gold_ingot", "mcl_core:gold_ingot"}, + {"mcl_core:gold_ingot", "mcl_core:gold_ingot", ""}, + } +}) + +minetest.register_craft({ + output = "mcl_nether:netheriteblock", + recipe = { + {"mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot"}, + {"mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot"}, + {"mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot"} + } +}) + +minetest.register_craft({ + output = "mcl_nether:netherite_ingot 9", + recipe = { + {"mcl_nether:netheriteblock", "", ""}, + {"", "", ""}, + {"", "", ""} + } +}) + dofile(minetest.get_modpath(minetest.get_current_modname()).."/nether_wart.lua") dofile(minetest.get_modpath(minetest.get_current_modname()).."/lava.lua") diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr index 3e3583355..864715eb7 100644 --- a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr @@ -1,40 +1,45 @@ # textdomain: mcl_nether Glowstone=Pierre Lumineuse -Glowstone is a naturally-glowing block which is home to the Nether.=La Pierre Lumineuse est un bloc naturellement brillant qui abrite le Nether. +Glowstone is a naturally-glowing block which is home to the Nether.=La Pierre Lumineuse est un bloc naturellement brillant originaire du Nether. Nether Quartz Ore=Minerai de quartz du Nether -Nether quartz ore is an ore containing nether quartz. It is commonly found around netherrack in the Nether.=Le minerai de quartz du Nether est un minerai contenant du quartz du Nether. Il se trouve généralement autour du Néantrack dans le Nether. +Nether quartz ore is an ore containing nether quartz. It is commonly found around netherrack in the Nether.=Le minerai de quartz du Nether est un minerai contenant du quartz du Nether. Il se trouve généralement autour de la netherrack dans le Nether. Netherrack=Netherrack -Netherrack is a stone-like block home to the Nether. Starting a fire on this block will create an eternal fire.=Netherrack est un bloc de pierre qui abrite le Nether. Démarrer un feu sur ce bloc créera un feu éternel. +Netherrack is a stone-like block home to the Nether. Starting a fire on this block will create an eternal fire.=La netherrack est un bloc de pierre originaire du Nether. Démarrer un feu sur ce bloc créera un feu éternel. Magma Block=Bloc de Magma -Magma blocks are hot solid blocks which hurt anyone standing on it, unless they have fire resistance. Starting a fire on this block will create an eternal fire.=Les blocs de magma sont des blocs solides chauds qui blessent quiconque s'y tient, à moins qu'ils n'aient une résistance au feu. Démarrer un feu sur ce bloc créera un feu éternel. +Magma blocks are hot solid blocks which hurt anyone standing on it, unless they have fire resistance. Starting a fire on this block will create an eternal fire.=Les blocs de magma sont des blocs solides chauds qui blessent quiconque s'y tient, à moins d'avoir une résistance au feu. Démarrer un feu sur ce bloc créera un feu éternel. @1 stood too long on a magma block.=@1 s'est tenu trop longtemps sur un bloc de magma. Soul Sand=Sable des âmes -Soul sand is a block from the Nether. One can only slowly walk on soul sand. The slowing effect is amplified when the soul sand is on top of ice, packed ice or a slime block.=Le sable de l'âme est un bloc du Nether. On ne peut que marcher lentement sur le sable de l'âme. L'effet de ralentissement est amplifié lorsque le sable de l'âme est au-dessus de la glace, de la glace tassée ou d'un bloc de slime. +Soul sand is a block from the Nether. One can only slowly walk on soul sand. The slowing effect is amplified when the soul sand is on top of ice, packed ice or a slime block.=Le sable de l'âme est un bloc du Nether. On ne peut marcher que lentement sur le sable de l'âme. L'effet de ralentissement est amplifié lorsque le sable de l'âme est au-dessus de la glace, de la glace tassée ou d'un bloc de slime. Nether Brick Block=Bloc de Briques du Nether Red Nether Brick Block=Bloc de Briques Rouges du Nether Nether Wart Block=Bloc de Verrues du Nether -A nether wart block is a purely decorative block made from nether wart.=Un bloc de verrues du Nether est un bloc purement décoratif fabriqué à partir de verrue du Nether. +A nether wart block is a purely decorative block made from nether wart.=Un bloc de verrues du Nether est un bloc purement décoratif fabriqué à partir de verrues du Nether. Block of Quartz=Bloc de Quartz Chiseled Quartz Block=Bloc de Quartz sculpté Pillar Quartz Block=Bloc de Quartz rayé Smooth Quartz=Quartz Lisse Glowstone Dust=Poudre Lumineuse -Glowstone dust is the dust which comes out of broken glowstones. It is mainly used in crafting.=La poudre lumineuse est la poussière qui sort des pierres incandescentes brisées. Il est principalement utilisé dans l'artisanat. +Glowstone dust is the dust which comes out of broken glowstones. It is mainly used in crafting.=La poudre lumineuse est la poussière qui sort des pierres lumineuses brisées. Elle est principalement utilisée dans l'artisanat. Nether Quartz=Quartz du Nether Nether quartz is a versatile crafting ingredient.=Le quartz du Nether est un ingrédient artisanal polyvalent. Nether Brick=Brique du Nether Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences.=Les briques du Nether sont le principal ingrédient pour la fabrication de blocs de briques et de clôtures du Nether. Nether Lava Source=Source de Lave du Nether -Flowing Nether Lava=Lave du Nether en Mouvement +Flowing Nether Lava=Lave du Nether en mouvement Premature Nether Wart (Stage 1)=Verrue du Néant prématurée (étape 1) -A premature nether wart has just recently been planted on soul sand. Nether wart slowly grows on soul sand in 4 stages (the second and third stages look identical). Although nether wart is home to the Nether, it grows in any dimension.=Une verrue du Nether prématurée vient d'être plantée sur du sable d'âme. La verrue du Nether pousse lentement sur le sable de l'âme en 4 étapes (les deuxième et troisième étapes semblent identiques). Bien que la verrue du Nether habite le Nether, elle se développe dans toutes les dimensions. -Premature Nether Wart (Stage 2)=Verrue du Néant prématurée (étape 2) -Premature Nether Wart (Stage 3)=Verrue du Néant prématurée (étape 3) -Mature Nether Wart=Verrue du Néant Mature -The mature nether wart is a plant from the Nether and reached its full size and won't grow any further. It is ready to be harvested for its items.=La verrue du Nether mature est une plante du Nether qui a atteint sa taille maximale et ne poussera plus. Il est prêt à être récolté pour ses articles. +A premature nether wart has just recently been planted on soul sand. Nether wart slowly grows on soul sand in 4 stages (the second and third stages look identical). Although nether wart is home to the Nether, it grows in any dimension.=Une verrue du Nether prématurée vient d'être plantée sur du sable d'âme. La verrue du Nether pousse lentement sur le sable de l'âme en 4 étapes (les deuxième et troisième étapes semblent identiques). Bien que la verrue du Nether soit originaire du Nether, elle se développe dans toutes les dimensions. +Premature Nether Wart (Stage 2)=Verrue du Nether prématurée (étape 2) +Premature Nether Wart (Stage 3)=Verrue du Nether prématurée (étape 3) +Mature Nether Wart=Verrue du Nether Mature +The mature nether wart is a plant from the Nether and reached its full size and won't grow any further. It is ready to be harvested for its items.=La verrue du Nether mature est une plante du Nether qui a atteint sa taille maximale et ne poussera plus. Elle est prête à être récoltée. Nether Wart=Verrues du Nether -Nether warts are plants home to the Nether. They can be planted on soul sand and grow in 4 stages.=Les verrues du Nether sont des plantes qui habitent le Nether. Ils peuvent être plantés sur du sable d'âme et se développer en 4 étapes. +Nether warts are plants home to the Nether. They can be planted on soul sand and grow in 4 stages.=Les verrues du Nether sont des plantes originaires du Nether. Elles peuvent être plantées sur du sable d'âme et se développer en 4 étapes. Place this item on soul sand to plant it and watch it grow.=Placez cet article sur du sable d'âme pour le planter et regardez-le grandir. Burns your feet=Vous brûle les pieds Grows on soul sand=Pousse sur le sable de l'âme -Reduces walking speed=Réduit la vitesse de marche \ No newline at end of file +Reduces walking speed=Réduit la vitesse de marche +Netherite Scrap=Fragments de Netherite +Netherite Ingot=Lingot de Netherite +Ancient Debris=Débris antiques +Netherite Block=Bloc de Netherite +Netherite block is very hard and can be made of 9 netherite ingots.=Les blocs de netherite sont très durs et peuvent être fabriqués à partir de 9 lingots de netherite. \ No newline at end of file diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.ja.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.ja.tr new file mode 100644 index 000000000..3ba6bf9fe --- /dev/null +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.ja.tr @@ -0,0 +1,45 @@ +# textdomain: mcl_nether +Glowstone=グローストーン +Glowstone is a naturally-glowing block which is home to the Nether.=グローストーンは、ネザーをホームとする、自然に発光するブロックです。 +Nether Quartz Ore=ネザークォーツ鉱石 +Nether quartz ore is an ore containing nether quartz. It is commonly found around netherrack in the Nether.=ネザークォーツ鉱石は、ネザークォーツを含む鉱石です。ネザーの、ネザーラック周辺によく見られます。 +Netherrack=ネザーラック +Netherrack is a stone-like block home to the Nether. Starting a fire on this block will create an eternal fire.=ネザーラックは、ネザーにある石のようなブロックです。このブロックに火を点けると、永続的な炎が発生します。 +Magma Block=マグマブロック +Magma blocks are hot solid blocks which hurt anyone standing on it, unless they have fire resistance. Starting a fire on this block will create an eternal fire.=マグマブロックは高温の固体ブロックであり、その上に立つ者は、火耐性がない限りダメージを受けます。このブロック上で火を起こすと、永続的な炎が発生します。 +@1 stood too long on a magma block.=@1 はマグマブロックの上に長く立ちすぎました。 +Soul Sand=ソウルサンド +Soul sand is a block from the Nether. One can only slowly walk on soul sand. The slowing effect is amplified when the soul sand is on top of ice, packed ice or a slime block.=ソウルサンドはネザー由来のブロックです。ソウルサンド上ではゆっくりしか歩けません。ソウルサンドが氷や氷塊、スライムブロックの上にある場合、速度低下の効果が増幅されます。 +Nether Brick Block=ネザーレンガブロック +Red Nether Brick Block=赤いネザーレンガブロック +Nether Wart Block=ネザーウォートブロック +A nether wart block is a purely decorative block made from nether wart.=ネザーウォートブロックは、ネザーウォートを使った純粋な装飾用ブロックです。 +Block of Quartz=クォーツブロック +Chiseled Quartz Block=模様入りクォーツブロック +Pillar Quartz Block=クォーツブロックピラー +Smooth Quartz=滑らかなクォーツ +Glowstone Dust=グローストーンダスト +Glowstone dust is the dust which comes out of broken glowstones. It is mainly used in crafting.=グローストーンダストは、グローストーンが割れたときに出る粉です。主にクラフトに使用されます。 +Nether Quartz=ネザークォーツ +Nether quartz is a versatile crafting ingredient.=ネザークォーツは、汎用性の高いクラフト材料です。 +Nether Brick=ネザーレンガ +Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences.=ネザーレンガは、ネザーレンガブロックやネザーフェンスを製作するための主なクラフト材料です。 +Nether Lava Source=ネザー溶岩源 +Flowing Nether Lava=流れるネザー溶岩 +Premature Nether Wart (Stage 1)=未成熟なネザーウォート(段階1) +A premature nether wart has just recently been planted on soul sand. Nether wart slowly grows on soul sand in 4 stages (the second and third stages look identical). Although nether wart is home to the Nether, it grows in any dimension.=未成熟なネザーウォートは、ソウルサンドに植えられたばかりです。ネザーウォートはソウルサンドの上で4段階に分けてゆっくりと成長します(2段階目と3段階目の見た目は同じ)。ネザーウォートはネザーに生息しているものの、どこの次元でも成長します。 +Premature Nether Wart (Stage 2)=未成熟なネザーウォート(段階2) +Premature Nether Wart (Stage 3)=未成熟なネザーウォート(段階3) +Mature Nether Wart=成熟したネザーウォート +The mature nether wart is a plant from the Nether and reached its full size and won't grow any further. It is ready to be harvested for its items.=成熟したネザーウォートは、フルサイズに達し成長の止まった、ネザー由来の植物です。もうアイテムとして収穫可能です。 +Nether Wart=ネザーウォート +Nether warts are plants home to the Nether. They can be planted on soul sand and grow in 4 stages.=ネザーウォート(ウォート=イボ)は、ネザーに生息する植物です。ソウルサンドに植えることができ、4段階に分けて成長します。 +Place this item on soul sand to plant it and watch it grow.=このアイテムをソウルサンドの上に置いて植えると、その成長を見ることができます。 +Burns your feet=足裏の火傷 +Grows on soul sand=ソウルサンドの上で育つ +Reduces walking speed=歩行速度 低下 +Netherite Scrap=ネザライトスクラップ +Netherite Ingot=ネザライトインゴット +Ancient Debris=古代の残骸 +Netherite Block=ネザライトブロック +Netherite block is very hard and can be made of 9 netherite ingots.=ネザライトブロックは、非常に硬く、9個のネザライトインゴットから作れます。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_nether/locale/template.txt b/mods/ITEMS/mcl_nether/locale/template.txt index 0e69ad520..283472f63 100644 --- a/mods/ITEMS/mcl_nether/locale/template.txt +++ b/mods/ITEMS/mcl_nether/locale/template.txt @@ -37,4 +37,9 @@ Nether warts are plants home to the Nether. They can be planted on soul sand and Place this item on soul sand to plant it and watch it grow.= Burns your feet= Grows on soul sand= -Reduces walking speed= \ No newline at end of file +Reduces walking speed= +Netherite Scrap= +Netherite Ingot= +Ancient Debris= +Netherite Block= +Netherite block is very hard and can be made of 9 netherite ingots.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_ancient_debris_side.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_ancient_debris_side.png new file mode 100644 index 000000000..989160402 Binary files /dev/null and b/mods/ITEMS/mcl_nether/textures/mcl_nether_ancient_debris_side.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_ancient_debris_top.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_ancient_debris_top.png new file mode 100644 index 000000000..ba68f658a Binary files /dev/null and b/mods/ITEMS/mcl_nether/textures/mcl_nether_ancient_debris_top.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_gold_ore.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_gold_ore.png new file mode 100644 index 000000000..2a670e61a Binary files /dev/null and b/mods/ITEMS/mcl_nether/textures/mcl_nether_gold_ore.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_netherite_ingot.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_netherite_ingot.png new file mode 100644 index 000000000..113961198 Binary files /dev/null and b/mods/ITEMS/mcl_nether/textures/mcl_nether_netherite_ingot.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_netherite_scrap.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_netherite_scrap.png new file mode 100644 index 000000000..c93b6e1af Binary files /dev/null and b/mods/ITEMS/mcl_nether/textures/mcl_nether_netherite_scrap.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_netheriteblock.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_netheriteblock.png new file mode 100644 index 000000000..302ead2a0 Binary files /dev/null and b/mods/ITEMS/mcl_nether/textures/mcl_nether_netheriteblock.png differ diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index ae273abe9..5957bafb2 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -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, compostability = 30}, + groups = {deco_block = 1, compostability = 30, smoker_cookable = 1}, }) if mod_doc then @@ -782,7 +782,7 @@ minetest.register_node("mcl_ocean:dried_kelp_block", { on_place = mcl_util.rotate_axis, on_rotate = on_rotate, _mcl_hardness = 0.5, - _mcl_blast_resistance = 12.5, + _mcl_blast_resistance = 2.5, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ja.tr b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ja.tr new file mode 100644 index 000000000..1db188129 --- /dev/null +++ b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ja.tr @@ -0,0 +1,60 @@ +# textdomain: mcl_ocean +Sea Lantern=シーランタン +Sea lanterns are decorative light sources which look great underwater but can be placed anywhere.=シーランタンは、水中で映える装飾的な光源ですが、どこにでも設置できます。 +Prismarine=プリズマリン +Prismarine is used as a building block. It slowly changes its color.=プリズマリンは、建築ブロックとして使用されます。 それはゆっくりと色を変えます。 +Prismarine Bricks=プリズマリンレンガ +Dark Prismarine=暗色プリズマリン +Prismarine Crystals=プリズマリンクリスタル +Prismarine Shard=プリズマリンの欠片 +Dried Kelp=乾燥コンブ +Dried Kelp Block=乾燥コンブブロック +Brain Coral Block=脳サンゴブロック +Brain Coral Fan=脳ウチワサンゴ +Brain Coral=脳サンゴ +Bubble Coral Block=泡サンゴブロック +Bubble Coral Fan=泡ウチワサンゴ +Bubble Coral=泡サンゴ +Fire Coral Block=火サンゴブロック +Fire Coral Fan=火ウチワサンゴ +Fire Coral=火サンゴ +Horn Coral Block=角サンゴブロック +Horn Coral Fan=角ウチワサンゴ +Horn Coral=角サンゴ +Tube Coral Block=管サンゴブロック +Tube Coral Fan=管ウチワサンゴ +Tube Coral=管サンゴ +Dead Brain Coral Block=死した脳サンゴブロック +Dead Brain Coral Fan=死した脳ウチワサンゴ +Dead Brain Coral=死した脳サンゴ +Dead Bubble Coral Block=死した泡サンゴブロック +Dead Bubble Coral Fan=死した泡ウチワサンゴ +Dead Bubble Coral=死した泡サンゴ +Dead Fire Coral Block=死した火サンゴブロック +Dead Fire Coral Fan=死した火ウチワサンゴ +Dead Fire Coral=死した火サンゴ +Dead Horn Coral Block=死した角サンゴブロック +Dead Horn Coral Fan=死した角ウチワサンゴ +Dead Horn Coral=死した角サンゴ +Dead Tube Coral Block=死した管サンゴブロック +Dead Tube Coral Fan=死した管ウチワサンゴ +Dead Tube Coral=死した管サンゴ +Seagrass=海草 +Kelp=コンブ +Kelp grows inside water on top of dirt, sand or gravel.=昆布が育つのは、水中の土・砂・砂利の上です。 +Coral blocks live in the oceans and need a water source next to them to survive. Without water, they die off.=サンゴのブロックは海に生息しており、生きていくためには隣に水源が必要です。水がないと死んでしまうのです。 +Corals grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=サンゴはサンゴブロックの上で成長し、生きていくためには水源の中にいる必要があります。 水がなければ、下のサンゴブロックと同様に死んでしまいます。 +Corals fans grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=ウチワサンゴはサンゴブロックの上で成長し、生きていくためには水源の中にいる必要があります。 水がなければ、下のサンゴブロックと同様に死んでしまいます。 +Seagrass grows inside water on top of dirt, sand or gravel.=海草が育つのは、水中の土・砂・砂利の上です。 +A decorative block that serves as a great furnace fuel.=炉の燃料として最適な装飾ブロック。 +Dried kelp is a food item.=乾燥コンブは食品です。 +Grows on coral block of same species=同種のサンゴブロックに生育 +Needs water to live=生きるために水が必要 +Grows in water on dirt, sand, gravel=水中の土・砂・砂利の上で成長 +Glows in the water=水中で成長 +4 possible sizes=4種類のサイズが可能 +Grows on dead brain coral block=死した脳サンゴブロックに生育 +Sea Pickle=ヒカリボヤ +Sea pickles grow on dead brain coral blocks and provide light when underwater. They come in 4 sizes that vary in brightness.=死した脳サンゴブロックに生え、水中での光源となるヒカリボヤ。明るさの異なる4種類のサイズがあります。 +It can only be placed on top of dead brain coral blocks. Placing a sea pickle on another sea pickle will make it grow and brighter.=死した脳サンゴブロックの上にしか置けません。ヒカリボヤを別のヒカリボヤの上に置くと成長し、明るくなります。 + diff --git a/mods/ITEMS/mcl_ocean/prismarine.lua b/mods/ITEMS/mcl_ocean/prismarine.lua index e38b3e0a6..32d17538d 100644 --- a/mods/ITEMS/mcl_ocean/prismarine.lua +++ b/mods/ITEMS/mcl_ocean/prismarine.lua @@ -40,7 +40,7 @@ minetest.register_node("mcl_ocean:prismarine", { tiles = {{name="mcl_ocean_prismarine_anim.png", animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=45.0}}}, groups = {pickaxey=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 1.5, + _mcl_blast_resistance = 6, _mcl_hardness = 1.5, }) diff --git a/mods/ITEMS/mcl_ocean/seagrass.lua b/mods/ITEMS/mcl_ocean/seagrass.lua index 2f58a2812..8213fec10 100644 --- a/mods/ITEMS/mcl_ocean/seagrass.lua +++ b/mods/ITEMS/mcl_ocean/seagrass.lua @@ -82,8 +82,8 @@ minetest.register_craftitem("mcl_ocean:seagrass", { description = S("Seagrass"), _tt_help = S("Grows in water on dirt, sand, gravel"), _doc_items_create_entry = false, - inventory_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", - wield_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", + inventory_image = "mcl_ocean_seagrass_item.png", + wield_image = "mcl_ocean_seagrass_item.png", on_place = seagrass_on_place, groups = {deco_block = 1, compostability = 30}, }) @@ -106,7 +106,7 @@ for s=1, #surfaces do doc_longdesc = S("Seagrass grows inside water on top of dirt, sand or gravel.") desc = S("Seagrass") doc_create = true - doc_img = "mcl_ocean_seagrass.png^[verticalframe:12:0" + doc_img = "mcl_ocean_seagrass_item.png" else doc_create = false end @@ -126,8 +126,8 @@ for s=1, #surfaces do animation = {type="vertical_frames", aspect_w=16, aspect_h=16, length=1.0}, } }, - inventory_image = "("..def.tiles[1]..")^(mcl_ocean_seagrass.png^[verticalframe:12:0)", - wield_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", + inventory_image = "mcl_ocean_seagrass_item.png", + wield_image = "mcl_ocean_seagrass_item.png", selection_box = { type = "fixed", fixed = { diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_seagrass_item.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_seagrass_item.png new file mode 100644 index 000000000..99b11dc29 Binary files /dev/null and b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_seagrass_item.png differ diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.ja.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.ja.tr new file mode 100644 index 000000000..aea984691 --- /dev/null +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.ja.tr @@ -0,0 +1,15 @@ +# textdomain: mcl_portals +End Portal=エンドポータル +An End portal teleports creatures and objects to the mysterious End dimension (and back!).=エンドポータルは、生物や物を不可思議なエンドの次元にテレポートさせます(また戻ってくる事も可能)。 +Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=ポータルに飛び込むとテレポート。(オーバーワールドにあるエンドポータルに入ると、エンド次元の固定位置にテレポートし、目的地に5×5の黒曜石のプラットフォームが作成されます。そのエンドポータルに入れば、オーバーワールドのスポーン地点に戻れます) +End Portal Frame=エンドポータル・フレーム +End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.=エンドポータル・フレームは、エンダーアイを入れるソケットがあり、エンドポータルの構築に使われます。 +NOTE: The End dimension is currently incomplete and might change in future versions.=注:エンド次元は現在未完成であり、将来のバージョンで変更される可能性があります。 +End Portal Frame with Eye of Ender=エンドポータル・フレーム(エンダーアイ入り) +Nether Portal=ネザーポータル +A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=ネザーポータルは、生物や物を熱くて危険なネザー次元にテレポートさせます(また戻ってくる事も可能)。入るのは自己責任で! +Stand in the portal for a moment to activate the teleportation. Entering a Nether portal for the first time will also create a new portal in the other dimension. If a Nether portal has been built in the Nether, it will lead to the Overworld. A Nether portal is destroyed if the any of the obsidian which surrounds it is destroyed, or if it was caught in an explosion.=ポータルの中でしばらく立っていると、テレポートが有効になります。初めて入った時は、異次元の方にも新たなポータルが作られます(それはオーバーワールドに通じています)。ネザーポータルは、それを囲む黒曜石のどれかが破壊されたり、爆発に巻き込まれたりすると壊れます。 +Obsidian is also used as the frame of Nether portals.=黒曜石は、ネザーポータルの枠組としても使われます。 +To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=ネザーポータルを開くには、まず黒曜石で直立した枠組を構築します(幅4ブロック以上、高さ5ブロック以上。内側は中空にして黒曜石を配置)。その後、枠の中に火をつけます。ネザーポータルは、オーバーワールドとネザーでしか使えません。 +Once placed, an eye of ender can not be taken back.=エンダーアイは、一度置くと取り戻せません。 +Used to construct end portals=エンドポータルの構築に使用 diff --git a/mods/ITEMS/mcl_portals/mod.conf b/mods/ITEMS/mcl_portals/mod.conf index 610b590c6..ab03de570 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, mcl_credits +depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn, mcl_credits, mcl_structures optional_depends = awards, doc diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index e4982c39b..8fa22e4fb 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -99,7 +99,7 @@ minetest.register_node("mcl_portals:portal_end", { groups = {portal=1, not_in_creative_inventory = 1, disable_jump = 1}, _mcl_hardness = -1, - _mcl_blast_resistance = 36000000, + _mcl_blast_resistance = 3600000, }) -- Obsidian platform at the End portal destination in the End @@ -241,7 +241,7 @@ function mcl_portals.end_portal_teleport(pos, node) end mcl_portals.end_teleport(obj, objpos) - + awards.unlock(obj:get_player_name(), "mcl:enterEndPortal") end end end diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 0d93e11d1..5f889d86f 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -1,4 +1,6 @@ -local S = minetest.get_translator(minetest.get_current_modname()) +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) local SCAN_2_MAP_CHUNKS = true -- slower but helps to find more suitable places @@ -90,6 +92,27 @@ local limits = { }, } +local function save_portal_pos(pos,target_pos) + local p1 = vector.offset(pos,-2,-1,-2) + local p2 = vector.offset(pos,2,15,2) + local nn = find_nodes_in_area(p1,p2,{"mcl_portals:portal"}) + for _,p in pairs(nn) do + minetest.get_meta(p):set_string("target_portal",minetest.hash_node_position(target_pos)) + end +end + +local function get_portal_pos(pos) + local p1 = vector.offset(pos,-5,-1,-5) + local p2 = vector.offset(pos,5,5,5) + local nn = find_nodes_in_area(p1,p2,{"mcl_portals:portal"}) + for _,p in pairs(nn) do + local m = minetest.get_meta(p):get_string("target_portal") + if m and m ~= "" and mcl_vars.get_node(p).name == "mcl_portals:portal" then + return minetest.get_position_from_hash(m) + end + end +end + -- This function registers exits from Nether portals. -- Incoming verification performed: two nodes must be portal nodes, and an obsidian below them. -- If the verification passes - position adds to the table and saves to mod storage on exit. @@ -406,6 +429,10 @@ local function finalize_teleport(obj, exit) end local _, dim = mcl_worlds.y_to_layer(exit.y) + local saved_portal = find_exit(get_portal_pos(objpos),10,10,10) + + if saved_portal then exit = saved_portal end + -- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)} @@ -421,12 +448,18 @@ local function finalize_teleport(obj, exit) teleport_cooloff(obj) -- Teleport + save_portal_pos(objpos,exit) obj:set_pos(exit) - + minetest.after(1,function() + save_portal_pos(exit,objpos) + end) if is_player then mcl_worlds.dimension_change(obj, dim) minetest.sound_play("mcl_portals_teleport", {pos=exit, gain=0.5, max_hear_distance = 16}, true) log("action", "[mcl_portals] player "..name.." teleported to Nether portal at "..pos_to_string(exit)..".") + if dim == "nether" then + awards.unlock(obj:get_player_name(), "mcl:theNether") + end else log("action", "[mcl_portals] entity teleported to Nether portal at "..pos_to_string(exit)..".") end @@ -873,3 +906,18 @@ minetest.override_item(OBSIDIAN, { end end, }) + +mcl_structures.register_structure("nether_portal",{ + nospawn = true, + filenames = { + modpath.."/schematics/mcl_portals_nether_portal.mts" + }, + after_place = function(pos,def,pr,blockseed) + end +}) +mcl_structures.register_structure("nether_portal_open",{ + nospawn = true, + filenames = { + modpath.."/schematics/mcl_portals_nether_portal_open.mts" + }, +}) diff --git a/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal.mts b/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal.mts new file mode 100644 index 000000000..b5d75cdbf Binary files /dev/null and b/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal.mts differ diff --git a/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal_open.mts b/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal_open.mts new file mode 100644 index 000000000..a1c6c79ce Binary files /dev/null and b/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal_open.mts differ diff --git a/mods/ITEMS/mcl_potions/commands.lua b/mods/ITEMS/mcl_potions/commands.lua index 1fbf591d9..76ac71e72 100644 --- a/mods/ITEMS/mcl_potions/commands.lua +++ b/mods/ITEMS/mcl_potions/commands.lua @@ -19,6 +19,7 @@ get_chat_function["water_breathing"] = mcl_potions.water_breathing_func get_chat_function["leaping"] = mcl_potions.leaping_func get_chat_function["swiftness"] = mcl_potions.swiftness_func get_chat_function["heal"] = mcl_potions.healing_func +get_chat_function["bad_omen"] = mcl_potions.bad_omen_func minetest.register_chatcommand("effect",{ params = S(" []"), diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index 2c47d50d1..de3f6df10 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -9,6 +9,7 @@ EF.leaping = {} EF.swift = {} -- for swiftness AND slowness EF.night_vision = {} EF.fire_proof = {} +EF.bad_omen = {} local EFFECT_TYPES = 0 for _,_ in pairs(EF) do @@ -41,7 +42,7 @@ local function potions_init_icons(player) text = "blank.png", position = { x = 1, y = 0 }, offset = { x = x, y = 3 }, - scale = { x = 3, y = 3 }, + scale = { x = 0.375, y = 0.375 }, alignment = { x = 1, y = 1 }, z_index = 100, }) @@ -70,7 +71,7 @@ local function potions_set_icons(player) if effect_name == nil then player:hud_change(icon, "text", "blank.png") else - player:hud_change(icon, "text", "mcl_potions_effect_"..effect_name..".png") + player:hud_change(icon, "text", "mcl_potions_effect_"..effect_name..".png^[resize:128x128") end end @@ -350,6 +351,26 @@ minetest.register_globalstep(function(dtime) end + -- Check for Bad Omen + for player, vals in pairs(EF.bad_omen) do + + is_player = player:is_player() + + EF.bad_omen[player].timer = EF.bad_omen[player].timer + dtime + + if player:get_pos() then mcl_potions._add_spawner(player, "#0b6138") end + + if EF.bad_omen[player] and EF.bad_omen[player].timer >= EF.bad_omen[player].dur then + EF.bad_omen[player] = nil + if is_player then + meta = player:get_meta() + meta:set_string("_has_bad_omen", minetest.serialize(EF.bad_omen[player])) + potions_set_hud(player) + end + end + + end + end) -- Prevent damage to player with Fire Resistance enabled @@ -375,38 +396,42 @@ end, -50) -- ███████╗╚█████╔╝██║░░██║██████╔╝██╔╝░░░██████╔╝██║░░██║░░╚██╔╝░░███████╗ -- ╚══════╝░╚════╝░╚═╝░░╚═╝╚═════╝░╚═╝░░░░╚═════╝░╚═╝░░╚═╝░░░╚═╝░░░╚══════╝ - -function mcl_potions._reset_player_effects(player, set_hud) - - if not player:is_player() then - return - end - meta = player:get_meta() - - mcl_potions.make_invisible(player, false) +function mcl_potions._clear_cached_player_data(player) EF.invisible[player] = nil EF.poisoned[player] = nil EF.regenerating[player] = nil EF.strong[player] = nil EF.weak[player] = nil EF.water_breathing[player] = nil - EF.leaping[player] = nil + EF.swift[player] = nil + EF.night_vision[player] = nil + EF.fire_proof[player] = nil + EF.bad_omen[player] = nil + + meta = player:get_meta() + meta:set_int("night_vision", 0) +end + +function mcl_potions._reset_player_effects(player, set_hud) + + if not player:is_player() then + return + end + + mcl_potions.make_invisible(player, false) + playerphysics.remove_physics_factor(player, "jump", "mcl_potions:leaping") - EF.swift[player] = nil playerphysics.remove_physics_factor(player, "speed", "mcl_potions:swiftness") - EF.night_vision[player] = nil - meta:set_int("night_vision", 0) mcl_weather.skycolor.update_sky_color({player}) - EF.fire_proof[player] = nil + mcl_potions._clear_cached_player_data(player) if set_hud ~= false then potions_set_hud(player) end - end function mcl_potions._save_player_effects(player) @@ -426,6 +451,7 @@ function mcl_potions._save_player_effects(player) meta:set_string("_is_swift", minetest.serialize(EF.swift[player])) meta:set_string("_is_cat", minetest.serialize(EF.night_vision[player])) meta:set_string("_is_fire_proof", minetest.serialize(EF.fire_proof[player])) + meta:set_string("_has_bad_omen", minetest.serialize(EF.bad_omen[player])) end @@ -477,6 +503,10 @@ function mcl_potions._load_player_effects(player) EF.fire_proof[player] = minetest.deserialize(meta:get_string("_is_fire_proof")) end + if minetest.deserialize(meta:get_string("_has_bad_omen")) then + EF.bad_omen[player] = minetest.deserialize(meta:get_string("_has_bad_omen")) + end + end -- Returns true if player has given effect @@ -487,9 +517,21 @@ function mcl_potions.player_has_effect(player, effect_name) return EF[effect_name][player] ~= nil end +function mcl_potions.player_get_effect(player, effect_name) + if not EF[effect_name] or not EF[effect_name][player] then + return false + end + return EF[effect_name][player] +end + +function mcl_potions.player_clear_effect(player,effect) + EF[effect][player] = nil + potions_set_icons(player) +end + minetest.register_on_leaveplayer( function(player) mcl_potions._save_player_effects(player) - mcl_potions._reset_player_effects(player) -- clearout the buffer to prevent looking for a player not there + mcl_potions._clear_cached_player_data(player) -- clearout the buffer to prevent looking for a player not there icon_ids[player:get_player_name()] = nil end) @@ -558,45 +600,24 @@ function mcl_potions.is_obj_hit(self, pos) end -function mcl_potions.make_invisible(player, toggle) - - if not player then - return false +function mcl_potions.make_invisible(obj_ref, hide) + if obj_ref:is_player() then + if hide then + mcl_player.player_set_visibility(obj_ref, false) + obj_ref:set_nametag_attributes({ color = { a = 0 } }) + else + mcl_player.player_set_visibility(obj_ref, true) + obj_ref:set_nametag_attributes({ color = { r = 255, g = 255, b = 255, a = 255 } }) + end + else + if hide then + local luaentity = obj_ref:get_luaentity() + EF.invisible[obj_ref].old_size = luaentity.visual_size + obj_ref:set_properties({ visual_size = { x = 0, y = 0 } }) + else + obj_ref:set_properties({ visual_size = EF.invisible[obj_ref].old_size }) + end end - - local is_player = player:is_player() - local entity = player:get_luaentity() - --local playername = player:get_player_name() - local skin_file - - if toggle then -- hide player - - skin_file = "mobs_mc_empty.png" - - if entity then - EF.invisible[player].old_size = entity.visual_size - elseif not is_player then -- if not a player or entity, do nothing - return - end - - if is_player then - mcl_player.player_set_skin(player, skin_file) - elseif not is_player then - player:set_properties({visual_size = {x = 0, y = 0}}) - end - player:set_nametag_attributes({color = {a = 0}}) - - elseif EF.invisible[player] then -- show player - - if is_player then - mcl_skins.update_player_skin(player) - elseif not is_player then - player:set_properties({visual_size = EF.invisible[player].old_size}) - end - player:set_nametag_attributes({color = {r = 255, g = 255, b = 255, a = 255}}) - - end - end @@ -984,3 +1005,18 @@ function mcl_potions._extinguish_nearby_fire(pos, radius) end return exting end + +function mcl_potions.bad_omen_func(player, factor, duration) + if not EF.bad_omen[player] then + EF.bad_omen[player] = {dur = duration, timer = 0, factor = factor} + else + local victim = EF.bad_omen[player] + victim.dur = math.max(duration, victim.dur - victim.timer) + victim.timer = 0 + victim.factor = factor + end + + if player:is_player() then + potions_set_icons(player) + end +end diff --git a/mods/ITEMS/mcl_potions/init.lua b/mods/ITEMS/mcl_potions/init.lua index 5b9f1fab3..2ea7e2879 100644 --- a/mods/ITEMS/mcl_potions/init.lua +++ b/mods/ITEMS/mcl_potions/init.lua @@ -176,6 +176,76 @@ local fill_cauldron = function(cauldron, water_type) end end +-- function to set node and empty water bottle (used for cauldrons and mud) +local function set_node_empty_bottle(itemstack, placer, pointed_thing, newitemstring) + local pname = placer:get_player_name() + if minetest.is_protected(pointed_thing.under, pname) then + minetest.record_protection_violation(pointed_thing.under, pname) + return itemstack + end + + -- set the node to `itemstring` + minetest.set_node(pointed_thing.under, {name=newitemstring}) + + -- play sound + minetest.sound_play("mcl_potions_bottle_pour", {pos=pointed_thing.under, gain=0.5, max_hear_range=16}, true) + + -- + if minetest.is_creative_enabled(placer:get_player_name()) then + return itemstack + else + return "mcl_potions:glass_bottle" + end +end + +-- used for water bottles and river water bottles +local function dispense_water_bottle(stack, pos, droppos) + local node = minetest.get_node(droppos) + if node.name == "mcl_core:dirt" or node.name == "mcl_core:coarse_dirt" then + -- convert dirt/coarse dirt to mud + minetest.set_node(droppos, {name = "mcl_mud:mud"}) + minetest.sound_play("mcl_potions_bottle_pour", {pos=droppos, gain=0.5, max_hear_range=16}, true) + return ItemStack("mcl_potions:glass_bottle") + + elseif node.name == "mcl_mud:mud" then + -- dont dispense into mud + return stack + end +end + +-- on_place function for `mcl_potions:water` and `mcl_potions:river_water` + +local function water_bottle_on_place(itemstack, placer, pointed_thing) + if pointed_thing.type == "node" then + local node = minetest.get_node(pointed_thing.under) + local def = minetest.registered_nodes[node.name] + + -- Call on_rightclick if the pointed node defines it + if placer and not placer:get_player_control().sneak then + if def and def.on_rightclick then + return def.on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + + local cauldron = nil + if itemstack:get_name() == "mcl_potions:water" then -- regular water + cauldron = fill_cauldron(node.name, "mcl_core:water_source") + elseif itemstack:get_name() == "mcl_potions:river_water" then -- river water + cauldron = fill_cauldron(node.name, "mclx_core:river_water_source") + end + + + if cauldron then + set_node_empty_bottle(itemstack, placer, pointed_thing, cauldron) + elseif node.name == "mcl_core:dirt" or node.name == "mcl_core:coarse_dirt" then + set_node_empty_bottle(itemstack, placer, pointed_thing, "mcl_mud:mud") + end + end + + -- Drink the water by default + return minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, placer, pointed_thing) +end + -- Itemstring of potions is “mcl_potions:” minetest.register_craftitem("mcl_potions:water", { @@ -187,39 +257,9 @@ minetest.register_craftitem("mcl_potions:water", { inventory_image = potion_image("#0022FF"), wield_image = potion_image("#0022FF"), groups = {brewitem=1, food=3, can_eat_when_full=1, water_bottle=1}, - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type == "node" then - local node = minetest.get_node(pointed_thing.under) - local def = minetest.registered_nodes[node.name] - - -- Call on_rightclick if the pointed node defines it - if placer and not placer:get_player_control().sneak then - if def and def.on_rightclick then - return def.on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack - end - end - - local cauldron = fill_cauldron(node.name, "mcl_core:water_source") - if cauldron then - local pname = placer:get_player_name() - if minetest.is_protected(pointed_thing.under, pname) then - minetest.record_protection_violation(pointed_thing.under, pname) - return itemstack - end - -- Increase water level of cauldron by 1 - minetest.set_node(pointed_thing.under, {name=cauldron}) - minetest.sound_play("mcl_potions_bottle_pour", {pos=pointed_thing.under, gain=0.5, max_hear_range=16}, true) - if minetest.is_creative_enabled(placer:get_player_name()) then - return itemstack - else - return "mcl_potions:glass_bottle" - end - end - end - - -- Drink the water by default - return minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, placer, pointed_thing) - end, + on_place = water_bottle_on_place, + _on_dispense = dispense_water_bottle, + _dispense_into_walkable = true, on_secondary_use = minetest.item_eat(0, "mcl_potions:glass_bottle"), }) @@ -234,39 +274,9 @@ minetest.register_craftitem("mcl_potions:river_water", { inventory_image = potion_image("#0044FF"), wield_image = potion_image("#0044FF"), groups = {brewitem=1, food=3, can_eat_when_full=1, water_bottle=1}, - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type == "node" then - local node = minetest.get_node(pointed_thing.under) - local def = minetest.registered_nodes[node.name] - - -- Call on_rightclick if the pointed node defines it - if placer and not placer:get_player_control().sneak then - if def and def.on_rightclick then - return def.on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack - end - end - - local cauldron = fill_cauldron(node.name, "mclx_core:river_water_source") - if cauldron then - local pname = placer:get_player_name() - if minetest.is_protected(pointed_thing.under, pname) then - minetest.record_protection_violation(pointed_thing.under, pname) - return itemstack - end - -- Increase water level of cauldron by 1 - minetest.set_node(pointed_thing.under, {name=cauldron}) - minetest.sound_play("mcl_potions_bottle_pour", {pos=pointed_thing.under, gain=0.5, max_hear_range=16}, true) - if minetest.is_creative_enabled(placer:get_player_name()) then - return itemstack - else - return "mcl_potions:glass_bottle" - end - end - end - - -- Drink the water by default - return minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, placer, pointed_thing) - end, + on_place = water_bottle_on_place, + _on_dispense = dispense_water_bottle, + _dispense_into_walkable = true, on_secondary_use = minetest.item_eat(0, "mcl_potions:glass_bottle"), }) diff --git a/mods/ITEMS/mcl_potions/locale/mcl_potions.ja.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.ja.tr new file mode 100644 index 000000000..89e8fc9ab --- /dev/null +++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.ja.tr @@ -0,0 +1,115 @@ +# textdomain: mcl_potions + []=<エフェクト> <デュレーション> [<ファクター>] + +Add a status effect to yourself. Arguments: : name of status effect, e.g. poison. : duration in seconds. : effect strength multiplier (1 @= 100%)=自分自身にステータス効果を付加する。引数は以下の通り。<エフェクト>: ステータス効果の名前。 <デュレーション>:継続時間(秒)。 <ファクター>: 効果の強さの倍率 (1 @= 100%)。 + +Missing effect parameter!=エフェクト のパラメータがありません! +Missing or invalid duration parameter!=デュレーション パラメータがないか、無効です! +Invalid factor parameter!=ファクター のパラメーターが無効です! +@1 is not an available status effect.=@1 は利用可能なステータス効果ではありません。 +Fermented Spider Eye=発酵したクモの目 +Glass Bottle=ガラス瓶 +Liquid container=液体用容器 + +A glass bottle is used as a container for liquids and can be used to collect water directly.=ガラス瓶は液体用の容器として使われ、直接 水を採取することができます。 + +To collect water, use it on a cauldron with water (which removes a level of water) or any water source (which removes no water).=水を集めるには、水の入った釜(水を1レベル取り除く)か、水源(水を全く取り除かない)に使用します。 + +Water Bottle=水入り瓶 +Water bottles can be used to fill cauldrons. Drinking water has no effect.=水入り瓶は大釜を満たすのに使えます。水を飲んでも効果はありません。 + +Use the “Place” key to drink. Place this item on a cauldron to pour the water into the cauldron.=飲むときは「置く」キーを使用します。このアイテムを大釜の上に置くと水を注げます。 + +River Water Bottle=河川水入り瓶 +River water bottles can be used to fill cauldrons. Drinking it has no effect.=河川水入り瓶は大釜を満たすのに使えます。飲んでも効果はありません。 + +Use the “Place” key to drink. Place this item on a cauldron to pour the river water into the cauldron.=「置く」キーで飲むことができます。このアイテムを大釜の上に置くと河川水を注げます。 + +Splash Water Bottle=水入り飛散瓶 +Extinguishes fire and hurts some mobs=火を消し、一部のモブにダメージを与える + +A throwable water bottle that will shatter on impact, where it extinguishes nearby fire and hurts mobs that are vulnerable to water.=投げられる水入り瓶で、衝撃で粉々になり、そこで近くの火を消したり、水に弱いモブにダメージを与えます。 + +Lingering Water Bottle=水入り滞留瓶 + +A throwable water bottle that will shatter on impact, where it creates a cloud of water vapor that lingers on the ground for a while. This cloud extinguishes fire and hurts mobs that are vulnerable to water.=投げられる水入り瓶で、衝撃で粉々になり、そこで水蒸気の雲を作り、しばらく地面に留まります。この雲は火を消し、水に弱いモブにダメージを与えます。 + +Glistering Melon=きらめくメロン + +This shiny melon is full of tiny gold nuggets and would be nice in an item frame. It isn't edible and not useful for anything else.=このピカピカのメロンには小さな金塊がたくさん入っていて、アイテムフレームに入れるといい感じです。食用ではないので、他の用途には使えません。 + +A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect, possibly repeatedly.=投げられるポーションで、衝撃を与えると粉々になり、魔法の雲を作り出し、しばらく周囲に留まります。雲の中にいるプレイヤーやモブはポーションの効果を繰り返し受けることができます。 + +Use the “Punch” key to throw it.=「パンチ」キーで投げます。 +Use the “Place” key to drink it.=「置く」キーで飲めます。 +Drinking a potion gives you a particular effect.=ポーションを飲むと、特定の効果が得られます。 +1 HP/@1s | @2=1 HP/@1s | @2 +@1 HP=@1 HP +@1 Potion=ポーション(@1) +Splash @1 Potion=飛散ポーション(@1) +Lingering @1 Potion=滞留ポーション(@1) +Arrow of @1=@1 の矢 + II= II + IV= IV +@1 Potion@2=ポーション(@1@2) +Splash @1@2 Potion=飛散ポーション(@1@2) +Lingering @1@2 Potion=滞留ポーション(@1@2) +Arrow of @1@2=@1@2 の矢 +@1 + Potion=ポーション(@1 +) +Splash @1 + Potion=飛散ポーション(@1 +) +Lingering @1 + Potion=滞留ポーション(@1 +) +Arrow of @1 +=@1 の矢 + +Awkward Potion=奇妙なポーション +Awkward Splash Potion=奇妙な飛散ポーション +Awkward Lingering Potion=奇妙な滞留ポーション +Has an awkward taste and is used for brewing potions.=味に癖があり、ポーションの醸造に使用されます。 +Mundane Potion=平凡なポーション +Mundane Splash Potion=平凡な飛散ポーション +Mundane Lingering Potion=平凡な滞留ポーション +Has a terrible taste and is not useful for brewing potions.=味は最悪で、ポーションの醸造には使えません。 +Thick Potion=濃厚なポーション +Thick Splash Potion=濃厚な飛散ポーション +Thick Lingering Potion=濃厚な滞留ポーション +Has a bitter taste and is not useful for brewing potions.=苦味があり、ポーションの醸造には使えません。 +Dragon's Breath=ドラゴンブレス + +This item is used in brewing and can be combined with splash potions to create lingering potions.=醸造に使用するアイテムで、飛散ポーションと組み合わせて滞留ポーションが作れます。 + +Healing=治癒 ++4 HP=+4 HP ++8 HP=+8 HP +Instantly heals.=即座に治癒します。 +Harming=負傷 +-6 HP=-6 HP +-12 HP=-12 HP +Instantly deals damage.=即座にダメージを与えます。 +Night Vision=暗視 +Increases the perceived brightness of light under a dark sky.=暗い空の下で、光の明るさを感じやすくします。 +Swiftness=加速 +Increases walking speed.=歩行速度が上がります。 +Slowness=減速 +Decreases walking speed.=歩行速度が下がります。 +Leaping=跳躍 +Increases jump strength.=ジャンプ力を高めます。 +Poison=毒薬 +Applies the poison effect which deals damage at a regular interval.=一定間隔でダメージを与える毒効果を及ぼします。 +Regeneration=再生 +Regenerates health over time.=時間経過でヘルスを回復します。 +Invisibility=透過 +Grants invisibility.=不可視性を付与します。 +Water Breathing=吸気 +Grants limitless breath underwater.=水中で無限の呼吸を付与します。 +Fire Resistance=耐火 +Grants immunity to damage from heat sources like fire.=火などの熱源から受けるダメージに対する免疫力を付与します。 +Weakness=弱化 +Weakness +=弱化 + +Strength=剛力 +Strength II=剛力 II +Strength +=剛力 + +Try different combinations to create potions.=いろいろな組み合わせを試して、ポーションを作ってみましょう。 +No effect=効果なし + +A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.=投げられるポーションで、衝撃で粉々になり、近くのプレイヤーやモブにステータス効果を与えます。 + +This particular arrow is tipped and will give an effect when it hits a player or mob.=この矢は先端が尖っており、プレイヤーやモブに当たると効果を発揮します。 + diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_bad_omen.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_bad_omen.png new file mode 100644 index 000000000..dfe8f0332 Binary files /dev/null and b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_bad_omen.png differ diff --git a/mods/ITEMS/mcl_potions/tipped_arrow.lua b/mods/ITEMS/mcl_potions/tipped_arrow.lua index e6da04dff..53a37705e 100644 --- a/mods/ITEMS/mcl_potions/tipped_arrow.lua +++ b/mods/ITEMS/mcl_potions/tipped_arrow.lua @@ -30,6 +30,7 @@ local how_to_shoot = minetest.registered_items["mcl_bows:arrow"]._doc_items_usag local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") local mod_button = minetest.get_modpath("mesecons_button") +local enable_pvp = minetest.settings:get_bool("enable_pvp") local arrow_longdesc = minetest.registered_items["mcl_bows:arrow"]._doc_items_longdesc or "" local arrow_tt = minetest.registered_items["mcl_bows:arrow"]._tt_help or "" @@ -210,29 +211,34 @@ function mcl_potions.register_arrow(name, desc, color, def) end -- Iterate through all objects and remember the closest attackable object - for k, obj in pairs(objs) do - local ok = false - -- Arrows can only damage players and mobs - if obj ~= self._shooter and obj:is_player() then - ok = true - elseif obj:get_luaentity() then - if obj ~= self._shooter and obj:get_luaentity().is_mob then + local arrow_dir = self.object:get_velocity() + --create a raycast from the arrow based on the velocity of the arrow to deal with lag + local raycast = minetest.raycast(pos, vector.add(pos, vector.multiply(arrow_dir, 0.1)), true, false) + for hitpoint in raycast do + if hitpoint.type == "object" then + -- find the closest object that is in the way of the arrow + local ok = false + if hitpoint.ref:is_player() and enable_pvp then ok = true + elseif not hitpoint.ref:is_player() and hitpoint.ref:get_luaentity() then + if (hitpoint.ref:get_luaentity().is_mob or hitpoint.ref:get_luaentity()._hittable_by_projectile) then + ok = true + end end - end - - if ok then - local dist = vector.distance(pos, obj:get_pos()) - if not closest_object or not closest_distance then - closest_object = obj - closest_distance = dist - elseif dist < closest_distance then - closest_object = obj - closest_distance = dist + if ok then + local dist = vector.distance(hitpoint.ref:get_pos(), pos) + if not closest_object or not closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + elseif dist < closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + end end end end + -- If an attackable object was found, we will damage the closest one only if closest_object then local obj = closest_object @@ -278,7 +284,7 @@ function mcl_potions.register_arrow(name, desc, color, def) if is_player then if self._shooter and self._shooter:is_player() then -- “Ding” sound for hitting another player - minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter}, true) + minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter:get_player_name()}, true) end end diff --git a/mods/ITEMS/mcl_raw_ores/init.lua b/mods/ITEMS/mcl_raw_ores/init.lua index 12ca8d222..be570068f 100644 --- a/mods/ITEMS/mcl_raw_ores/init.lua +++ b/mods/ITEMS/mcl_raw_ores/init.lua @@ -1,49 +1,58 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + local function register_raw_ore(description, n) - local ore = description:lower() - local n = n or "" - local raw_ingot = "mcl_raw_ores:raw_"..ore - local texture = "mcl_raw_ores_raw_"..ore + local ore = description:lower() + local n = n or "" + local raw_ingot = "mcl_raw_ores:raw_"..ore + local texture = "mcl_raw_ores_raw_"..ore - minetest.register_craftitem(raw_ingot, { - description = ("Raw "..description), - _doc_items_longdesc = ("Raw "..ore..". Mine a"..n.." "..ore.." ore to get it."), + minetest.register_craftitem(raw_ingot, { + description = S("Raw "..description), + _doc_items_longdesc = S("Raw "..ore..". Mine a"..n.." "..ore.." ore to get it."), inventory_image = texture..".png", - groups = { craftitem = 1 }, - }) + groups = { craftitem = 1, blast_furnace_smeltable = 1 }, + }) - minetest.register_node(raw_ingot.."_block", { - description = ("Block of Raw "..description), - _doc_items_longdesc = ("A block of raw "..ore.." is mostly a decorative block but also useful as a compact storage of raw "..ore.."."), - tiles = { texture.."_block.png" }, - is_ground_content = false, - groups = { pickaxey = 2, building_block = 1 }, - sounds = mcl_sounds.node_sound_metal_defaults(), - _mcl_blast_resistance = 6, - _mcl_hardness = 5, - }) + minetest.register_node(raw_ingot.."_block", { + description = S("Block of Raw "..description), + _doc_items_longdesc = S("A block of raw "..ore.." is mostly a decorative block but also useful as a compact storage of raw "..ore.."."), + tiles = { texture.."_block.png" }, + is_ground_content = false, + groups = { pickaxey = 2, building_block = 1, blast_furnace_smeltable = 1 }, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + }) - minetest.register_craft({ - output = raw_ingot.."_block", - recipe = { - { raw_ingot, raw_ingot, raw_ingot }, - { raw_ingot, raw_ingot, raw_ingot }, - { raw_ingot, raw_ingot, raw_ingot }, - }, - }) + minetest.register_craft({ + output = raw_ingot.."_block", + recipe = { + { raw_ingot, raw_ingot, raw_ingot }, + { raw_ingot, raw_ingot, raw_ingot }, + { raw_ingot, raw_ingot, raw_ingot }, + }, + }) - minetest.register_craft({ - type = "cooking", - output = "mcl_core:"..ore.."_ingot", - recipe = raw_ingot, - cooktime = 10, - }) + minetest.register_craft({ + type = "cooking", + output = "mcl_core:"..ore.."_ingot", + recipe = raw_ingot, + cooktime = 10, + }) - minetest.register_craft({ - output = raw_ingot.." 9", - recipe = { - { raw_ingot.."_block" }, - }, - }) + minetest.register_craft({ + type = "cooking", + output = "mcl_core:"..ore.."block", + recipe = raw_ingot.."_block", + cooktime = 90, + }) + + minetest.register_craft({ + output = raw_ingot.." 9", + recipe = { + { raw_ingot.."_block" }, + }, + }) end register_raw_ore("Iron", "n") diff --git a/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.fr.tr b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.fr.tr new file mode 100644 index 000000000..bf9c08c4e --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.fr.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_raw_ores +Raw Iron=Fer Brut +Raw Gold=Or Brut +Raw Iron. Mine an Iron ore to get it.=Fer Brut. Miner du minerai de fer pour en obtenir. +Raw Gold. Mine a Gold ore to get it.=Or Brut. Miner du minerai d'or pour en obtenir. +Block of Raw Iron=Bloc de Fer Brut +Block of Raw Gold=Bloc d'Or Brut +A block of raw Iron is mostly a decorative block but also useful as a compact storage of raw Iron.=Un bloc de Fer brut est principalement un bloc décoratif mais aussi utile comme stockage compact de Fer brut. +A block of raw Gold is mostly a decorative block but also useful as a compact storage of raw Gold.=Un bloc d'Or brut est principalement un bloc décoratif mais aussi utile comme stockage compact d'Or brut. \ No newline at end of file diff --git a/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ja.tr b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ja.tr new file mode 100644 index 000000000..9be029657 --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ja.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_raw_ores +Raw Iron=鉄の粗鉱 +Raw Gold=金の粗鉱 +Raw Iron. Mine an Iron ore to get it.=未処理の鉄。鉄鉱石を採掘して入手します。 +Raw Gold. Mine a Gold ore to get it.=未処理の金。金鉱石を採掘して入手します。 +Block of Raw Iron=鉄の粗鉱ブロック +Block of Raw Gold=金の粗鉱ブロック +A block of raw Iron is mostly a decorative block but also useful as a compact storage of raw Iron.=鉄の粗鉱ブロックは、主に装飾用のブロックですが、鉄の粗鉱をコンパクトに収納するのにも便利です。 +A block of raw Gold is mostly a decorative block but also useful as a compact storage of raw Gold.=金の粗鉱ブロックは、主に装飾用のブロックですが、金の粗鉱をコンパクトに収納するのにも便利です。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_raw_ores/locale/template.txt b/mods/ITEMS/mcl_raw_ores/locale/template.txt new file mode 100644 index 000000000..c9913e5c9 --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/template.txt @@ -0,0 +1,9 @@ +# textdomain: mcl_raw_ores +Raw Iron= +Raw Gold= +Raw Iron. Mine an Iron ore to get it.= +Raw Gold. Mine a Gold ore to get it.= +Block of Raw Iron= +Block of Raw Gold= +A block of raw Iron is mostly a decorative block but also useful as a compact storage of raw Iron.= +A block of raw Gold is mostly a decorative block but also useful as a compact storage of raw Gold.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_sculk/init.lua b/mods/ITEMS/mcl_sculk/init.lua new file mode 100644 index 000000000..765a01051 --- /dev/null +++ b/mods/ITEMS/mcl_sculk/init.lua @@ -0,0 +1,267 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +local mt_sound_play = minetest.sound_play + +local spread_to = {"mcl_core:stone","mcl_core:dirt","mcl_core:sand","mcl_core:dirt_with_grass","group:grass_block","mcl_core:andesite","mcl_core:diorite","mcl_core:granite","mcl_core:mycelium","group:dirt","mcl_end:end_stone","mcl_nether:netherrack","mcl_blackstone:basalt","mcl_nether:soul_sand","mcl_blackstone:soul_soil","mcl_crimson:warped_nylium","mcl_crimson:crimson_nylium","mcl_core:gravel"} + +local sounds = { + footstep = {name = "mcl_sculk_block", }, + dug = {name = "mcl_sculk_block", }, +} + +local SPREAD_RANGE = 8 +local SENSOR_RANGE = 8 +local SENSOR_DELAY = 0.5 +local SHRIEKER_COOLDOWN = 10 + +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,1,0), + vector.new(0,-1,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +--[[ +local function sensor_action(p,tp) + local s = minetest.find_node_near(p,SPREAD_RANGE,{"mcl_sculk:shrieker"}) + local n = minetest.get_node(s) + if s and n.param2 ~= 1 then + minetest.sound_play("mcl_sculk_shrieker", {pos=s, gain=1.5, max_hear_distance = 16}, true) + n.param2 = 1 + minetest.set_node(s,n) + minetest.after(SHRIEKER_COOLDOWN,function(s) + minetest.set_node(s,{name = "mcl_sculk:shrieker",param2=0}) + end,s) + end + --local p1 = vector.offset(p,-SENSOR_RANGE,-SENSOR_RANGE,-SENSOR_RANGE) + --local p2 = vector.offset(p,SENSOR_RANGE,SENSOR_RANGE,SENSOR_RANGE) + --darken_area(p1,p2) +end + +function minetest.sound_play(spec, parameters, ephemeral) + local rt = mt_sound_play(spec, parameters, ephemeral) + if parameters.pos then + pos = parameters.pos + elseif parameters.to_player then + pos = minetest.get_player_by_name(parameters.to_player):get_pos() + end + if not pos then return rt end + local s = minetest.find_node_near(pos,SPREAD_RANGE,{"mcl_sculk:sensor"}) + if s then + --minetest.after(SENSOR_DELAY,sensor_action,s,pos) + end + return rt +end + +walkover.register_global(function(pos, node, player) + local s = minetest.find_node_near(pos,SPREAD_RANGE,{"mcl_sculk:sensor"}) + if not s then return end + local v = player:get_velocity() + if v.x == 0 and v.y == 0 and v.z == 0 then return end + if player:get_player_control().sneak then return end + local def = minetest.registered_nodes[node.name] + if def and def.sounds then + minetest.log("walkover "..node.name) + minetest.after(SENSOR_DELAY,sensor_action,s,pos) + end +end) +--]] + +local function get_node_xp(pos) + local meta = minetest.get_meta(pos) + return meta:get_int("xp") +end +local function set_node_xp(pos,xp) + local meta = minetest.get_meta(pos) + return meta:set_int("xp",xp) +end + +local function sculk_on_destruct(pos) + local xp = get_node_xp(pos) + local n = minetest.get_node(pos) + if n.param2 == 1 then + xp = 1 + end + local obs = mcl_experience.throw_xp(pos,xp) + for _,v in pairs(obs) do + local l = v:get_luaentity() + l._sculkdrop = true + end +end + +local function has_air(pos) + for _,v in pairs(adjacents) do + if minetest.get_item_group(minetest.get_node(vector.add(pos,v)).name,"solid") <= 0 then return true end + end +end + +local function has_nonsculk(pos) + for _,v in pairs(adjacents) do + local p = vector.add(pos,v) + if minetest.get_item_group(minetest.get_node(p).name,"sculk") <= 0 and minetest.get_item_group(minetest.get_node(p).name,"solid") > 0 then return p end + end +end + +local old_on_step = minetest.registered_entities["mcl_experience:orb"].on_step + +minetest.registered_entities["mcl_experience:orb"].on_step = function(self,dtime) + local p = self.object:get_pos() + local nu = minetest.get_node(vector.offset(p,0,-1,0)) + local ret = old_on_step(self,dtime) + if not self._sculkdrop then + local c = minetest.find_node_near(p,SPREAD_RANGE,{"mcl_sculk:catalyst"}) + if c then + local nnn = minetest.find_nodes_in_area(vector.offset(p,-SPREAD_RANGE,-SPREAD_RANGE,-SPREAD_RANGE),vector.offset(p,SPREAD_RANGE,SPREAD_RANGE,SPREAD_RANGE),spread_to) + local nn={} + for _,v in pairs(nnn) do + if has_air(v) then + table.insert(nn,v) + end + end + table.sort(nn,function(a, b) + return vector.distance(p, a) < vector.distance(p, b) + end) + if nn and #nn > 0 and self._xp > 0 then + local d = math.random(100) + --[[ --enable to generate shriekers and sensors + if d <= 1 then + minetest.set_node(nn[1],{name = "mcl_sculk:shrieker"}) + set_node_xp(nn[1],math.min(1,self._xp - 10)) + self.object:remove() + return ret + elseif d <= 9 then + minetest.set_node(nn[1],{name = "mcl_sculk:sensor"}) + set_node_xp(nn[1],math.min(1,self._xp - 5)) + self.object:remove() + return ret + else --]] + local r = math.min(math.random(#nn),self._xp) + for i=1,r do + minetest.set_node(nn[i],{name = "mcl_sculk:sculk" }) + set_node_xp(nn[i],math.floor(self._xp / r)) + end + for i=1,r do + local p = has_nonsculk(nn[i]) + if p and has_air(p) then + minetest.set_node(vector.offset(p,0,1,0),{name = "mcl_sculk:vein", param2 = 1}) + end + end + set_node_xp(nn[1],get_node_xp(nn[1]) + self._xp % r) + self.object:remove() + return ret + --end + end + end + end + return ret +end + +minetest.register_node("mcl_sculk:sculk", { + description = S("Sculk"), + tiles = { + { name = "mcl_sculk_sculk.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 3.0, + }, }, + }, + drop = "", + groups = {handy = 1, hoey = 1, building_block=1, sculk = 1,}, + place_param2 = 1, + sounds = sounds, + is_ground_content = false, + on_destruct = sculk_on_destruct, + _mcl_blast_resistance = 0.2, + _mcl_hardness = 0.6, + _mcl_silk_touch_drop = true, +}) + +minetest.register_node("mcl_sculk:vein", { + description = S("Sculk Vein"), + _doc_items_longdesc = S("Sculk vein."), + drawtype = "signlike", + tiles = {"mcl_sculk_vein.png"}, + inventory_image = "mcl_sculk_vein.png", + wield_image = "mcl_sculk_vein.png", + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "wallmounted", + walkable = false, + climbable = true, + buildable_to = true, + selection_box = { + type = "wallmounted", + }, + groups = { + handy = 1, axey = 1, shearsy = 1, swordy = 1, deco_block = 1, + dig_by_piston = 1, destroy_by_lava_flow = 1, sculk = 1, dig_by_water = 1, + }, + sounds = sounds, + drop = "", + _mcl_shears_drop = true, + node_placement_prediction = "", + _mcl_blast_resistance = 0.2, + _mcl_hardness = 0.2, + on_rotate = false, +}) + +minetest.register_node("mcl_sculk:catalyst", { + description = S("Sculk Catalyst"), + tiles = { + "mcl_sculk_catalyst_top.png", + "mcl_sculk_catalyst_bottom.png", + "mcl_sculk_catalyst_side.png" + }, + drop = "", + sounds = sounds, + groups = {handy = 1, hoey = 1, building_block=1, sculk = 1,}, + place_param2 = 1, + is_ground_content = false, + on_destruct = sculk_on_destruct, + _mcl_blast_resistance = 3, + light_source = 6, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, +}) + +--[[ +minetest.register_node("mcl_sculk:sensor", { + description = S("Sculk Sensor"), + tiles = { + "mcl_sculk_sensor_top.png", + "mcl_sculk_sensor_bottom.png", + "mcl_sculk_sensor_side.png" + }, + drop = "", + sounds = sounds, + groups = {handy = 1, hoey = 1, building_block=1, sculk = 1,}, + place_param2 = 1, + is_ground_content = false, + on_destruct = sculk_on_destruct, + _mcl_blast_resistance = 3, + light_source = 6, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, +}) +minetest.register_node("mcl_sculk:shrieker", { + description = S("Sculk Shrieker"), + tiles = { + "mcl_sculk_shrieker_top.png", + "mcl_sculk_shrieker_bottom.png", + "mcl_sculk_shrieker_side.png" + }, + drop = "", + sounds = sounds, + groups = {handy = 1, hoey = 1, building_block=1, sculk = 1,}, + place_param2 = 0, + is_ground_content = false, + on_destruct = sculk_on_destruct, + _mcl_blast_resistance = 3, + light_source = 6, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, +}) +--]] diff --git a/mods/ITEMS/mcl_sculk/mod.conf b/mods/ITEMS/mcl_sculk/mod.conf new file mode 100644 index 000000000..e9fc71e9a --- /dev/null +++ b/mods/ITEMS/mcl_sculk/mod.conf @@ -0,0 +1,3 @@ +name = mcl_sculk +author = cora +depends = mcl_core, mcl_sounds, mcl_experience, walkover diff --git a/mods/ITEMS/mcl_sculk/sounds/mcl_sculk.ogg b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk.ogg new file mode 100644 index 000000000..ca211128d Binary files /dev/null and b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk.ogg differ diff --git a/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_2.ogg b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_2.ogg new file mode 100644 index 000000000..352342880 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_2.ogg differ diff --git a/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_block.ogg b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_block.ogg new file mode 100644 index 000000000..e71425d4b Binary files /dev/null and b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_block.ogg differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_bottom.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_bottom.png new file mode 100644 index 000000000..1e50bfaae Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_bottom.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_side.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_side.png new file mode 100644 index 000000000..1a4edb6ed Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_side.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_top.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_top.png new file mode 100644 index 000000000..f3b4ebb95 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_catalyst_top.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sculk.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sculk.png new file mode 100644 index 000000000..75edbae9a Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sculk.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_bottom.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_bottom.png new file mode 100644 index 000000000..e1f5e9242 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_bottom.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_side.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_side.png new file mode 100644 index 000000000..1041bf367 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_side.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_top.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_top.png new file mode 100644 index 000000000..3bdb0e7f5 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_sensor_top.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_bottom.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_bottom.png new file mode 100644 index 000000000..e1f5e9242 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_bottom.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_side.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_side.png new file mode 100644 index 000000000..b5a176dd6 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_side.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_top.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_top.png new file mode 100644 index 000000000..6bd98fb53 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_shrieker_top.png differ diff --git a/mods/ITEMS/mcl_sculk/textures/mcl_sculk_vein.png b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_vein.png new file mode 100644 index 000000000..53d62f70b Binary files /dev/null and b/mods/ITEMS/mcl_sculk/textures/mcl_sculk_vein.png differ diff --git a/mods/ITEMS/mcl_shields/init.lua b/mods/ITEMS/mcl_shields/init.lua index 038ffc0f3..3ad2ada51 100644 --- a/mods/ITEMS/mcl_shields/init.lua +++ b/mods/ITEMS/mcl_shields/init.lua @@ -31,12 +31,12 @@ minetest.register_tool("mcl_shields:shield", { 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), + _mcl_wieldview_item = "", }) local function wielded_item(obj, i) @@ -219,12 +219,11 @@ 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 + if not shield_hud[player] then return end --this function takes a long time. only run it when necessary + player:hud_remove(shield_hud[player]) + shield_hud[player] = nil + set_shield(player, false, 1) + set_shield(player, false, 2) local hf = player:hud_get_flags() if not hf.wielditem then @@ -275,9 +274,16 @@ local function handle_blocking(player) 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)) + local pointed_thing = mcl_util.get_pointed_thing(player, true) + local offhand_can_block = (wielded_item(player) == "" or not pointed_thing) and (minetest.get_item_group(wielded_item(player), "bow") ~= 1 and minetest.get_item_group(wielded_item(player), "crossbow") ~= 1) + if pointed_thing and pointed_thing.type == "node" then + if minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "container") > 1 then + return + end + end + if not offhand_can_block then return end @@ -432,7 +438,6 @@ for _, colortab in pairs(mcl_banners.colors) do shield = 1, weapon = 1, enchantability = -1, - no_wieldview = 1, not_in_creative_inventory = 1, offhand_item = 1, }, @@ -440,6 +445,7 @@ for _, colortab in pairs(mcl_banners.colors) do _repair_material = "group:wood", wield_scale = vector.new(2, 2, 2), _shield_color = colortab[4], + _mcl_wieldview_item = "", }) local banner = "mcl_banners:banner_item_" .. color diff --git a/mods/ITEMS/mcl_shields/locale/mcl_shields.fr.tr b/mods/ITEMS/mcl_shields/locale/mcl_shields.fr.tr new file mode 100644 index 000000000..fb4b5fd70 --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/mcl_shields.fr.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_shields +Shield=Bouclier +A shield is a tool used for protecting the player against attacks.=Un bouclier est un outil utilisé pour protéger le joueur contre les attaques. +White Shield=Bouclier Blanc +Grey Shield=Bouclier Gris +Light Grey Shield=Bouclier Gris Clair +Black Shield=Bouclier Noir +Red Shield=Bouclier Rouge +Yellow Shield=Bouclier Jaune +Green Shield=Bouclier Vert +Cyan Shield=Bouclier Cyan +Blue Shield=Bouclier Bleu +Magenta Shield=Bouclier Magenta +Orange Shield=Bouclier Orange +Purple Shield=Bouclier Pourpre +Brown Shield=Bouclier Marron +Pink Shield=Bouclier Rose +Lime Shield=Bouclier Vert Clair +Light Blue Shield=Bouclier Bleu Clair \ No newline at end of file diff --git a/mods/ITEMS/mcl_shields/locale/mcl_shields.ja.tr b/mods/ITEMS/mcl_shields/locale/mcl_shields.ja.tr new file mode 100644 index 000000000..794139e38 --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/mcl_shields.ja.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_shields +Shield=盾 +A shield is a tool used for protecting the player against attacks.=盾は、攻撃からプレイヤーを守るために使う道具です。 +White Shield=盾(白色) +Grey Shield=盾(灰色) +Light Grey Shield=盾(薄灰色) +Black Shield=盾(黒色) +Red Shield=盾(赤色) +Yellow Shield=盾(黄色) +Green Shield=盾(緑色) +Cyan Shield=盾(青緑色) +Blue Shield=盾(青色) +Magenta Shield=盾(赤紫色) +Orange Shield=盾(橙色) +Purple Shield=盾(紫色) +Brown Shield=盾(茶色) +Pink Shield=盾(桃色) +Lime Shield=盾(黄緑色) +Light Blue Shield=盾(空色) diff --git a/mods/ITEMS/mcl_shields/textures/mcl_shield_hud.png b/mods/ITEMS/mcl_shields/textures/mcl_shield_hud.png index 4286d3e83..f4d0b080f 100644 Binary files a/mods/ITEMS/mcl_shields/textures/mcl_shield_hud.png and b/mods/ITEMS/mcl_shields/textures/mcl_shield_hud.png differ diff --git a/mods/ITEMS/mcl_signs/README.txt b/mods/ITEMS/mcl_signs/README.txt index ee161fc95..e4fbead8a 100644 --- a/mods/ITEMS/mcl_signs/README.txt +++ b/mods/ITEMS/mcl_signs/README.txt @@ -1,4 +1,21 @@ -Mod based on reworked signs mod by PilzAdam: + +--- +# Mineclone2-Signs +--- +A reworking of MineClone 2's mcl_signs to be colorable and made to glow. Requires Minetest and Mineclone2. +--- + +Created by Michieal (FaerRaven) @ DateTime: 10/14/22 4:05 PM + + +Reworked to be an API and to allow players to color, and/or make the lettering for the signs glow (be bright at night). +Reworked by Michieal (FaerRaven), including the sign textures batch changed to be white instead of the original black. + +A special thanks to Cora for pointing me in the right direction (as always). + + +The original Mod, MCL_SIGNS is based on reworked signs mod by PilzAdam: + https://forum.minetest.net/viewtopic.php?t=3289 License of code and font: MIT License @@ -6,8 +23,22 @@ License of code and font: MIT License Font source: 04.jp.org, some modifications and additions were made (added support for Latin-1 Supplement) Original font license text states: “YOU MAY USE THEM AS YOU LIKE” (in about.gif file distributed with the font) -License of textures: See README.md in top directory of MineClone 2. +License of textures: See README.md in top directory of MineClone 2, with the exception of the following: +default_sign.png, default_sign_dark.png, default_sign_greyscale.png, mcl_signs_sign_dark.png, +mcl_signs_sign_greyscale.png are licensed as follows: +Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) (https://creativecommons.org/licenses/by-sa/4.0/). +Credit Michieal (Faerraven). The extra sign textures are provided for you to use, modify, etc., with the goal being to +make the game better. (All of these textures were changed / created by me, to make them usable / better.) License of models: GPLv3 (https://www.gnu.org/licenses/gpl-3.0.html) + Models author: 22i. + Source: https://github.com/22i/amc + +Mineclone 2 source code: +https://git.minetest.land/MineClone2/MineClone2 + +--- +NOTE: This MODule requires Glow Squids in order for all features to work 100% correctly. Glow Squids are currently +in review by the MineClone 2 Team, and should be available soon after this initial release of the new signs. \ No newline at end of file diff --git a/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt b/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt new file mode 100644 index 000000000..e98741137 --- /dev/null +++ b/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt @@ -0,0 +1,122 @@ +--- +--- Generated by EmmyLua. +--- Created by Michieal (FaerRaven). +--- DateTime: 10/22/22 3:44 PM +--- + +SIGNS API + +--- How to Use: + +The simplest way to create a new sign is to use mcl_signs.register_sign [mcl_signs.register_sign (modname, color, _name, +ttsign)]. It's an all-in-one sign creator. It makes use of the standard textures for the signs, and colors them based on +the color code that you give it, and names it "mcl_signs:wall_sign" + _name. So, using the spruce sign to illustrate, it +would be named "mcl_signs:wall_sign_sprucewood", as we made _name equal to "_sprucewood" after the name of the +registered wood. + +To create a sign with specific textures: use the mcl_signs.register_sign_custom [mcl_signs.register_sign_custom +(modname, _name, tiles, color, inventory_image, wield_image, ttsign)]. Like the register_sign() function, this is also an +all-in-one sign creation function. With this function you can designate what textures to use, and give them a specified +color. This function follows the same naming conventions. + +If you wish to override / recreate one of the predefined signs, you may also do that. The reregister_sign() and +reregister_sign_custom() functions will replace an existing sign's definition with a new one. Caution, ONLY use this on +existing signs. If the sign doesn't exist, use the regular register_sign* functions. + +--- What the parameters mean, and what they do: + +* modname: optional (pass "" or "false" to ignore), for using mcl_signs with other mods to allow the creation of a sign +from the mod's wood (if installed). Use this to prevent failures of the specific mod is not installed that has the needed +information (textures, wood, etc.) Setting this is important, because it prevents items from being registered if the +mod in not installed. + +* tiles: the texture file to use for the sign's node. + +* color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, and just use the +texture as is. + +* inventory_image: the texture file to use for the sign's display in inventory. + +* wield_image: the texture file to use for the sign's weilded (in hand) object. + +* _name: the sign's name suffix, such as "_dark" or "_sprucewood", etc., appended to "wall_sign" or "standing_sign" + +* ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. ttsign stands +for translated tooltip sign. + +* wood_item_string: example: "mcl_core:wood", "mcl_core:sprucewood" or "mymod:mywood". This is used when defining the +recipe for the sign. + +--- Other Functions of Importance: + +* register_dye [mcl_signs.register_dye (modname, item_name, color_code)] -- this registers a new dye that the sign knows +about so that the player can color their signs with the dye. +Parameters: + modname: your mod / module's name. make sure to use this for compatibility. + item_name: the item_string of the dye to register. + color_code: the hex code for the color to make the lettering. Also called HTML color code. Ex. "#FFFFFF" is white. + +* register_sign_craft [mcl_signs.register_sign_craft(modname, wood_item_string, _name)] -- this is what creates the +recipes for the sign, and makes the sign "burnable". Typically called right after the register_sign* functions. +Parameters: + _name: MUST be the same name as used for the sign. So, if your sign _name is "_sprucewood" then this should be too. + wood_item_string: the item_string of the wood to use for the sign's recipe. Example: "mcl_core:wood" (default oak). + modname: like with the other functions that has this parameter, used to make sure that nothing breaks. + +* make_lbm() [mcl_signs.make_lbm()] -- This innocuous function is very important. This is the function that makes the +signs work after reloading the game. This function is the last to be called in your sign creation work flow. Note, you +do not need to call this function after every definition, just at the end of the last definition. +(See Example WorkFlow below.) + +--- Example Workflow for sign creation. + +* these are, at the time of writing, a selection of the actual signs' definitions. Note the functions called, and when. + +-- ---------------------------- -- +-- Register Signs for use. -- +-- ---------------------------- -- + +-- sprucewood Sign +mcl_signs.register_sign_custom("mcl_core", "_sprucewood", + "mcl_signs_sign_dark.png","#ffffff", "default_sign_dark.png", + "default_sign_dark.png", "Spruce Sign" +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:sprucewood", "_sprucewood") + +-- darkwood Sign +mcl_signs.register_sign_custom("mcl_core", "_darkwood", + "mcl_signs_sign_greyscale.png","#856443", "default_sign_greyscale.png", + "default_sign_greyscale.png", "Dark Oak Sign" +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:darkwood", "_darkwood") + +-- acaciawood Sign +mcl_signs.register_sign("mcl_core", "#ea7479", "_acaciawood", "Acacia Sign") +mcl_signs.register_sign_craft("mcl_core", "mcl_core:acaciawood", "_acaciawood") + +-- junglewood Sign +mcl_signs.register_sign("mcl_core", "#866249", "_junglewood", "Jungle Sign") +mcl_signs.register_sign_craft("mcl_core", "mcl_core:junglewood", "_junglewood") + +-- Register the LBMs for the created signs. +mcl_signs.make_lbm() + +--- ----------------------------------------------------------------------------- + +* If you wish to use a recipe other than the standard sign recipe, you will need to define your own recipe. In doing so, +use this output line: + output = "mcl_signs:wall_sign" .. _name .. " 3", +where _name is the same string that you have used throughout your sign's workflow. That way, when players make the recipe, +they get your sign (x3). + +--- Future landmarks on the horizon for the Signs API: + +* Once the forthcoming Hanging Signs are in Minecraft, and we implement the code for them in here, hanging signs will +automatically exist as part of the signs' package. You won't have to change any of your code, it'll just be more +functional. :) + +* if you have suggestions, comments, etc., please contact me on MineClone 2's Discord server. + +And that... is all there is to it! + +-- written by Michieal. \ No newline at end of file diff --git a/mods/ITEMS/mcl_signs/init.lua b/mods/ITEMS/mcl_signs/init.lua index b6bfb3fe8..e724def68 100644 --- a/mods/ITEMS/mcl_signs/init.lua +++ b/mods/ITEMS/mcl_signs/init.lua @@ -1,580 +1,158 @@ +--- +--- Generated by EmmyLua. +--- Created by Michieal (FaerRaven). +--- DateTime: 10/14/22 4:05 PM +--- + local modname = minetest.get_current_modname() local modpath = minetest.get_modpath(modname) + +-- Signs API +dofile(modpath .. "/signs_api.lua") + +-- LOCALIZATION 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: -Line 1: The literal UTF-8 encoded character -Line 2: Name of the texture file for this character minus the “.png” suffix; found in the “textures/” sub-directory -Line 3: Currently ignored. Previously this was for the character width in pixels - -After line 3, another info block may follow. This repeats until the end of the file. - -All character files must be 5 or 6 pixels wide (5 pixels are preferred) -]] - -local chars_file = io.open(modpath.."/characters.txt", "r") --- FIXME: Support more characters (many characters are missing). Currently ASCII and Latin-1 Supplement are supported. -local charmap = {} -if not chars_file then - minetest.log("error", "[mcl_signs] : character map file not found") -else - while true do - local char = chars_file:read("*l") - if char == nil then - break - end - local img = chars_file:read("*l") - chars_file:read("*l") - charmap[char] = img - end -end - --- CONSTANTS -local SIGN_WIDTH = 115 - -local LINE_LENGTH = 15 -local NUMBER_OF_LINES = 4 - -local LINE_HEIGHT = 14 -local CHAR_WIDTH = 5 - - --- Helper functions -local function round(num, idp) - local mult = 10^(idp or 0) - return math.floor(num * mult + 0.5) / mult -end - -local function string_to_array(str) - local tab = {} - for i=1,string.len(str) do - table.insert(tab, string.sub(str, i,i)) - end - return tab -end - -local function string_to_line_array(str) - local tab = {} - local current = 1 - local linechar = 1 - tab[1] = "" - for _,char in ipairs(string_to_array(str)) do - -- New line - if char == "\n" then - current = current + 1 - tab[current] = "" - linechar = 1 - else - tab[current] = tab[current]..char - linechar = linechar + 1 - end - end - return tab -end - -local function create_lines(text) - local line_num = 1 - local tab = {} - for _, line in ipairs(string_to_line_array(text)) do - if line_num > NUMBER_OF_LINES then - break - end - table.insert(tab, line) - line_num = line_num + 1 - end - return tab -end - -local function generate_line(s, ypos) - local i = 1 - local parsed = {} - local width = 0 - local chars = 0 - local printed_char_width = CHAR_WIDTH + 1 - while chars < LINE_LENGTH and i <= #s do - local file - -- Get and render character - if charmap[s:sub(i, i)] then - file = charmap[s:sub(i, i)] - i = i + 1 - elseif i < #s and charmap[s:sub(i, i + 1)] then - file = charmap[s:sub(i, i + 1)] - i = i + 2 - else - -- No character image found. - -- Use replacement character: - file = "_rc" - i = i + 1 - minetest.log("verbose", "[mcl_signs] Unknown symbol in '"..s.."' at "..i) - end - if file then - width = width + printed_char_width - table.insert(parsed, file) - chars = chars + 1 - end - end - width = width - 1 - - local texture = "" - local xpos = math.floor((SIGN_WIDTH - width) / 2) - for i = 1, #parsed do - texture = texture..":"..xpos..","..ypos.."="..parsed[i]..".png" - xpos = xpos + printed_char_width - end - return texture -end - -local function generate_texture(lines, signnodename) - local texture = "[combine:"..SIGN_WIDTH.."x"..SIGN_WIDTH - local ypos - if signnodename == "mcl_signs:wall_sign" then - ypos = 30 - else - ypos = 0 - end - for i = 1, #lines do - texture = texture..generate_line(lines[i], ypos) - ypos = ypos + LINE_HEIGHT - end - return texture -end - -local n = 23/56 - 1/128 - -local signtext_info_wall = { - {delta = {x = 0, y = 0, z = n}, yaw = 0}, - {delta = {x = n, y = 0, z = 0}, yaw = math.pi / -2}, - {delta = {x = 0, y = 0, z = -n}, yaw = math.pi}, - {delta = {x = -n, y = 0, z = 0}, yaw = math.pi / 2}, -} - -local signtext_info_standing = {} - -local m = -1/16 + 1/64 - -for rot=0, 15 do - local yaw = math.pi*2 - (((math.pi*2) / 16) * rot) - local delta = vector.multiply(minetest.yaw_to_dir(yaw), m) - -- Offset because sign is a bit above node boundaries - delta.y = delta.y + 2/28 - table.insert(signtext_info_standing, { delta = delta, yaw = yaw }) -end - -local function get_rotation_level(facedir, nodename) - local rl = facedir * 4 - if nodename == "mcl_signs:standing_sign22_5" then - rl = rl + 1 - elseif nodename == "mcl_signs:standing_sign45" then - rl = rl + 2 - elseif nodename == "mcl_signs:standing_sign67_5" then - rl = rl + 3 - end - return rl -end - -local function get_wall_signtext_info(param2, nodename) - local dir = minetest.wallmounted_to_dir(param2) - if dir.x > 0 then - return 2 - elseif dir.z > 0 then - return 1 - elseif dir.x < 0 then - return 4 - else - return 3 - end -end - -local sign_groups = {handy=1,axey=1, deco_block=1, material_wood=1, attached_node=1, dig_by_piston=1, flammable=-1} - -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() - if ent and ent.name == "mcl_signs:text" then - v:remove() - end - end - local players = minetest.get_connected_players() - for p=1, #players do - if vector.distance(players[p]:get_pos(), pos) <= 30 then - minetest.close_formspec(players[p]:get_player_name(), "mcl_signs:set_text_"..pos.x.."_"..pos.y.."_"..pos.z) - end - end -end - -local function update_sign(pos, fields, sender, force_remove) - local meta = minetest.get_meta(pos) - if not meta then - return - end - local text = meta:get_string("text") - if fields and (text == "" and fields.text) then - meta:set_string("text", fields.text) - text = fields.text - end - if text == nil then - text = "" - end - - local sign_info - local n = minetest.get_node(pos) - local nn = n.name - if nn == "mcl_signs:standing_sign" or nn == "mcl_signs:standing_sign22_5" or nn == "mcl_signs:standing_sign45" or nn == "mcl_signs:standing_sign67_5" then - sign_info = signtext_info_standing[get_rotation_level(n.param2, nn) + 1] - elseif nn == "mcl_signs:wall_sign" then - sign_info = signtext_info_wall[get_wall_signtext_info(n.param2)] - end - if sign_info == nil then - minetest.log("error", "[mcl_signs] Missing sign_info!") - return - end - - local objects = minetest.get_objects_inside_radius(pos, 0.5) - local text_entity - for _, v in ipairs(objects) do - local ent = v:get_luaentity() - if ent and ent.name == "mcl_signs:text" then - if force_remove then - v:remove() - else - text_entity = v - break - end - end - end - - if not text_entity then - text_entity = minetest.add_entity({ - x = pos.x + sign_info.delta.x, - y = pos.y + sign_info.delta.y, - z = pos.z + sign_info.delta.z}, "mcl_signs:text") - end - text_entity:get_luaentity()._signnodename = nn - text_entity:set_properties({textures={generate_texture(create_lines(text), nn)}}) - - text_entity:set_yaw(sign_info.yaw) -end - -local function show_formspec(player, pos) - minetest.show_formspec( - player:get_player_name(), - "mcl_signs:set_text_"..pos.x.."_"..pos.y.."_"..pos.z, - "size[6,3]textarea[0.25,0.25;6,1.5;text;"..F(S("Enter sign text:"))..";]label[0,1.5;"..F(S("Maximum line length: 15")).."\n"..F(S("Maximum lines: 4")).."]button_exit[0,2.5;6,1;submit;"..F(S("Done")).."]" - ) -end +-- HANDLE THE FORMSPEC CALLBACK minetest.register_on_player_receive_fields(function(player, formname, fields) - if formname:find("mcl_signs:set_text_") == 1 then - local x, y, z = formname:match("mcl_signs:set_text_(.-)_(.-)_(.*)") - local pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)} - if not pos or not pos.x or not pos.y or not pos.z then return end - update_sign(pos, fields, player) - end + if formname:find("mcl_signs:set_text_") == 1 then + local x, y, z = formname:match("mcl_signs:set_text_(.-)_(.-)_(.*)") + local pos = { x = tonumber(x), y = tonumber(y), z = tonumber(z) } + if not pos or not pos.x or not pos.y or not pos.z then + return + end + mcl_signs:update_sign(pos, fields, player) + end end) -local node_sounds -if minetest.get_modpath("mcl_sounds") then - node_sounds = mcl_sounds.node_sound_wood_defaults() -end - -minetest.register_node("mcl_signs:wall_sign", { - description = S("Sign"), - _tt_help = S("Can be written"), - _doc_items_longdesc = S("Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them."), - _doc_items_usagehelp = S("After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again."), - inventory_image = "default_sign.png", - walkable = false, - is_ground_content = false, - wield_image = "default_sign.png", - node_placement_prediction = "", - paramtype = "light", - sunlight_propagates = true, - paramtype2 = "wallmounted", - drawtype = "mesh", - mesh = "mcl_signs_signonwallmount.obj", - selection_box = {type = "wallmounted", wall_side = {-0.5, -7/28, -0.5, -23/56, 7/28, 0.5}}, - tiles = {"mcl_signs_sign.png"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - groups = sign_groups, - stack_max = 16, - sounds = node_sounds, - - on_place = function(itemstack, placer, pointed_thing) - local above = pointed_thing.above - local under = pointed_thing.under - - -- Use pointed node's on_rightclick function first, if present - local node_under = minetest.get_node(under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then - return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack - end - end - - local dir = vector.subtract(under, above) - - -- Only build when it's legal - local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] - if not abovenodedef or abovenodedef.buildable_to == false then - return itemstack - end - - local wdir = minetest.dir_to_wallmounted(dir) - - --local placer_pos = placer:get_pos() - - local fdir = minetest.dir_to_facedir(dir) - - local sign_info - local nodeitem = ItemStack(itemstack) - -- Ceiling - if wdir == 0 then - --how would you add sign to ceiling? - return itemstack - -- Floor - elseif wdir == 1 then - -- Standing sign - - -- Determine the sign rotation based on player's yaw - local yaw = math.pi*2 - placer:get_look_horizontal() - - -- Select one of 16 possible rotations (0-15) - local rotation_level = round((yaw / (math.pi*2)) * 16) - - if rotation_level > 15 then - rotation_level = 0 - elseif rotation_level < 0 then - rotation_level = 15 - end - - -- The actual rotation is a combination of predefined mesh and facedir (see node definition) - if rotation_level % 4 == 0 then - nodeitem:set_name("mcl_signs:standing_sign") - elseif rotation_level % 4 == 1 then - nodeitem:set_name("mcl_signs:standing_sign22_5") - elseif rotation_level % 4 == 2 then - nodeitem:set_name("mcl_signs:standing_sign45") - elseif rotation_level % 4 == 3 then - nodeitem:set_name("mcl_signs:standing_sign67_5") - end - fdir = math.floor(rotation_level / 4) - - -- Place the node! - local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) - if not success then - return itemstack - end - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - sign_info = signtext_info_standing[rotation_level + 1] - -- Side - else - -- Wall sign - local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) - if not success then - return itemstack - end - sign_info = signtext_info_wall[fdir + 1] - end - - -- Determine spawn position of entity - local place_pos - if minetest.registered_nodes[node_under.name].buildable_to then - place_pos = under - else - place_pos = above - end - - local text_entity = minetest.add_entity({ - x = place_pos.x + sign_info.delta.x, - y = place_pos.y + sign_info.delta.y, - z = place_pos.z + sign_info.delta.z}, "mcl_signs:text") - text_entity:set_yaw(sign_info.yaw) - text_entity:get_luaentity()._signnodename = nodeitem:get_name() - - minetest.sound_play({name="default_place_node_hard", gain=1.0}, {pos = place_pos}, true) - - show_formspec(placer, place_pos) - return itemstack - end, - on_destruct = destruct_sign, - on_punch = function(pos, node, puncher) - update_sign(pos) - end, - on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - local r = screwdriver.rotate.wallmounted(pos, node, mode) - node.param2 = r - minetest.swap_node(pos, node) - update_sign(pos, nil, nil, true) - return true - else - return false - end - end, - _mcl_hardness = 1, - _mcl_blast_resistance = 1, -}) - --- Standing sign nodes. --- 4 rotations at 0°, 22.5°, 45° and 67.5°. --- These are 4 out of 16 possible rotations. --- With facedir the remaining 12 rotations are constructed. - --- 0° -local ssign = { - paramtype = "light", - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - sunlight_propagates = true, - walkable = false, - is_ground_content = false, - paramtype2 = "facedir", - drawtype = "mesh", - mesh = "mcl_signs_sign.obj", - selection_box = {type = "fixed", fixed = {-0.2, -0.5, -0.2, 0.2, 0.5, 0.2}}, - tiles = {"mcl_signs_sign.png"}, - groups = sign_groups, - drop = "mcl_signs:wall_sign", - stack_max = 16, - sounds = node_sounds, - - on_destruct = destruct_sign, - on_punch = function(pos, node, puncher) - update_sign(pos) - end, - on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign22_5" - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - update_sign(pos, nil, nil, true) - return true - end, - - _mcl_hardness = 1, - _mcl_blast_resistance = 1, -} - -minetest.register_node("mcl_signs:standing_sign", ssign) - --- 22.5° -local ssign22_5 = table.copy(ssign) -ssign22_5.mesh = "mcl_signs_sign22.5.obj" -ssign22_5.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign45" - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - update_sign(pos, nil, nil, true) - return true -end -minetest.register_node("mcl_signs:standing_sign22_5", ssign22_5) - --- 45° -local ssign45 = table.copy(ssign) -ssign45.mesh = "mcl_signs_sign45.obj" -ssign45.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign67_5" - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - update_sign(pos, nil, nil, true) - return true -end -minetest.register_node("mcl_signs:standing_sign45", ssign45) - --- 67.5° -local ssign67_5 = table.copy(ssign) -ssign67_5.mesh = "mcl_signs_sign67.5.obj" -ssign67_5.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign" - node.param2 = (node.param2 + 1) % 4 - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - update_sign(pos, nil, nil, true) - return true -end -minetest.register_node("mcl_signs:standing_sign67_5", ssign67_5) - +-- This defines the text entity for the lettering of the sign. -- FIXME: Prevent entity destruction by /clearobjects minetest.register_entity("mcl_signs:text", { - pointable = false, - visual = "upright_sprite", - textures = {}, - physical = false, - collide_with_objects = false, + pointable = false, + visual = "upright_sprite", + textures = {}, + physical = false, + collide_with_objects = false, - _signnodename = nil, -- node name of sign node to which the text belongs + _signnodename = nil, -- node name of sign node to which the text belongs - on_activate = function(self, staticdata) - if staticdata and staticdata ~= "" then - local des = minetest.deserialize(staticdata) - if des then - self._signnodename = des._signnodename - end - end - local meta = minetest.get_meta(self.object:get_pos()) - local text = meta:get_string("text") - self.object:set_properties({ - textures={generate_texture(create_lines(text), self._signnodename)}, - }) - self.object:set_armor_groups({ immortal = 1 }) - end, - get_staticdata = function(self) - local out = { _signnodename = self._signnodename } - return minetest.serialize(out) - end, + on_activate = function(self, staticdata) + + local meta = minetest.get_meta(self.object:get_pos()) + local text = meta:get_string("text") + local text_color = meta:get_string("mcl_signs:text_color") + local glowing_sign = meta:get_string("mcl_signs:glowing_sign") + if staticdata and staticdata ~= "" then + local des = minetest.deserialize(staticdata) + if des then + self._signnodename = des._signnodename + if des._text_color ~= nil and des._text_color ~= "" then + self.text_color = des._text_color + end + if des._glowing_sign ~= nil and des._glowing_sign ~= "" then + self.glowing_sign = des._glowing_sign + end + end + end + + if text_color == "" or text_color == nil then + text_color = "#000000" -- default to black text. + meta:set_string("mcl_signs:text_color", text_color) + end + + if glowing_sign == "" or glowing_sign == nil then + glowing_sign = "false" -- default to not glowing. + meta:set_string("mcl_signs:glowing_sign", glowing_sign) + end + + self.object:set_properties({ + textures = { mcl_signs:create_lettering(text, self._signnodename, text_color) }, + }) + if glowing_sign == "true" then + self.object:set_properties({ + glow = 6, --sign_glow, + }) + end + + self.object:set_armor_groups({ immortal = 1 }) + + end, + get_staticdata = function(self) + local out = { + _signnodename = self._signnodename, + } + return minetest.serialize(out) + end, }) -minetest.register_craft({ - type = "fuel", - recipe = "mcl_signs:wall_sign", - burntime = 10, -}) +-- Build the signs x,y,z & rotations so that they work. (IE, do not remove!) +mcl_signs.build_signs_info() -if minetest.get_modpath("mcl_core") then - minetest.register_craft({ - output = "mcl_signs:wall_sign 3", - recipe = { - {"group:wood", "group:wood", "group:wood"}, - {"group:wood", "group:wood", "group:wood"}, - {"", "mcl_core:stick", ""}, - } - }) +-- ---------------------------- -- +-- Register Signs for use. -- +-- ---------------------------- -- + +-- Standard (original) Sign +mcl_signs.register_sign("mcl_core", "#ffffff", "", "Sign") +mcl_signs.register_sign_craft("mcl_core", "mcl_core:wood", "") + +-- birchwood Sign "#d5cb8d" / "#ffdba7" +mcl_signs.register_sign_custom("mcl_core", "_birchwood", + "mcl_signs_sign_greyscale.png","#ffdba7", "default_sign_greyscale.png", + "default_sign_greyscale.png", "Birch Sign" +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:birchwood", "_birchwood") + +-- sprucewood Sign +mcl_signs.register_sign_custom("mcl_core", "_sprucewood", + "mcl_signs_sign_dark.png","#ffffff", "default_sign_dark.png", + "default_sign_dark.png", "Spruce Sign" +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:sprucewood", "_sprucewood") + +-- darkwood Sign "#291f1a" / "#856443" +mcl_signs.register_sign_custom("mcl_core", "_darkwood", + "mcl_signs_sign_greyscale.png","#856443", "default_sign_greyscale.png", + "default_sign_greyscale.png", "Dark Oak Sign" +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:darkwood", "_darkwood") + +-- junglewood Sign +mcl_signs.register_sign("mcl_core", "#866249", "_junglewood", "Jungle Sign") +mcl_signs.register_sign_craft("mcl_core", "mcl_core:junglewood", "_junglewood") + +-- acaciawood Sign "b8693d" +mcl_signs.register_sign("mcl_core", "#ea7479", "_acaciawood", "Acacia Sign") +mcl_signs.register_sign_craft("mcl_core", "mcl_core:acaciawood", "_acaciawood") + +if minetest.get_modpath("mcl_mangrove") then + -- mangrove_wood Sign "#c7545c" + mcl_signs.register_sign("mcl_mangrove", "#b8693d", "_mangrove_wood", "Mangrove Sign") + mcl_signs.register_sign_craft("mcl_mangrove", "mcl_mangrove:mangrove_wood", "_mangrove_wood") end -if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign") - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5") - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45") - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5") +-- add in the nether wood signs +if minetest.get_modpath("mcl_crimson") then + + -- warped_hyphae_wood Sign + mcl_signs.register_sign_custom("mcl_crimson","_warped_hyphae_wood", "mcl_signs_sign_greyscale.png", + "#9f7dcf", "default_sign_greyscale.png", "default_sign_greyscale.png", + "Warped Hyphae Sign") + mcl_signs.register_sign_craft("mcl_crimson", "mcl_crimson:warped_hyphae_wood", "_warped_hyphae_wood") + + -- crimson_hyphae_wood Sign + mcl_signs.register_sign_custom("mcl_crimson", "_crimson_hyphae_wood","mcl_signs_sign_greyscale.png", + "#c35f51","default_sign_greyscale.png", "default_sign_greyscale.png", + "Crimson Hyphae Sign") + mcl_signs.register_sign_craft("mcl_crimson", "mcl_crimson:crimson_hyphae_wood", "_crimson_hyphae_wood") + end +-- Register the LBMs for the created signs. +mcl_signs.make_lbm() + +-- really ancient compatibility. minetest.register_alias("signs:sign_wall", "mcl_signs:wall_sign") minetest.register_alias("signs:sign_yard", "mcl_signs:standing_sign") - -minetest.register_lbm({ - name = "mcl_signs:respawn_entities", - label = "Respawn sign text entities", - run_at_every_load = true, - nodenames = { "mcl_signs:wall_sign", "mcl_signs:standing_sign", "mcl_signs:standing_sign22_5", "mcl_signs:standing_sign45", "mcl_signs:standing_sign67_5" }, - action = function(pos, node) - update_sign(pos) - end, -}) +minetest.register_alias("mcl_signs:wall_sign_dark", "mcl_signs:wall_sign_sprucewood") +minetest.register_alias("mcl_signs:standing_sign_dark", "mcl_signs:standing_sign_sprucewood") diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.de.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.de.tr index a7513659b..323e90364 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.de.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.de.tr @@ -1,9 +1,18 @@ # textdomain: mcl_signs -Sign=Schild +Sign=Zeichen / Schild Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=Schilder können beschrieben werden und kommen in zwei Varianten: Wandschild und stehendes Schild. Sie können auf und an den Seiten von anderen Blöclen platziert werden, aber nicht unter ihnen. -After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again.=Nachdem das Schild platziert wurde, kann man etwas darauf schreiben. 4 Zeilen mit je 15 Zeichen pro Zeile sind verfügbar, alles darüber geht verloren. Es werden nicht alle Zeichen unterstützt. Der Text kann nicht geändert werden, sobald er geschrieben wurde; man muss das Schild erneut platzieren. +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=Nachdem das Schild platziert wurde, kann man etwas darauf schreiben. 4 Zeilen mit je 15 Zeichen pro Zeile sind verfügbar, alles darüber geht verloren. Es werden nicht alle Zeichen unterstützt. Der Text kann nicht geändert werden, sobald er geschrieben wurde; man muss das Schild erneut platzieren. Kann gefärbt und zum Leuchten gebracht werden. Enter sign text:=Schildtext eingeben: Maximum line length: 15=Maximale Zeilenlänge: 15 Maximum lines: 4=Maximale Zeilen: 4 Done=Fertig Can be written=Kann beschriftet werden +Oak Sign=Eichezeichen +Birch Sign=Birke Zeichen +Spruce Sign=Fichtenzeichen +Dark Oak Sign=Dunkles Eichenschild +Jungle Sign=Dschungelzeichen +Acacia Sign=Akazienzeichen +Mangrove Sign=Mangroven-Zeichen +Warped Hyphae Sign=Verzerrtes Hyphen-Zeichen +Crimson Hyphae Sign=Hochrotes Hyphen-Zeichen diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.es.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.es.tr index d67e2da0d..87f737935 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.es.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.es.tr @@ -1,8 +1,18 @@ # textdomain: mcl_signs -Sign=Firmar +Sign=Signo / Firmar Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=Los letreros se pueden escribir y vienen en dos variantes: letrero de muro y letrero en un poste de letrero. Los letreros se pueden colocar en la parte superior y en los costados de otros bloques, pero no debajo de ellos. -After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again.=Después de colocar el letrero, puede escribir algo en él. Tiene 4 líneas de texto con hasta 15 caracteres para cada línea; todo lo que esté más allá de estos límites se pierde. No todos los personajes son compatibles. El texto no se puede cambiar una vez que se ha escrito; tienes que romper y colocar el letrero nuevamente. +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=Después de colocar el letrero, puede escribir algo en él. Tiene 4 líneas de texto con hasta 15 caracteres para cada línea; todo lo que esté más allá de estos límites se pierde. No todos los personajes son compatibles. El texto no se puede cambiar una vez que se ha escrito; tienes que romper y colocar el letrero nuevamente. Enter sign text:=Inserte el texto del letrero: Maximum line length: 15=Longitud máxima de línea: 15 Maximum lines: 4=Líneas máximas: 4 +Can be written=Los letreros se pueden escribir Done=Escribir cartel +Oak Sign=Signo de roble +Birch Sign=Signo de abedul +Spruce Sign=Signo de abeto +Dark Oak Sign=Signo de roble oscuro +Jungle Sign= Signo de la selva +Acacia Sign= Signo de acacia +Mangrove Sign= Signo de manglar +Warped Hyphae Sign=Signo de hifas deformadas +Crimson Hyphae Sign=Signo de hifas carmesí diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.fr.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.fr.tr index 158640dae..0cc571e70 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.fr.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.fr.tr @@ -1,9 +1,18 @@ # textdomain: mcl_signs -Sign=Panneau +Sign=Panneau / signe Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=Les panneaux peuvent être écrits et se déclinent en deux variantes: panneau mural et panneau sur poteau. Des panneaux peuvent être placés en haut et sur les côtés des autres blocs, mais pas en dessous. -After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again.=Après avoir placé le panneau, vous pouvez écrire quelque chose dessus. Vous avez 4 lignes de texte avec jusqu'à 15 caractères pour chaque ligne; tout ce qui dépasse ces limites est perdu. Tous les caractères ne sont pas pris en charge. Le texte ne peut pas être modifié une fois qu'il a été écrit; vous devez casser et placer à nouveau le panneau. +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=Après avoir placé le panneau, vous pouvez écrire quelque chose dessus. Vous avez 4 lignes de texte avec jusqu'à 15 caractères pour chaque ligne; tout ce qui dépasse ces limites est perdu. Tous les caractères ne sont pas pris en charge. Le texte ne peut pas être modifié une fois qu'il a été écrit; vous devez casser et placer à nouveau le panneau. Peut être coloré et rendu brillant. Enter sign text:=Saisir le texte du panneau: Maximum line length: 15=Longueur maximum des lignes: 15 Maximum lines: 4=Nombre maximum de lignes: 4 Done=Terminé Can be written=Peut être écrit +Oak Sign=Signe de chêne +Birch Sign=Signe de bouleau +Spruce Sign=Signe d'épinette +Dark Oak Sign=Enseigne Chêne Foncé +Jungle Sign=Signe de la jungle +Acacia Sign=Signe d'acacia +Mangrove Sign=Signe de la mangrove +Warped Hyphae Sign=Signe hyphe déformé +Crimson Hyphae Sign=Signe d'hyphes cramoisi \ No newline at end of file diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.ja.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.ja.tr new file mode 100644 index 000000000..c6b4032c3 --- /dev/null +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.ja.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_signs +Sign=看板 +Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=看板は書くことができ、2つのバリエーションがあります(壁かけ看板と立て看板)。看板の設置は、他のブロックの上部と側面にできますが、下部にはできません。 +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=看板を設置した後、そこに何かを書き込めます。文字数は、1行あたり15文字で4行まで、それ以上は失われます。すべての文字がサポートされているわけではありません。一度書いた文字は変更できません(変えるには看板を壊して再配置)。着色や発光が可能です。 +Enter sign text:=看板の文字を入力: +Maximum line length: 15=1行あたりの最大文字数:15 +Maximum lines: 4=最大行数:4 +Done=完了 +Can be written=書き込み可能 +Oak Sign=オークの看板 +Birch Sign=シラカバの看板 +Spruce Sign=トウヒの看板 +Dark Oak Sign=ダークオークの看板 +Jungle Sign=ジャングルの看板 +Acacia Sign=アカシアの看板 +Mangrove Sign=マングローブの看板 diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.pl.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.pl.tr index bf3bbf3c8..b9fbcd1bf 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.pl.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.pl.tr @@ -1,9 +1,18 @@ # textdomain: mcl_signs Sign=Znak Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=Na znakach można pisać i postawić je w dwóch wariantach: znak ścienny i znak na patyku. Znaki mogą być stawiane na górze i na bokach bloków, ale nie pod nimi. -After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again.=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. +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=Po postawieniu znaku możesz coś na nim napisać. Masz miejsce na cztery linie tekstu po 15 znaków każda; cokolwiek poza limitami będzie utracone. Nie wszystkie znaki są wspierane. Tekstu nie można zmienić po napisaniu; musisz zniszczyć znak i postawić go ponownie. Może być pokolorowany i rozświetlony. Enter sign text:=Wpisz tekst znaku: Maximum line length: 15=Maksymalna długość linii: 15 Maximum lines: 4=Maksymalna liczba linii: 4 Done=Skończone Can be written=Można na nim coś napisać +Oak Sign=Znak dębu +Birch Sign=Brzoza Znak +Spruce Sign=Świerk Znak +Dark Oak Sign=Znak ciemnego dębu +Jungle Sign=Znak Dżungli +Acacia Sign=Znak akacji +Mangrove Sign=Znak namorzynowy +Warped Hyphae Sign=Wypaczony znak strzępek +Crimson Hyphae Sign=Karmazynowy znak strzępek diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr index 354e556a8..279bde614 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr @@ -1,9 +1,18 @@ # textdomain: mcl_signs Sign=Табличка Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=На табличках можно писать. Таблички бывают двух видов: настенные и отдельно стоящие. Таблички можно размещать на верхушках и сторонах блоков, но не под блоками. -After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again.=После установки таблички вы можете написать на ней что-то. Вам доступны 4 строки текста, до 15 символов в каждой; всё, что вы напишете сверх лимита, потеряется. Поддерживаются не все символы. Текст нельзя изменить. Чтобы изменить его, вам придётся сломать табличку и подписать её снова. +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=После установки таблички вы можете написать на ней что-то. Вам доступны 4 строки текста, до 15 символов в каждой; всё, что вы напишете сверх лимита, потеряется. Поддерживаются не все символы. Текст нельзя изменить. Чтобы изменить его, вам придётся сломать табличку и подписать её снова. Можно раскрасить и заставить светиться. Enter sign text:=Текст на табличке: Maximum line length: 15=Максимальная длина строки: 15 Maximum lines: 4=Максимум строк: 4 Done=Готово Can be written=Может быть подписана +Oak Sign=Дубовый знак +Birch Sign=Березовый знак +Spruce Sign=Ель Знак +Dark Oak Sign=Знак темного дуба +Jungle Sign=Знак джунглей +Acacia Sign=Знак акации +Mangrove Sign=Знак мангровых зарослей +Warped Hyphae Sign=Знак искривленных гиф +Crimson Hyphae Sign=Багровый знак гиф diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.zh_TW.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.zh_TW.tr index 62994bc3d..d2cabe04e 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.zh_TW.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.zh_TW.tr @@ -1,9 +1,16 @@ # textdomain: mcl_signs Sign=告示牌 Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=告示牌可以寫字,有兩種變體:牆上的告示牌和柱上的告示牌。告示牌可以放在其他方塊的頂部和側面,但不能放在下面。 -After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again.=放置告示牌後,你可以在上面寫東西。你最多可以寫4行文字,每行最多可以寫15個字符;超過這些限制的文字就會丟失。不是所有的字符都被支持。文字一旦寫完就不能更改;你必須打破並重新放置標誌。 +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=放置告示牌後,你可以在上面寫東西。你最多可以寫4行文字,每行最多可以寫15個字符;超過這些限制的文字就會丟失。不是所有的字符都被支持。文字一旦寫完就不能更改;你必須打破並重新放置標誌。可以著色並發光。 Enter sign text:=輸入告示牌文字: Maximum line length: 15=每行最多可以寫15個字符 Maximum lines: 4=最多可以寫4行文字 Done=確認 Can be written=可以寫字 +Oak Sign=橡木標誌 +Birch Sign=樺木標誌 +Spruce Sign=雲杉標誌 +Dark Oak Sign=深色橡木標誌 +Jungle Sign=叢林標誌 +Acacia Sign=相思標誌 +Mangrove Sign=紅樹林標誌 diff --git a/mods/ITEMS/mcl_signs/locale/template.txt b/mods/ITEMS/mcl_signs/locale/template.txt index 6635e989f..137cc44cd 100644 --- a/mods/ITEMS/mcl_signs/locale/template.txt +++ b/mods/ITEMS/mcl_signs/locale/template.txt @@ -1,9 +1,16 @@ # textdomain: mcl_signs Sign= Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.= -After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again.= +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.= Enter sign text:= Maximum line length: 15= Maximum lines: 4= Done= Can be written= +Oak Sign= +Birch Sign= +Spruce Sign= +Dark Oak Sign= +Jungle Sign= +Acacia Sign= +Mangrove Sign= diff --git a/mods/ITEMS/mcl_signs/mod.conf b/mods/ITEMS/mcl_signs/mod.conf index 1af689d7b..ada0ae58a 100644 --- a/mods/ITEMS/mcl_signs/mod.conf +++ b/mods/ITEMS/mcl_signs/mod.conf @@ -1,2 +1,4 @@ name = mcl_signs -optional_depends = mcl_sounds, mcl_core, doc +description = New and Improved signs - can be colored and made to glow. +depends = mcl_core, mcl_sounds, mcl_dye, mcl_colors +optional_depends = doc diff --git a/mods/ITEMS/mcl_signs/signs_api.lua b/mods/ITEMS/mcl_signs/signs_api.lua new file mode 100644 index 000000000..1f7369ba3 --- /dev/null +++ b/mods/ITEMS/mcl_signs/signs_api.lua @@ -0,0 +1,2003 @@ +--- +--- Generated by EmmyLua. +--- Created by Michieal (FaerRaven). +--- DateTime: 10/14/22 4:05 PM +--- + +--local logging = minetest.settings:get_bool("mcl_logging_mcl_signs",true) + +local DEBUG = minetest.settings:get_bool("mcl_logging_mcl_signs", false) -- special debug setting. + +if DEBUG then + minetest.log("action", "[mcl_signs] Signs API Loading") +end + +-- LOCALIZATION +local S = minetest.get_translator("mcl_signs") +-- Signs form +local F = minetest.formspec_escape + +-- PATHs +local modpath = minetest.get_modpath("mcl_signs") + +-- CONSTANTS +local SIGN_WIDTH = 115 + +local LINE_LENGTH = 15 +local NUMBER_OF_LINES = 4 + +local LINE_HEIGHT = 14 +local CHAR_WIDTH = 5 +local TIMER_INTERVAL = 40.0 +-- ----------------------- +-- CACHE LOCAL COPIES +local table = table +local string = string + +-- CACHE NODE_SOUNDS +local node_sounds +if minetest.get_modpath("mcl_sounds") then + node_sounds = mcl_sounds.node_sound_wood_defaults() +end + +-- SET UP THE CHARACTER MAPPING +-- Load the characters map (characters.txt) +--[[ File format of characters.txt: +It's an UTF-8 encoded text file that contains metadata for all supported characters. It contains a sequence of info + blocks, one for each character. Each info block is made out of 3 lines: +Line 1: The literal UTF-8 encoded character +Line 2: Name of the texture file for this character minus the “.png” suffix; found in the “textures/” sub-directory +Line 3: Currently ignored. Previously this was for the character width in pixels + +After line 3, another info block may follow. This repeats until the end of the file. + +All character files must be 5 or 6 pixels wide (5 pixels are preferred) +]] + +local chars_file = io.open(modpath .. "/characters.txt", "r") +-- FIXME: Support more characters (many characters are missing). Currently ASCII and Latin-1 Supplement are supported. +local charmap = {} +if not chars_file then + minetest.log("error", "[mcl_signs] : character map file not found") +else + while true do + local char = chars_file:read("*l") + if char == nil then + break + end + local img = chars_file:read("*l") + chars_file:read("*l") + charmap[char] = img + end +end + +local pi = 3.1415926 -- enough accuracy, to build an engine for a car. + +local math = math + +-- locally cached copy of the official colors; this way, it updates as mcl_colors updates. +local mcl_colors_official = mcl_colors +if DEBUG then + minetest.log("verbose", "[mcl_signs]Official MCL_Colors:\n" .. dump(mcl_colors_official)) +end + +-- INITIALIZE THE GLOBAL API FOR SIGNS. +mcl_signs = {} + +-- GLOBALS +mcl_signs.sign_groups = { handy = 1, axey = 1, deco_block = 1, material_wood = 1, attached_node = 1, dig_by_piston = 1, flammable = -1 } +--- colors used for wools. +mcl_signs.mcl_wool_colors = { + unicolor_white = "#FFFFFF", + unicolor_dark_orange = "#502A00", + unicolor_grey = "#5B5B5B", + unicolor_darkgrey = "#303030", + unicolor_blue = "#0000CC", + unicolor_dark_green = "#005000", + unicolor_green_or_lime = "#50CC00", + unicolor_violet_purple = "#5000CC", + unicolor_light_red_pink = "#FF5050", + unicolor_yellow = "#CCCC00", + unicolor_orange = "#CC5000", + unicolor_red = "#CC0000", + unicolor_cyan = "#00CCCC", + unicolor_red_violet_magenta = "#CC0050", + unicolor_black = "#000000", + unicolor_light_blue = "#5050FF", +} +mcl_signs.signtext_info_wall = {} +mcl_signs.signtext_info_standing = {} -- built in build_signs_info(). +-- the rotational levels for all of the standing signs. +mcl_signs.standing_rotation_levels = {} + +-- data structure block for dynamically registered signs. +mcl_signs.registered_signs = {} +mcl_signs.registered_signs.wall_signs = {} +mcl_signs.registered_signs.standing_signs = {} +mcl_signs.registered_signs.hanging_signs = {} -- unused. prepping for future use. +-- DEFINE SIGN BASE TYPES +mcl_signs.wall_standard = {} -- initialize +mcl_signs.standing_standard = {} -- initialize + +function mcl_signs.build_signs_info() + local n = 23 / 56 - 1 / 128 -- some required magic number from the original code. + local m = -1 / 16 + 1 / 64 -- " " " " " " " " + + mcl_signs.signtext_info_wall = { + { delta = { x = 0, y = 0, z = n }, yaw = 0 }, + { delta = { x = n, y = 0, z = 0 }, yaw = pi / -2 }, + { delta = { x = 0, y = 0, z = -n }, yaw = pi }, + { delta = { x = -n, y = 0, z = 0 }, yaw = pi / 2 }, + } + + -- PLACE YAW VALUES INTO THE TABLE. + for rot = 0, 15 do + local yaw = pi * 2 - (((pi * 2) / 16) * rot) + local delta = vector.multiply(minetest.yaw_to_dir(yaw), m) + -- Offset because sign is a bit above node boundaries + delta.y = delta.y + 2 / 28 + table.insert(mcl_signs.signtext_info_standing, { delta = delta, yaw = yaw }) + end + +end + +-- wall signs' & hanging signs' base (definition) +mcl_signs.wall_standard = { + description = S("Sign"), + _tt_help = S("Can be written"), + _doc_items_longdesc = S("Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them."), + _doc_items_usagehelp = S("After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow."), + inventory_image = "default_sign.png", + walkable = false, + is_ground_content = false, + wield_image = "default_sign.png", + node_placement_prediction = "", + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "wallmounted", + drawtype = "mesh", + mesh = "mcl_signs_signonwallmount.obj", + selection_box = { type = "wallmounted", wall_side = { -0.5, -7 / 28, -0.5, -23 / 56, 7 / 28, 0.5 } }, + tiles = { "mcl_signs_sign.png" }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + groups = mcl_signs.sign_groups, + stack_max = 16, + sounds = node_sounds, + + on_timer = function(pos) + -- fix for /ClearObjects + mcl_signs:update_sign(pos) + -- note: update_sign decides to keep the timer running based on if there is text. + -- This prevents every sign from having a timer, when not needed. + end, + + on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + + --local placer_pos = placer:get_pos() + + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + end + + if wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign") + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5") + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45") + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5") + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + if DEBUG then + minetest.log("verbose", "[mcl_signs]Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end, + on_destruct = function(pos) + mcl_signs:destruct_sign(pos) + end, + + -- Not Useless Code. force updates the sign. + on_punch = function(pos, node, puncher) + mcl_signs:update_sign(pos) + end, + on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + local r = screwdriver.rotate.wallmounted(pos, node, mode) + node.param2 = r + minetest.swap_node(pos, node) + mcl_signs:update_sign(pos, nil, nil, true) + return true + else + return false + end + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if DEBUG then + minetest.log("verbose", "[mcl_signs] Wall_Sign Right Click event.") + end + + -- make sure player is clicking + if not clicker or not clicker:is_player() then + return + end + + local item = clicker:get_wielded_item() + local iname = item:get_name() + + if node then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Wall_Sign Right Click event on valid node.") + end + + -- handle glow from glow_ink_sac *first* + if (iname == "mcl_mobitems:glow_ink_sac") then + clicker:set_wielded_item(item) + local success = mcl_signs:glow_sign(pos) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Glow Success.") + end + itemstack:take_item() + end + return + end + + -- "mcl_dye:black" is a special case: it makes the sign's lettering black AND removes glow. + if (iname == "mcl_dye:black") then + clicker:set_wielded_item(item) + local success = mcl_signs:glow_sign(pos, true) + mcl_signs:color_sign(pos, mcl_colors.BLACK) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Glow removal Success.") + end + + itemstack:take_item() + end + return + end + + -- check the wielded item to make sure that it is a dye. + local txt_color = mcl_signs:get_color_for_sign(iname) + if txt_color ~= "false" then + clicker:set_wielded_item(item) + local success = mcl_signs:color_sign(pos, txt_color) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Color Success.") + end + itemstack:take_item() + end + end + end + end, + + _mcl_hardness = 1, + _mcl_blast_resistance = 1, +} +-- standing sign base (definition) +mcl_signs.standing_standard = { + paramtype = "light", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + sunlight_propagates = true, + walkable = false, + is_ground_content = false, + paramtype2 = "facedir", + drawtype = "mesh", + mesh = "mcl_signs_sign.obj", + selection_box = { type = "fixed", fixed = { -0.2, -0.5, -0.2, 0.2, 0.5, 0.2 } }, + tiles = { "mcl_signs_sign.png" }, + groups = mcl_signs.sign_groups, + drop = "mcl_signs:wall_sign", + stack_max = 16, + sounds = node_sounds, + + on_destruct = function(pos) + mcl_signs:destruct_sign(pos) + end, + + on_timer = function(pos) + -- fix for /ClearObjects + mcl_signs:update_sign(pos) + minetest.get_node_timer(pos):start(40.0) + end, + + -- Not Useless Code. this force updates the sign. + on_punch = function(pos, node, puncher) + mcl_signs:update_sign(pos) + end, + on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + + if DEBUG then + minetest.log("verbose", "[mcl_signs] Standing_Sign Right Click event.") + end + + -- make sure player is clicking + if not clicker or not clicker:is_player() then + return + end + + local item = clicker:get_wielded_item() + local iname = item:get_name() + + if node then + -- handle glow from glow_ink_sac *first* + if DEBUG then + minetest.log("verbose", "[mcl_signs] Standing_Sign Right Click event on valid node.") + end + + if (iname == "mcl_mobitems:glow_ink_sac") then + clicker:set_wielded_item(item) + local success = mcl_signs:glow_sign(pos) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Glow Success.") + end + itemstack:take_item() + end + return + end + + -- check the wielded item to make sure that it is a dye. + local txt_color = mcl_signs:get_color_for_sign(iname) + if txt_color ~= "false" then + clicker:set_wielded_item(item) + local success = mcl_signs:color_sign(pos, txt_color) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Color Success.") + end + itemstack:take_item() + end + end + end + end, + + _mcl_hardness = 1, + _mcl_blast_resistance = 1, +} + +-- HELPER FUNCTIONS' VARIABLES +local sign_glow = 6 +local Dyes_table = { + { "mcl_dye:aqua", mcl_colors_official.AQUA }, + { "mcl_dye:black", mcl_colors_official.BLACK }, + { "mcl_dye:blue", mcl_colors_official.BLUE }, + { "mcl_dye:brown", mcl_colors_official.brown }, + { "mcl_dye:cyan", mcl_signs.mcl_wool_colors.unicolor_cyan }, + { "mcl_dye:green", mcl_colors_official.GREEN }, + { "mcl_dye:dark_green", mcl_colors_official.DARK_GREEN }, + { "mcl_dye:grey", mcl_colors_official.GRAY }, + { "mcl_dye:dark_grey", mcl_colors_official.DARK_GRAY }, + { "mcl_dye:lightblue", mcl_signs.mcl_wool_colors.unicolor_light_blue }, + { "mcl_dye:lime", mcl_signs.unicolor_green_or_lime }, + { "mcl_dye:magenta", mcl_colors_official.LIGHT_PURPLE }, + { "mcl_dye:orange", mcl_signs.mcl_wool_colors.unicolor_orange }, + { "mcl_dye:pink", mcl_signs.mcl_wool_colors.unicolor_light_red_pink }, + { "mcl_dye:purple", mcl_colors_official.LIGHT_PURPLE }, + { "mcl_dye:red", mcl_signs.mcl_wool_colors.unicolor_red }, + { "mcl_dye:silver", mcl_signs.mcl_wool_colors.unicolor_grey }, + { "mcl_dye:violet", mcl_colors_official.DARK_PURPLE }, + { "mcl_dye:white", mcl_colors_official.WHITE }, + { "mcl_dye:yellow", mcl_colors_official.YELLOW }, +} + +local function update_sign_registry(type, name) + if type == "wall" then + table.insert(mcl_signs.registered_signs.wall_signs, name) + end + if type == "standing" then + table.insert(mcl_signs.registered_signs.standing_signs, name) + end + if type == "hanging" then + table.insert(mcl_signs.registered_signs.hanging_signs, name) + end +end + +function mcl_signs.make_lbm() + + local registered_sign_nodenames = {} + + for i = 0, #mcl_signs.registered_signs.wall_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.wall_signs[i]) + end + + for i = 0, #mcl_signs.registered_signs.standing_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.standing_signs[i]) + end + + for i = 0, #mcl_signs.registered_signs.hanging_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.hanging_signs[i]) + end + + -- the above is not yet used. + minetest.register_lbm({ + name = "mcl_signs:respawn_entities", + label = "Respawn sign text entities", + run_at_every_load = true, + nodenames = registered_sign_nodenames, + action = function(pos, node) + mcl_signs:update_sign(pos) + end, + }) + +end + +function mcl_signs.register_dye (modname, item_name, color_code) + if minetest.get_modpath(modname) then + table.insert(Dyes_table, { item_name, color_code }) + end +end + +--- Register a new sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- color: the color code to color the base sign textures. must be a valid html color code. +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.register_sign (modname, color, _name, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + if color == nil or color == "" then + color = "#FFFFFF" + end + + new_sign = table.copy(mcl_signs.wall_standard) + new_sign.description = S(ttsign) + + new_sign.wield_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" + + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + + local yaw = 0 + + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? simple - hanging sign. + -- add code for placement underneath a node. + + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + if DEBUG then + minetest.log("action", "[mcl_signs] Register_Sign::Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + + minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:wall_sign" .. _name .. color .. "\n" .. dump(new_sign)) + minetest.log("action", "[mcl_signs] mcl_signs:wall_sign_standard\n" .. dump(mcl_signs.wall_standard)) + end + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" + + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + + minetest.register_node(":mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:standing_sign" .. _name .. color .. "\n" .. dump(new_sign_standing)) + end + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) +end + +--- The same as register_sign, except caller defines the textures. Note, there is a greyscale version of the sign, +--- called "default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- tiles: the texture file to use for the sign. +--- +--- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, +--- and just use the texture as is +--- +--- inventory_image: the texture file to use for the sign's display in inventory. +--- +--- wield_image: the texture file to use for the sign's weilded (in hand) object. +--- +--- inventory_image: the image used for in-inventory and in hand. +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.register_sign_custom (modname, _name, tiles, color, inventory_image, wield_image, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + new_sign = table.copy(mcl_signs.wall_standard) + + new_sign.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + new_sign.description = S(ttsign) + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.register_node(":mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) + +end + +--- Override an existing sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- color: the color code to color the base sign textures. must be a valid html color code. +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.reregister_sign (modname, color, _name, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + if color == nil or color == "" then + color = "#FFFFFF" + end + + new_sign = table.copy(mcl_signs.wall_standard) + new_sign.description = S(ttsign) + + new_sign.wield_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" + + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + if DEBUG then + minetest.log("action", "[mcl_signs] Register_Sign::Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + + minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:wall_sign" .. _name .. color .. "\n" .. dump(new_sign)) + minetest.log("action", "[mcl_signs] mcl_signs:wall_sign_standard\n" .. dump(mcl_signs.wall_standard)) + end + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.override_item("mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:standing_sign" .. _name .. color .. "\n" .. dump(new_sign_standing)) + end + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) +end + +--- The same as reregister_sign, except caller defines the textures. Note, there is a greyscale version of the sign, +--- called "default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- tiles: the texture file to use for the sign. +--- +--- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, +--- and just use the texture as is +--- +--- inventory_image: the texture file to use for the sign's display in inventory. +--- +--- wield_image: the texture file to use for the sign's weilded (in hand) object. +--- +--- inventory_image: the image used for in-inventory and in hand. +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.reregister_sign_custom (modname, _name, tiles, color, inventory_image, wield_image, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + new_sign = table.copy(mcl_signs.wall_standard) + + new_sign.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + new_sign.description = S(ttsign) + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.override_item("mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) + table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) + +end + +--- Usage: Call this with the mod's name, the wood's item string (for the planks), and with the sign's suffix. +--- Registers the crafting recipe for that sign. for every registered sign, call this function to register the +--- standard recipe for the sign. Otherwise, you have to do your own register craft call. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). Example: "mcl_core". +--- +--- wood_item_string: example: "mcl_core:wood" or "mcl_core:sprucewood" +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +function mcl_signs.register_sign_craft(modname, wood_item_string, _name) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_signs:wall_sign" .. _name, + burntime = 10, + }) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Register Sign Crafts: \n" .. modname .. "\n" .. wood_item_string .. "\n" .. _name) + end + + -- register crafts (actual recipe) + if minetest.get_modpath(modname) then + + local itemstring = "mcl_signs:wall_sign" + + minetest.register_craft({ + output = itemstring .. _name .. " 3", + recipe = { + { wood_item_string, wood_item_string, wood_item_string }, + { wood_item_string, wood_item_string, wood_item_string }, + { "", "mcl_core:stick", "" }, + }, + }) + end +end + +function mcl_signs.register_hanging_sign_craft(modname, wood_item_string, _name) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + minetest.register_craft({ + type = "fuel", + recipe = ":mcl_signs:wall_sign" .. _name, + burntime = 10, + }) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Register Sign Crafts: \n" .. modname .. "\n" .. wood_item_string .. "\n" .. _name) + end + + -- register crafts (actual recipe) + if minetest.get_modpath(modname) then + + local itemstring = ":mcl_signs:hanging_sign" + local quantity = "6" + + local bamboo = string.find(wood_item_string, "bamboo") + if bamboo then + quantity = "2" + end + minetest.register_craft({ + output = itemstring .. _name .. " " .. quantity, + recipe = { + { "mcl_lanterns:chain", "", "mcl_lanterns:chain" }, + { wood_item_string, wood_item_string, wood_item_string }, + { wood_item_string, wood_item_string, wood_item_string }, + }, + }) + end +end + +-- Helper functions +local function string_to_array(str) + local string_table = {} + for i = 1, string.len(str) do + table.insert(string_table, string.sub(str, i, i)) + end + return string_table +end + +local function string_to_line_array(str) + local linechar_table = {} + local current = 1 + local linechar = 1 + linechar_table[1] = "" + for _, char in ipairs(string_to_array(str)) do + -- New line + if char == "\n" then + current = current + 1 + linechar_table[current] = "" + linechar = 1 + else + linechar_table[current] = linechar_table[current] .. char + linechar = linechar + 1 + end + end + return linechar_table +end + +local function get_rotation_level(facedir, nodename) + local nnames = mcl_signs.standing_rotation_levels -- functional copy... was easier this way. #LazyAF :P + + local rl + local offset = 0 + for x = 1, #nnames do + if nnames[x][1] == nodename then + offset = nnames[x][2] + break + end + end + rl = facedir * 4 + offset + if DEBUG then + minetest.log("action", "[mcl_signs] GetRotationLevel: NodeName: " .. nodename .. " RL value: " .. rl) + end + return rl +end + +function mcl_signs:round(num, idp) + local mult = 10 ^ (idp or 0) + return math.floor(num * mult + 0.5) / mult +end + +function mcl_signs:get_color_for_sign(item_name) + + for d = 1, #Dyes_table do + if Dyes_table[d][1] == item_name then + return Dyes_table[d][2] + end + end + return "false" +end + +function mcl_signs:color_sign (pos, text_color) + + local success = mcl_signs:update_sign(pos, nil, nil, true, text_color) + + -- debug step + local meta = minetest.get_meta(pos) + if not meta then + minetest.log("error", "[mcl_signs] Sign Color Fail - Metadata.") + + return false + end + if DEBUG then + minetest.log("verbose", "[mcl_signs] Post-Sign Color: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + return success + +end + +function mcl_signs:glow_sign (pos, remove_glow) + local success = true + -- Get Meta Data for the sign. + local meta = minetest.get_meta(pos) + + if not meta then + return false + end + local text = meta:get_string("text") + if text == nil then + text = "" + end + + -- we can't make the text glow if there isn't any text + if text == "" then + return false + end + + if remove_glow == nil then + remove_glow = false + end + + -- set up text glow + local objects = minetest.get_objects_inside_radius(pos, 0.5) + local text_entity + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + text_entity = v + break + end + end + if remove_glow == true then + text_entity:set_properties({ + glow = nil, + }) + meta:set_string("mcl_signs:glowing_sign", "false") + else + text_entity:set_properties({ + glow = sign_glow, + }) + meta:set_string("mcl_signs:glowing_sign", "true") + end + if not text_entity then + return false + end + text_entity:get_luaentity()._glowing_sign = meta:get_string("mcl_signs:glowing_sign") + + -- debug step + if DEBUG then + minetest.log("verbose", "[mcl_signs] Post-Sign Glow: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + return success +end + +function mcl_signs:create_lettering(text, signnodename, sign_color) + if sign_color == nil then + sign_color = mcl_colors.BLACK + end + local texture = mcl_signs:generate_texture(mcl_signs:create_lines(text), signnodename, sign_color) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Creating sign text; text:" .. text) + end + + return texture +end + +function mcl_signs:create_lines(text) + local line_num = 1 + local text_table = {} + for _, line in ipairs(string_to_line_array(text)) do + if line_num > NUMBER_OF_LINES then + break + end + table.insert(text_table, line) + line_num = line_num + 1 + end + return text_table +end + +function mcl_signs:generate_line(s, ypos) + local i = 1 + local parsed = {} + local width = 0 + local chars = 0 + local printed_char_width = CHAR_WIDTH + 1 + while chars < LINE_LENGTH and i <= #s do + local file + -- Get and render character + if charmap[s:sub(i, i)] then + file = charmap[s:sub(i, i)] + i = i + 1 + elseif i < #s and charmap[s:sub(i, i + 1)] then + file = charmap[s:sub(i, i + 1)] + i = i + 2 + else + -- No character image found. + -- Use replacement character: + file = "_rc" + i = i + 1 + if DEBUG then + minetest.log("verbose", "[mcl_signs] Unknown symbol in '" .. s .. "' at " .. i) + end + end + if file then + width = width + printed_char_width + table.insert(parsed, file) + chars = chars + 1 + end + end + width = width - 1 + + local texture = "" + local xpos = math.floor((SIGN_WIDTH - width) / 2) + + for j = 1, #parsed do + texture = texture .. ":" .. xpos .. "," .. ypos .. "=" .. parsed[j] .. ".png" + xpos = xpos + printed_char_width + end + return texture +end + +function mcl_signs:generate_texture(lines, signnodename, letter_color) + local texture = "[combine:" .. SIGN_WIDTH .. "x" .. SIGN_WIDTH + local ypos = 0 + + -- Handle all of the dynamically created signs. + for x = 1, #mcl_signs.registered_signs.wall_signs do + if signnodename == mcl_signs.registered_signs.wall_signs[x] then + ypos = 30 + break + end + end + for x = 1, #mcl_signs.registered_signs.standing_signs do + if signnodename == mcl_signs.registered_signs.standing_signs[x] then + ypos = 0 + break + end + end + -- for future inclusion, when the hanging sings are made. + --[[ + for x = 1, #mcl_signs.registered_signs.hanging_signs do + if signnodename == mcl_signs.registered_signs.hanging_signs[x] then + ypos = 30 + break + end + end + ]] + + -- kept in for now, compatibility with existing hard coded signs. TODO: Remove after done with api. + if signnodename == "mcl_signs:wall_sign" or signnodename == "mcl_signs:wall_sign_dark" then + ypos = 30 + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Generate_Texture::Debug_Data:\nSignNodeName: " .. dump(signnodename) .. "\nYPOS: " .. ypos) + end + + for i = 1, #lines do + texture = texture .. mcl_signs:generate_line(lines[i], ypos) + ypos = ypos + LINE_HEIGHT + end + + texture = "(" .. texture .. "^[multiply:" .. letter_color .. ")" + return texture +end + +function mcl_signs:get_wall_signtext_info(param2, nodename) + local dir = minetest.wallmounted_to_dir(param2) + if dir.x > 0 then + return 2 + elseif dir.z > 0 then + return 1 + elseif dir.x < 0 then + return 4 + else + return 3 + end +end + +function mcl_signs:destruct_sign(pos) + local objects = minetest.get_objects_inside_radius(pos, 0.5) + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + v:remove() + end + end + local players = minetest.get_connected_players() + for p = 1, #players do + if vector.distance(players[p]:get_pos(), pos) <= 30 then + minetest.close_formspec(players[p]:get_player_name(), "mcl_signs:set_text_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z) + end + end +end + +function mcl_signs:update_sign(pos, fields, sender, force_remove, text_color) + -- Get Meta Data for the sign. + local meta = minetest.get_meta(pos) + + if not meta then + return false + end + local text = meta:get_string("text", "") + if fields and (text == "" and fields.text) then + meta:set_string("text", fields.text) + text = fields.text + end + if text == nil then + text = "" + end + + -- find text color. + local sign_color + + if meta:get_string("mcl_signs:text_color") == "" then + -- if no sign text color has been assigned, make it black. + sign_color = mcl_colors.BLACK + meta:set_string("mcl_signs:text_color", sign_color) + else + sign_color = meta:get_string("mcl_signs:text_color") + end + + if text_color == nil or text == "" then + text_color = "false" + end + + if text_color == "false" then + text_color = sign_color --if a new color hasn't been chosen, then keep the existing color. + end + + -- find the sign's glow value + local has_glow = false + + if meta:get_string("mcl_signs:glowing_sign") == "" or meta:get_string("mcl_signs:glowing_sign") == "false" then + has_glow = false + meta:set_string("mcl_signs:glowing_sign", "false") + else + has_glow = true + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Signs: Pre-Sign Update: " .. sign_color .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + local sign_info + local npos = minetest.get_node(pos) + local npos_name = npos.name + + -- Handle all of the dynamically created signs. + for x = 1, #mcl_signs.registered_signs.wall_signs do + if npos_name == mcl_signs.registered_signs.wall_signs[x] then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(npos.param2)] + break + end + end + for x = 1, #mcl_signs.registered_signs.standing_signs do + if npos_name == mcl_signs.registered_signs.standing_signs[x] then + sign_info = mcl_signs.signtext_info_standing[get_rotation_level(npos.param2, npos_name) + 1] + break + end + end + -- for future inclusion, when the hanging sings are made. + --[[ + for x = 1, #mcl_signs.registered_signs.hanging_signs do + if nn == mcl_signs.registered_signs.hanging_signs[x] then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(n.param2)] + break + end + end + ]] + + -- the following if..elseif..end block is here for compatibility with the old code. TODO: remove this block after the new api is complete. + if npos_name == "mcl_signs:standing_sign_dark" or npos_name == "mcl_signs:standing_sign22_5_dark" or npos_name == "mcl_signs:standing_sign45_dark" or npos_name == "mcl_signs:standing_sign67_5_dark" then + sign_info = mcl_signs.signtext_info_standing[get_rotation_level(npos.param2, npos_name) + 1] + elseif npos_name == "mcl_signs:wall_sign_dark" then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(npos.param2)] + end + if sign_info == nil then + minetest.log("error", "[mcl_signs] Update_Signs: Missing sign_info!") + return false + end + + local text_entity + text_entity = mcl_signs:get_text_entity(pos,force_remove) + + if not text_entity then + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Text_Entity - does not exist, creating it now.") + end + text_entity = minetest.add_entity({ + x = pos.x + sign_info.delta.x, + y = pos.y + sign_info.delta.y, + z = pos.z + sign_info.delta.z }, "mcl_signs:text") + + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Placed position:" .. dump(pos) .. "\nSign_info: " .. dump(sign_info)) + end + end + text_entity:get_luaentity()._signnodename = npos_name + + -- set up special case: Dark Oak Sign. Dark Oak signs are soooo dark, they start off with white lettering. + if npos_name == "mcl_signs:wall_sign_darkwood" or + npos_name == "mcl_signs:standing_sign67_5_darkwood" or + npos_name == "mcl_signs:standing_sign45_darkwood" or + npos_name == "mcl_signs:standing_sign22_5_darkwood" or + npos_name == "mcl_signs:standing_sign_darkwood" + then + if text_color == "#000000" then + text_color = "#ffffff" + end + end + + -- Set the actual properties for the sign + + text_entity:set_properties({ + textures = { mcl_signs:create_lettering(text, npos_name, text_color) }, + }) + + if has_glow then + text_entity:set_properties({ + glow = sign_glow, + }) + end + + text_entity:set_yaw(sign_info.yaw) + if DEBUG then + minetest.log("verbose", "[mcl_signs] Update_Sign: After texture recreation.") + minetest.log("action", "[mcl_signs] Update_Sign: " .. npos_name .. "\nPlaced position:" .. dump(pos) .. "\nSign_info: " .. dump(sign_info)) + end + + -- save sign metadata. + meta:set_string("mcl_signs:text_color", text_color) + + -- Moved timer stuff to here, to make sure that it's called and only has one set of code. + local timer = minetest.get_node_timer(pos) + if text_entity and text ~= "" then + -- Do timer related stuff - but only if there is text to display. + -- Also, prevent excessive use with punching. (see node def.) + if timer:is_started() == false then + timer:start(TIMER_INTERVAL) + else + timer:stop() + timer:start(TIMER_INTERVAL) + end + else + if timer:is_started() == true then + timer:stop() + end + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Post-Sign Update: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + return true + +end + +function mcl_signs:show_formspec(player, pos) + minetest.show_formspec( + player:get_player_name(), + "mcl_signs:set_text_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z, + "size[6,3]textarea[0.25,0.25;6,1.5;text;" .. F(S("Enter sign text:")) .. ";]label[0,1.5;" .. F(S("Maximum line length: 15")) .. "\n" .. F(S("Maximum lines: 4")) .. "]button_exit[0,2.5;6,1;submit;" .. F(S("Done")) .. "]" + ) +end + +function mcl_signs:get_text_entity (pos, force_remove) + local objects = minetest.get_objects_inside_radius(pos, 0.5) + local text_entity = false -- just to have a check for failure. + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + if force_remove ~= nil and force_remove == true then + v:remove() + else + text_entity = v + break + end + end + end + return text_entity +end \ No newline at end of file diff --git a/mods/ITEMS/mcl_signs/textures/_0.png b/mods/ITEMS/mcl_signs/textures/_0.png index e764f3d6a..7ec1aea7a 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_0.png and b/mods/ITEMS/mcl_signs/textures/_0.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_1.png b/mods/ITEMS/mcl_signs/textures/_1.png index 7fae5fa4c..e4bf5c3ac 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_1.png and b/mods/ITEMS/mcl_signs/textures/_1.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_1_2.png b/mods/ITEMS/mcl_signs/textures/_1_2.png index 52d025e87..8bdc3f8cc 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_1_2.png and b/mods/ITEMS/mcl_signs/textures/_1_2.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_1_4.png b/mods/ITEMS/mcl_signs/textures/_1_4.png index 220e65ef5..d32aa3027 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_1_4.png and b/mods/ITEMS/mcl_signs/textures/_1_4.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_1_sup.png b/mods/ITEMS/mcl_signs/textures/_1_sup.png index 6be5fdcb1..0e20bf3a6 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_1_sup.png and b/mods/ITEMS/mcl_signs/textures/_1_sup.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_2.png b/mods/ITEMS/mcl_signs/textures/_2.png index e32866d03..29583723f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_2.png and b/mods/ITEMS/mcl_signs/textures/_2.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_2_sup.png b/mods/ITEMS/mcl_signs/textures/_2_sup.png index 3db952179..ddc378772 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_2_sup.png and b/mods/ITEMS/mcl_signs/textures/_2_sup.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_3.png b/mods/ITEMS/mcl_signs/textures/_3.png index 4e7da5665..c58caaa8c 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_3.png and b/mods/ITEMS/mcl_signs/textures/_3.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_3_4.png b/mods/ITEMS/mcl_signs/textures/_3_4.png index 46e171049..316909108 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_3_4.png and b/mods/ITEMS/mcl_signs/textures/_3_4.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_3_sup.png b/mods/ITEMS/mcl_signs/textures/_3_sup.png index add337326..eae28867d 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_3_sup.png and b/mods/ITEMS/mcl_signs/textures/_3_sup.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_4.png b/mods/ITEMS/mcl_signs/textures/_4.png index 5f3d95656..38048937c 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_4.png and b/mods/ITEMS/mcl_signs/textures/_4.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_5.png b/mods/ITEMS/mcl_signs/textures/_5.png index baf23b273..96da18b50 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_5.png and b/mods/ITEMS/mcl_signs/textures/_5.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_6.png b/mods/ITEMS/mcl_signs/textures/_6.png index 31fcd7d72..e34e190e1 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_6.png and b/mods/ITEMS/mcl_signs/textures/_6.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_7.png b/mods/ITEMS/mcl_signs/textures/_7.png index 7594eb9d6..2b078c134 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_7.png and b/mods/ITEMS/mcl_signs/textures/_7.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_8.png b/mods/ITEMS/mcl_signs/textures/_8.png index b61f4e294..d4580e83f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_8.png and b/mods/ITEMS/mcl_signs/textures/_8.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_9.png b/mods/ITEMS/mcl_signs/textures/_9.png index 5ed82070b..3077c7bb3 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_9.png and b/mods/ITEMS/mcl_signs/textures/_9.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a.png b/mods/ITEMS/mcl_signs/textures/_a.png index 4b9356ac4..d57502ddb 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a.png and b/mods/ITEMS/mcl_signs/textures/_a.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_.png b/mods/ITEMS/mcl_signs/textures/_a_.png index 152beabd4..157565774 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_.png and b/mods/ITEMS/mcl_signs/textures/_a_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_acute.png b/mods/ITEMS/mcl_signs/textures/_a_acute.png index b72b4853e..552988e31 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_acute.png and b/mods/ITEMS/mcl_signs/textures/_a_acute.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_acute_.png b/mods/ITEMS/mcl_signs/textures/_a_acute_.png index d038b45ce..2f8736226 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_acute_.png and b/mods/ITEMS/mcl_signs/textures/_a_acute_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_circumflex.png b/mods/ITEMS/mcl_signs/textures/_a_circumflex.png index f9b80df66..224675375 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_circumflex.png and b/mods/ITEMS/mcl_signs/textures/_a_circumflex.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_a_circumflex_.png index 8b35bdf7c..146671315 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_circumflex_.png and b/mods/ITEMS/mcl_signs/textures/_a_circumflex_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_grave.png b/mods/ITEMS/mcl_signs/textures/_a_grave.png index 3f0de45a5..6ccb2088e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_grave.png and b/mods/ITEMS/mcl_signs/textures/_a_grave.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_grave_.png b/mods/ITEMS/mcl_signs/textures/_a_grave_.png index 8176f51c5..f973dec5d 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_grave_.png and b/mods/ITEMS/mcl_signs/textures/_a_grave_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_ring.png b/mods/ITEMS/mcl_signs/textures/_a_ring.png index d3c06ae6d..4d1b1e896 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_ring.png and b/mods/ITEMS/mcl_signs/textures/_a_ring.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_ring_.png b/mods/ITEMS/mcl_signs/textures/_a_ring_.png index d3e9b7e96..0c28aadcc 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_ring_.png and b/mods/ITEMS/mcl_signs/textures/_a_ring_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_sup.png b/mods/ITEMS/mcl_signs/textures/_a_sup.png index 4f4f9801c..c2a001016 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_sup.png and b/mods/ITEMS/mcl_signs/textures/_a_sup.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_tilde.png b/mods/ITEMS/mcl_signs/textures/_a_tilde.png index 567632c37..0600d53ad 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_tilde.png and b/mods/ITEMS/mcl_signs/textures/_a_tilde.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_tilde_.png b/mods/ITEMS/mcl_signs/textures/_a_tilde_.png index fd3d97784..baffca08e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_a_tilde_.png and b/mods/ITEMS/mcl_signs/textures/_a_tilde_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_acute.png b/mods/ITEMS/mcl_signs/textures/_acute.png index 0655de2dd..709cf70fb 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_acute.png and b/mods/ITEMS/mcl_signs/textures/_acute.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ae.png b/mods/ITEMS/mcl_signs/textures/_ae.png index 7f199e477..40bf3cd6b 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ae.png and b/mods/ITEMS/mcl_signs/textures/_ae.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ae_.png b/mods/ITEMS/mcl_signs/textures/_ae_.png index e19fdf1c8..2f6a56d00 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ae_.png and b/mods/ITEMS/mcl_signs/textures/_ae_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ae_lig.png b/mods/ITEMS/mcl_signs/textures/_ae_lig.png index a02bd30cf..0f721d8e0 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ae_lig.png and b/mods/ITEMS/mcl_signs/textures/_ae_lig.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ae_lig_.png b/mods/ITEMS/mcl_signs/textures/_ae_lig_.png index 0eb5d2f5c..8aba2a4bc 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ae_lig_.png and b/mods/ITEMS/mcl_signs/textures/_ae_lig_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_am.png b/mods/ITEMS/mcl_signs/textures/_am.png index 76a886757..15ad80d73 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_am.png and b/mods/ITEMS/mcl_signs/textures/_am.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ap.png b/mods/ITEMS/mcl_signs/textures/_ap.png index bced380ac..e44b77a61 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ap.png and b/mods/ITEMS/mcl_signs/textures/_ap.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_as.png b/mods/ITEMS/mcl_signs/textures/_as.png index 702a519b8..fbf1494d4 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_as.png and b/mods/ITEMS/mcl_signs/textures/_as.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_at.png b/mods/ITEMS/mcl_signs/textures/_at.png index 1c7fa502c..b6b1ebe31 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_at.png and b/mods/ITEMS/mcl_signs/textures/_at.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_b.png b/mods/ITEMS/mcl_signs/textures/_b.png index 427f488e5..bb44b3c1a 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_b.png and b/mods/ITEMS/mcl_signs/textures/_b.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_b_.png b/mods/ITEMS/mcl_signs/textures/_b_.png index c89961d1b..034f595ce 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_b_.png and b/mods/ITEMS/mcl_signs/textures/_b_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_bl.png b/mods/ITEMS/mcl_signs/textures/_bl.png index 422fcc586..a8e73c1b7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_bl.png and b/mods/ITEMS/mcl_signs/textures/_bl.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_br.png b/mods/ITEMS/mcl_signs/textures/_br.png index 88b1ba4a3..aebe3a025 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_br.png and b/mods/ITEMS/mcl_signs/textures/_br.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_broken_bar.png b/mods/ITEMS/mcl_signs/textures/_broken_bar.png index c733fd862..a2ec6ccc8 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_broken_bar.png and b/mods/ITEMS/mcl_signs/textures/_broken_bar.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_c.png b/mods/ITEMS/mcl_signs/textures/_c.png index 0ae311f3d..9d61a1c47 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_c.png and b/mods/ITEMS/mcl_signs/textures/_c.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_c_.png b/mods/ITEMS/mcl_signs/textures/_c_.png index 135260913..bd6d69d71 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_c_.png and b/mods/ITEMS/mcl_signs/textures/_c_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_c_cedille.png b/mods/ITEMS/mcl_signs/textures/_c_cedille.png index 9d5a4b564..a59faa4fb 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_c_cedille.png and b/mods/ITEMS/mcl_signs/textures/_c_cedille.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_c_cedille_.png b/mods/ITEMS/mcl_signs/textures/_c_cedille_.png index 7eb654bc4..3dcffc8e4 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_c_cedille_.png and b/mods/ITEMS/mcl_signs/textures/_c_cedille_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ca.png b/mods/ITEMS/mcl_signs/textures/_ca.png index 79fa4345f..799333fcc 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ca.png and b/mods/ITEMS/mcl_signs/textures/_ca.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_cedille.png b/mods/ITEMS/mcl_signs/textures/_cedille.png index 0de32ed0c..2fd6e557f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_cedille.png and b/mods/ITEMS/mcl_signs/textures/_cedille.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_cent.png b/mods/ITEMS/mcl_signs/textures/_cent.png index ecdb1f1d1..ac2265b05 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_cent.png and b/mods/ITEMS/mcl_signs/textures/_cent.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_cl.png b/mods/ITEMS/mcl_signs/textures/_cl.png index 38cad796c..71a046245 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_cl.png and b/mods/ITEMS/mcl_signs/textures/_cl.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_cm.png b/mods/ITEMS/mcl_signs/textures/_cm.png index 6b2b10a17..6a6a8bc5a 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_cm.png and b/mods/ITEMS/mcl_signs/textures/_cm.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_co.png b/mods/ITEMS/mcl_signs/textures/_co.png index 6775d5eaf..73808a7d9 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_co.png and b/mods/ITEMS/mcl_signs/textures/_co.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_copyright.png b/mods/ITEMS/mcl_signs/textures/_copyright.png index 7cfdf217e..1f0e3c934 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_copyright.png and b/mods/ITEMS/mcl_signs/textures/_copyright.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_cr.png b/mods/ITEMS/mcl_signs/textures/_cr.png index cd6d6dac6..2fbbf790f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_cr.png and b/mods/ITEMS/mcl_signs/textures/_cr.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_currency.png b/mods/ITEMS/mcl_signs/textures/_currency.png index 1264c8945..45806c12b 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_currency.png and b/mods/ITEMS/mcl_signs/textures/_currency.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_d.png b/mods/ITEMS/mcl_signs/textures/_d.png index d7988e2be..f7bd840cb 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_d.png and b/mods/ITEMS/mcl_signs/textures/_d.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_d_.png b/mods/ITEMS/mcl_signs/textures/_d_.png index 8803ea036..da46423c9 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_d_.png and b/mods/ITEMS/mcl_signs/textures/_d_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_d_dash.png b/mods/ITEMS/mcl_signs/textures/_d_dash.png index 73f5a1246..3f9b1e460 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_d_dash.png and b/mods/ITEMS/mcl_signs/textures/_d_dash.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_d_dash_.png b/mods/ITEMS/mcl_signs/textures/_d_dash_.png index e9c9e69c7..57e424f37 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_d_dash_.png and b/mods/ITEMS/mcl_signs/textures/_d_dash_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_degree.png b/mods/ITEMS/mcl_signs/textures/_degree.png index 64a7ee2b1..95b6c0800 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_degree.png and b/mods/ITEMS/mcl_signs/textures/_degree.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_diaresis.png b/mods/ITEMS/mcl_signs/textures/_diaresis.png index f8b75d38d..edbe9649c 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_diaresis.png and b/mods/ITEMS/mcl_signs/textures/_diaresis.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_div.png b/mods/ITEMS/mcl_signs/textures/_div.png index 808343753..ab6888146 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_div.png and b/mods/ITEMS/mcl_signs/textures/_div.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_dl.png b/mods/ITEMS/mcl_signs/textures/_dl.png index 044e4f00b..c1706295a 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_dl.png and b/mods/ITEMS/mcl_signs/textures/_dl.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_dt.png b/mods/ITEMS/mcl_signs/textures/_dt.png index 5dfa75349..b9a53650d 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_dt.png and b/mods/ITEMS/mcl_signs/textures/_dt.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_dv.png b/mods/ITEMS/mcl_signs/textures/_dv.png index 2989d93db..86d22fea4 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_dv.png and b/mods/ITEMS/mcl_signs/textures/_dv.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_e.png b/mods/ITEMS/mcl_signs/textures/_e.png index 316e966a1..431e2141b 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_e.png and b/mods/ITEMS/mcl_signs/textures/_e.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_.png b/mods/ITEMS/mcl_signs/textures/_e_.png index 5ef88d282..f9b674b15 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_e_.png and b/mods/ITEMS/mcl_signs/textures/_e_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_acute.png b/mods/ITEMS/mcl_signs/textures/_e_acute.png index 911207f86..4566f2dbc 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_e_acute.png and b/mods/ITEMS/mcl_signs/textures/_e_acute.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_acute_.png b/mods/ITEMS/mcl_signs/textures/_e_acute_.png index b60193740..70502e82f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_e_acute_.png and b/mods/ITEMS/mcl_signs/textures/_e_acute_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_circumflex.png b/mods/ITEMS/mcl_signs/textures/_e_circumflex.png index 2b5ace3c4..0aca71f43 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_e_circumflex.png and b/mods/ITEMS/mcl_signs/textures/_e_circumflex.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_e_circumflex_.png index c17d9dc29..02148554a 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_e_circumflex_.png and b/mods/ITEMS/mcl_signs/textures/_e_circumflex_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_grave.png b/mods/ITEMS/mcl_signs/textures/_e_grave.png index c24ab4635..c9366cd83 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_e_grave.png and b/mods/ITEMS/mcl_signs/textures/_e_grave.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_grave_.png b/mods/ITEMS/mcl_signs/textures/_e_grave_.png index c71bb2ef6..1006e5fea 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_e_grave_.png and b/mods/ITEMS/mcl_signs/textures/_e_grave_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ee.png b/mods/ITEMS/mcl_signs/textures/_ee.png index 646c19e14..4871c31be 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ee.png and b/mods/ITEMS/mcl_signs/textures/_ee.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ee_.png b/mods/ITEMS/mcl_signs/textures/_ee_.png index 5db7bc66a..3e174052f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ee_.png and b/mods/ITEMS/mcl_signs/textures/_ee_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_eq.png b/mods/ITEMS/mcl_signs/textures/_eq.png index 166f7a30d..9135af0fe 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_eq.png and b/mods/ITEMS/mcl_signs/textures/_eq.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ex.png b/mods/ITEMS/mcl_signs/textures/_ex.png index 65a76aad1..e63ed21f2 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ex.png and b/mods/ITEMS/mcl_signs/textures/_ex.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ex_inv.png b/mods/ITEMS/mcl_signs/textures/_ex_inv.png index 1e7bbfe87..af591188c 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ex_inv.png and b/mods/ITEMS/mcl_signs/textures/_ex_inv.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_f.png b/mods/ITEMS/mcl_signs/textures/_f.png index 1e431df13..40318ea05 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_f.png and b/mods/ITEMS/mcl_signs/textures/_f.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_f_.png b/mods/ITEMS/mcl_signs/textures/_f_.png index d0dec2b35..9c234f7c0 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_f_.png and b/mods/ITEMS/mcl_signs/textures/_f_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_g.png b/mods/ITEMS/mcl_signs/textures/_g.png index 0b39fc95e..7ddd6e106 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_g.png and b/mods/ITEMS/mcl_signs/textures/_g.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_g_.png b/mods/ITEMS/mcl_signs/textures/_g_.png index bfe054638..881d06842 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_g_.png and b/mods/ITEMS/mcl_signs/textures/_g_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_gr.png b/mods/ITEMS/mcl_signs/textures/_gr.png index 3f806499a..92832f94e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_gr.png and b/mods/ITEMS/mcl_signs/textures/_gr.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_gt.png b/mods/ITEMS/mcl_signs/textures/_gt.png index 0449b44de..a4ff1b616 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_gt.png and b/mods/ITEMS/mcl_signs/textures/_gt.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_guill_left.png b/mods/ITEMS/mcl_signs/textures/_guill_left.png index 32b90c3e2..a9cf7c724 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_guill_left.png and b/mods/ITEMS/mcl_signs/textures/_guill_left.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_guill_right.png b/mods/ITEMS/mcl_signs/textures/_guill_right.png index d372e6a85..f4433eca4 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_guill_right.png and b/mods/ITEMS/mcl_signs/textures/_guill_right.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_h.png b/mods/ITEMS/mcl_signs/textures/_h.png index bd6f1891c..b4c9cf2cb 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_h.png and b/mods/ITEMS/mcl_signs/textures/_h.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_h_.png b/mods/ITEMS/mcl_signs/textures/_h_.png index 08cb5d8b0..cdea24645 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_h_.png and b/mods/ITEMS/mcl_signs/textures/_h_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ha.png b/mods/ITEMS/mcl_signs/textures/_ha.png index 946ae4e5e..48323a28f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ha.png and b/mods/ITEMS/mcl_signs/textures/_ha.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_hs.png b/mods/ITEMS/mcl_signs/textures/_hs.png index 682a92a2d..60bce8e35 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_hs.png and b/mods/ITEMS/mcl_signs/textures/_hs.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_i.png b/mods/ITEMS/mcl_signs/textures/_i.png index 9ba3e01a3..4abe22825 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_i.png and b/mods/ITEMS/mcl_signs/textures/_i.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_.png b/mods/ITEMS/mcl_signs/textures/_i_.png index ffe090aa8..e8e5e1b58 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_i_.png and b/mods/ITEMS/mcl_signs/textures/_i_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_acute.png b/mods/ITEMS/mcl_signs/textures/_i_acute.png index 20bdafb62..b1ceff343 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_i_acute.png and b/mods/ITEMS/mcl_signs/textures/_i_acute.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_acute_.png b/mods/ITEMS/mcl_signs/textures/_i_acute_.png index 4cdc943d9..d59d86398 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_i_acute_.png and b/mods/ITEMS/mcl_signs/textures/_i_acute_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_circumflex.png b/mods/ITEMS/mcl_signs/textures/_i_circumflex.png index f0e712725..e7d5ab191 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_i_circumflex.png and b/mods/ITEMS/mcl_signs/textures/_i_circumflex.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_i_circumflex_.png index dc46f3ff5..a15c15336 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_i_circumflex_.png and b/mods/ITEMS/mcl_signs/textures/_i_circumflex_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_grave.png b/mods/ITEMS/mcl_signs/textures/_i_grave.png index 7254cd7d2..c0ae05825 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_i_grave.png and b/mods/ITEMS/mcl_signs/textures/_i_grave.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_grave_.png b/mods/ITEMS/mcl_signs/textures/_i_grave_.png index 1e2212679..7c68cb968 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_i_grave_.png and b/mods/ITEMS/mcl_signs/textures/_i_grave_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_j.png b/mods/ITEMS/mcl_signs/textures/_j.png index 7fec50215..118928bfc 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_j.png and b/mods/ITEMS/mcl_signs/textures/_j.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_j_.png b/mods/ITEMS/mcl_signs/textures/_j_.png index 440af26d5..3983cec05 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_j_.png and b/mods/ITEMS/mcl_signs/textures/_j_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_k.png b/mods/ITEMS/mcl_signs/textures/_k.png index af07f4bf3..987d0e26a 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_k.png and b/mods/ITEMS/mcl_signs/textures/_k.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_k_.png b/mods/ITEMS/mcl_signs/textures/_k_.png index 5e0a6b995..183c1d27c 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_k_.png and b/mods/ITEMS/mcl_signs/textures/_k_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_l.png b/mods/ITEMS/mcl_signs/textures/_l.png index d28a863f3..f70432b50 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_l.png and b/mods/ITEMS/mcl_signs/textures/_l.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_l_.png b/mods/ITEMS/mcl_signs/textures/_l_.png index c40390194..89a5e1562 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_l_.png and b/mods/ITEMS/mcl_signs/textures/_l_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_lt.png b/mods/ITEMS/mcl_signs/textures/_lt.png index 54295121e..a1b9d2ff8 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_lt.png and b/mods/ITEMS/mcl_signs/textures/_lt.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_m.png b/mods/ITEMS/mcl_signs/textures/_m.png index e4110bbb0..9c9c691d8 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_m.png and b/mods/ITEMS/mcl_signs/textures/_m.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_m_.png b/mods/ITEMS/mcl_signs/textures/_m_.png index ac516a053..c7e9fa044 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_m_.png and b/mods/ITEMS/mcl_signs/textures/_m_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_macron.png b/mods/ITEMS/mcl_signs/textures/_macron.png index ffb9dfd77..738a4374e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_macron.png and b/mods/ITEMS/mcl_signs/textures/_macron.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_mn.png b/mods/ITEMS/mcl_signs/textures/_mn.png index 2230e1065..63a9e67ba 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_mn.png and b/mods/ITEMS/mcl_signs/textures/_mn.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_mu.png b/mods/ITEMS/mcl_signs/textures/_mu.png index 3d8c1b890..483936af8 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_mu.png and b/mods/ITEMS/mcl_signs/textures/_mu.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_n.png b/mods/ITEMS/mcl_signs/textures/_n.png index ca5ea2787..3f16f50bc 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_n.png and b/mods/ITEMS/mcl_signs/textures/_n.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_n_.png b/mods/ITEMS/mcl_signs/textures/_n_.png index b96f27c62..430227892 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_n_.png and b/mods/ITEMS/mcl_signs/textures/_n_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_n_tilde.png b/mods/ITEMS/mcl_signs/textures/_n_tilde.png index 471669116..cfc1c626c 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_n_tilde.png and b/mods/ITEMS/mcl_signs/textures/_n_tilde.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_n_tilde_.png b/mods/ITEMS/mcl_signs/textures/_n_tilde_.png index 0dba0d471..404221056 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_n_tilde_.png and b/mods/ITEMS/mcl_signs/textures/_n_tilde_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_not.png b/mods/ITEMS/mcl_signs/textures/_not.png index a98f885e9..e7b1b7b66 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_not.png and b/mods/ITEMS/mcl_signs/textures/_not.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o.png b/mods/ITEMS/mcl_signs/textures/_o.png index 2a579385d..a59eacb8f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o.png and b/mods/ITEMS/mcl_signs/textures/_o.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_.png b/mods/ITEMS/mcl_signs/textures/_o_.png index 44ac3cbca..967c240b2 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_.png and b/mods/ITEMS/mcl_signs/textures/_o_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_acute.png b/mods/ITEMS/mcl_signs/textures/_o_acute.png index cda99b3a6..9094a80c7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_acute.png and b/mods/ITEMS/mcl_signs/textures/_o_acute.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_acute_.png b/mods/ITEMS/mcl_signs/textures/_o_acute_.png index e25a3a7f4..9279670fa 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_acute_.png and b/mods/ITEMS/mcl_signs/textures/_o_acute_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_circumflex.png b/mods/ITEMS/mcl_signs/textures/_o_circumflex.png index 2f7a188df..1240f1718 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_circumflex.png and b/mods/ITEMS/mcl_signs/textures/_o_circumflex.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_o_circumflex_.png index 5e4c6be6a..8acca66c9 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_circumflex_.png and b/mods/ITEMS/mcl_signs/textures/_o_circumflex_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_dash.png b/mods/ITEMS/mcl_signs/textures/_o_dash.png index 9e5de53d1..0f0d638ff 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_dash.png and b/mods/ITEMS/mcl_signs/textures/_o_dash.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_dash_.png b/mods/ITEMS/mcl_signs/textures/_o_dash_.png index badbe9b88..b6e98f1ee 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_dash_.png and b/mods/ITEMS/mcl_signs/textures/_o_dash_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_grave.png b/mods/ITEMS/mcl_signs/textures/_o_grave.png index b6b31a9a6..861327e27 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_grave.png and b/mods/ITEMS/mcl_signs/textures/_o_grave.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_grave_.png b/mods/ITEMS/mcl_signs/textures/_o_grave_.png index d34e9d71c..7ab9e374b 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_grave_.png and b/mods/ITEMS/mcl_signs/textures/_o_grave_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_sup.png b/mods/ITEMS/mcl_signs/textures/_o_sup.png index eeff0a295..bbabcf8c0 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_sup.png and b/mods/ITEMS/mcl_signs/textures/_o_sup.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_tilde.png b/mods/ITEMS/mcl_signs/textures/_o_tilde.png index 6cbd7cec0..3c95094bb 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_tilde.png and b/mods/ITEMS/mcl_signs/textures/_o_tilde.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_tilde_.png b/mods/ITEMS/mcl_signs/textures/_o_tilde_.png index bb0616918..8f980dd98 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_o_tilde_.png and b/mods/ITEMS/mcl_signs/textures/_o_tilde_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_oe.png b/mods/ITEMS/mcl_signs/textures/_oe.png index 9b6892155..693838ce7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_oe.png and b/mods/ITEMS/mcl_signs/textures/_oe.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_oe_.png b/mods/ITEMS/mcl_signs/textures/_oe_.png index 73b4da80e..c66b72ba2 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_oe_.png and b/mods/ITEMS/mcl_signs/textures/_oe_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_p.png b/mods/ITEMS/mcl_signs/textures/_p.png index 08f8534d0..8d0efe264 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_p.png and b/mods/ITEMS/mcl_signs/textures/_p.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_p_.png b/mods/ITEMS/mcl_signs/textures/_p_.png index 2ff300509..964387e64 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_p_.png and b/mods/ITEMS/mcl_signs/textures/_p_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_paragraph.png b/mods/ITEMS/mcl_signs/textures/_paragraph.png index 52c162120..cfbf0af51 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_paragraph.png and b/mods/ITEMS/mcl_signs/textures/_paragraph.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_pilcrow.png b/mods/ITEMS/mcl_signs/textures/_pilcrow.png index 9764ff8b5..cf9bbc778 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_pilcrow.png and b/mods/ITEMS/mcl_signs/textures/_pilcrow.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_plus_minus.png b/mods/ITEMS/mcl_signs/textures/_plus_minus.png index e7c3f1200..b9b79ec32 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_plus_minus.png and b/mods/ITEMS/mcl_signs/textures/_plus_minus.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_pound.png b/mods/ITEMS/mcl_signs/textures/_pound.png index 31d38d392..04a02d462 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_pound.png and b/mods/ITEMS/mcl_signs/textures/_pound.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_pr.png b/mods/ITEMS/mcl_signs/textures/_pr.png index c8783948d..21b8fbf80 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_pr.png and b/mods/ITEMS/mcl_signs/textures/_pr.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ps.png b/mods/ITEMS/mcl_signs/textures/_ps.png index 74b1f5b8e..37527155f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ps.png and b/mods/ITEMS/mcl_signs/textures/_ps.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_q.png b/mods/ITEMS/mcl_signs/textures/_q.png index b5fbcc27d..a48222e28 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_q.png and b/mods/ITEMS/mcl_signs/textures/_q.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_q_.png b/mods/ITEMS/mcl_signs/textures/_q_.png index 674799413..50f00af20 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_q_.png and b/mods/ITEMS/mcl_signs/textures/_q_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_qo.png b/mods/ITEMS/mcl_signs/textures/_qo.png index c7b87be68..9eaca2bd7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_qo.png and b/mods/ITEMS/mcl_signs/textures/_qo.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_qu.png b/mods/ITEMS/mcl_signs/textures/_qu.png index 1458c7e10..51dff64f3 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_qu.png and b/mods/ITEMS/mcl_signs/textures/_qu.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_qu_inv.png b/mods/ITEMS/mcl_signs/textures/_qu_inv.png index 757bd06db..b2fa4275e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_qu_inv.png and b/mods/ITEMS/mcl_signs/textures/_qu_inv.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_r.png b/mods/ITEMS/mcl_signs/textures/_r.png index 709c53889..6b80bb254 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_r.png and b/mods/ITEMS/mcl_signs/textures/_r.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_r_.png b/mods/ITEMS/mcl_signs/textures/_r_.png index f8b472755..3c1bafc58 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_r_.png and b/mods/ITEMS/mcl_signs/textures/_r_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_rc.png b/mods/ITEMS/mcl_signs/textures/_rc.png index 8b66915e6..b8ea5b70e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_rc.png and b/mods/ITEMS/mcl_signs/textures/_rc.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_re.png b/mods/ITEMS/mcl_signs/textures/_re.png index 8fdaf4d24..3f7dda14d 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_re.png and b/mods/ITEMS/mcl_signs/textures/_re.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_registered.png b/mods/ITEMS/mcl_signs/textures/_registered.png index 9a78dda3c..0e510a2a7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_registered.png and b/mods/ITEMS/mcl_signs/textures/_registered.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_s.png b/mods/ITEMS/mcl_signs/textures/_s.png index 4c47aee01..43c314be1 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_s.png and b/mods/ITEMS/mcl_signs/textures/_s.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_s_.png b/mods/ITEMS/mcl_signs/textures/_s_.png index 08cf6ff68..4edf86115 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_s_.png and b/mods/ITEMS/mcl_signs/textures/_s_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_sl.png b/mods/ITEMS/mcl_signs/textures/_sl.png index 413aa5778..1b4cf0f58 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_sl.png and b/mods/ITEMS/mcl_signs/textures/_sl.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_sm.png b/mods/ITEMS/mcl_signs/textures/_sm.png index 460c5d6dd..2d7dc7310 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_sm.png and b/mods/ITEMS/mcl_signs/textures/_sm.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_sp.png b/mods/ITEMS/mcl_signs/textures/_sp.png index 4aae0ea85..27db127b7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_sp.png and b/mods/ITEMS/mcl_signs/textures/_sp.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_sr.png b/mods/ITEMS/mcl_signs/textures/_sr.png index afefa91b2..b40144656 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_sr.png and b/mods/ITEMS/mcl_signs/textures/_sr.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_sz.png b/mods/ITEMS/mcl_signs/textures/_sz.png index 56d2847a1..6e323629a 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_sz.png and b/mods/ITEMS/mcl_signs/textures/_sz.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_t.png b/mods/ITEMS/mcl_signs/textures/_t.png index e750dd98e..e175268c3 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_t.png and b/mods/ITEMS/mcl_signs/textures/_t.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_t_.png b/mods/ITEMS/mcl_signs/textures/_t_.png index d7aabd04a..6fbae7a18 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_t_.png and b/mods/ITEMS/mcl_signs/textures/_t_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_thorn.png b/mods/ITEMS/mcl_signs/textures/_thorn.png index e44f23d85..3d3b4359d 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_thorn.png and b/mods/ITEMS/mcl_signs/textures/_thorn.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_thorn_.png b/mods/ITEMS/mcl_signs/textures/_thorn_.png index 1b6d2558b..add982bc1 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_thorn_.png and b/mods/ITEMS/mcl_signs/textures/_thorn_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_times_cross.png b/mods/ITEMS/mcl_signs/textures/_times_cross.png index 25af91b68..f6c6cd310 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_times_cross.png and b/mods/ITEMS/mcl_signs/textures/_times_cross.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_times_dot.png b/mods/ITEMS/mcl_signs/textures/_times_dot.png index 42dac52bc..92b5dae14 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_times_dot.png and b/mods/ITEMS/mcl_signs/textures/_times_dot.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_tl.png b/mods/ITEMS/mcl_signs/textures/_tl.png index 5f1b4fb43..e4eaf45a7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_tl.png and b/mods/ITEMS/mcl_signs/textures/_tl.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_u.png b/mods/ITEMS/mcl_signs/textures/_u.png index 2665e5685..1c81b91cc 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_u.png and b/mods/ITEMS/mcl_signs/textures/_u.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_.png b/mods/ITEMS/mcl_signs/textures/_u_.png index d04ff5481..06bac7dd9 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_u_.png and b/mods/ITEMS/mcl_signs/textures/_u_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_acute.png b/mods/ITEMS/mcl_signs/textures/_u_acute.png index 580f61042..04fe159d8 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_u_acute.png and b/mods/ITEMS/mcl_signs/textures/_u_acute.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_acute_.png b/mods/ITEMS/mcl_signs/textures/_u_acute_.png index 9237d3caf..266731981 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_u_acute_.png and b/mods/ITEMS/mcl_signs/textures/_u_acute_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_circumflex.png b/mods/ITEMS/mcl_signs/textures/_u_circumflex.png index 2b238be12..b402d9083 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_u_circumflex.png and b/mods/ITEMS/mcl_signs/textures/_u_circumflex.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_u_circumflex_.png index 1608ecf17..6e2bb85d2 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_u_circumflex_.png and b/mods/ITEMS/mcl_signs/textures/_u_circumflex_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_grave.png b/mods/ITEMS/mcl_signs/textures/_u_grave.png index 051280428..51fff9c2e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_u_grave.png and b/mods/ITEMS/mcl_signs/textures/_u_grave.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_grave_.png b/mods/ITEMS/mcl_signs/textures/_u_grave_.png index 668685793..2605b3eca 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_u_grave_.png and b/mods/ITEMS/mcl_signs/textures/_u_grave_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ue.png b/mods/ITEMS/mcl_signs/textures/_ue.png index 6249aaebb..d6af6eb7b 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ue.png and b/mods/ITEMS/mcl_signs/textures/_ue.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_ue_.png b/mods/ITEMS/mcl_signs/textures/_ue_.png index 3193a9412..52b4c9298 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_ue_.png and b/mods/ITEMS/mcl_signs/textures/_ue_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_un.png b/mods/ITEMS/mcl_signs/textures/_un.png index d65f12d4e..5da6b09a7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_un.png and b/mods/ITEMS/mcl_signs/textures/_un.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_v.png b/mods/ITEMS/mcl_signs/textures/_v.png index 888b2f1cf..390e3aae3 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_v.png and b/mods/ITEMS/mcl_signs/textures/_v.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_v_.png b/mods/ITEMS/mcl_signs/textures/_v_.png index f2ecbf143..5e27b773e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_v_.png and b/mods/ITEMS/mcl_signs/textures/_v_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_vb.png b/mods/ITEMS/mcl_signs/textures/_vb.png index ca2e5667a..d23d3a074 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_vb.png and b/mods/ITEMS/mcl_signs/textures/_vb.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_w.png b/mods/ITEMS/mcl_signs/textures/_w.png index 6c2eea3e1..1b8dc528e 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_w.png and b/mods/ITEMS/mcl_signs/textures/_w.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_w_.png b/mods/ITEMS/mcl_signs/textures/_w_.png index f1e26c108..259b599b9 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_w_.png and b/mods/ITEMS/mcl_signs/textures/_w_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_x.png b/mods/ITEMS/mcl_signs/textures/_x.png index 3eb2d52d7..746fa1776 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_x.png and b/mods/ITEMS/mcl_signs/textures/_x.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_x_.png b/mods/ITEMS/mcl_signs/textures/_x_.png index bcb351d56..05300eca7 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_x_.png and b/mods/ITEMS/mcl_signs/textures/_x_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_y.png b/mods/ITEMS/mcl_signs/textures/_y.png index 7cd1d87b7..87b45d413 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_y.png and b/mods/ITEMS/mcl_signs/textures/_y.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_y_.png b/mods/ITEMS/mcl_signs/textures/_y_.png index b5f49850c..de9a88db4 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_y_.png and b/mods/ITEMS/mcl_signs/textures/_y_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_y_acute.png b/mods/ITEMS/mcl_signs/textures/_y_acute.png index 37cb54b30..1fd9679d1 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_y_acute.png and b/mods/ITEMS/mcl_signs/textures/_y_acute.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_y_acute_.png b/mods/ITEMS/mcl_signs/textures/_y_acute_.png index bcc15c41c..18c5a5528 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_y_acute_.png and b/mods/ITEMS/mcl_signs/textures/_y_acute_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_y_diaresis.png b/mods/ITEMS/mcl_signs/textures/_y_diaresis.png index 135a8ce25..ecb56c237 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_y_diaresis.png and b/mods/ITEMS/mcl_signs/textures/_y_diaresis.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_yen.png b/mods/ITEMS/mcl_signs/textures/_yen.png index ec4ad65ee..7ea4e0094 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_yen.png and b/mods/ITEMS/mcl_signs/textures/_yen.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_z.png b/mods/ITEMS/mcl_signs/textures/_z.png index 8a710780a..62a89e647 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_z.png and b/mods/ITEMS/mcl_signs/textures/_z.png differ diff --git a/mods/ITEMS/mcl_signs/textures/_z_.png b/mods/ITEMS/mcl_signs/textures/_z_.png index 6192800b4..dcdf0ab8d 100644 Binary files a/mods/ITEMS/mcl_signs/textures/_z_.png and b/mods/ITEMS/mcl_signs/textures/_z_.png differ diff --git a/mods/ITEMS/mcl_signs/textures/default_sign.png b/mods/ITEMS/mcl_signs/textures/default_sign.png index 077983118..8fcee7e9f 100644 Binary files a/mods/ITEMS/mcl_signs/textures/default_sign.png and b/mods/ITEMS/mcl_signs/textures/default_sign.png differ diff --git a/mods/ITEMS/mcl_signs/textures/default_sign_dark.png b/mods/ITEMS/mcl_signs/textures/default_sign_dark.png new file mode 100644 index 000000000..016098238 Binary files /dev/null and b/mods/ITEMS/mcl_signs/textures/default_sign_dark.png differ diff --git a/mods/ITEMS/mcl_signs/textures/default_sign_greyscale.png b/mods/ITEMS/mcl_signs/textures/default_sign_greyscale.png new file mode 100644 index 000000000..570851a6a Binary files /dev/null and b/mods/ITEMS/mcl_signs/textures/default_sign_greyscale.png differ diff --git a/mods/ITEMS/mcl_signs/textures/mcl_signs_sign_dark.png b/mods/ITEMS/mcl_signs/textures/mcl_signs_sign_dark.png new file mode 100644 index 000000000..6189e7709 Binary files /dev/null and b/mods/ITEMS/mcl_signs/textures/mcl_signs_sign_dark.png differ diff --git a/mods/ITEMS/mcl_signs/textures/mcl_signs_sign_greyscale.png b/mods/ITEMS/mcl_signs/textures/mcl_signs_sign_greyscale.png new file mode 100644 index 000000000..845a8d857 Binary files /dev/null and b/mods/ITEMS/mcl_signs/textures/mcl_signs_sign_greyscale.png differ diff --git a/mods/ITEMS/mcl_smithing_table/init.lua b/mods/ITEMS/mcl_smithing_table/init.lua new file mode 100644 index 000000000..dbb6c620f --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/init.lua @@ -0,0 +1,145 @@ +--[[ +By EliasFleckenstein03 and Code-Sploit +]] + +local S = minetest.get_translator("mcl_smithing_table") +mcl_smithing_table = {} + +-- Function to upgrade diamond tool/armor to netherite tool/armor +function mcl_smithing_table.upgrade_item(itemstack) + local def = itemstack:get_definition() + + if not def or not def._mcl_upgradable then + return + end + local itemname = itemstack:get_name() + local upgrade_item = itemname:gsub("diamond", "netherite") + + if def._mcl_upgrade_item and upgrade_item == itemname then + return + end + + itemstack:set_name(upgrade_item) + + -- Reload the ToolTips of the tool + + tt.reload_itemstack_description(itemstack) + + -- Only return itemstack if upgrade was successfull + return itemstack +end + +-- Badly copied over from mcl_anvils +-- ToDo: Make better formspec + +local formspec = "size[9,9]" .. + "background[-0.19,-0.25;9.41,9.49;mcl_smithing_table_inventory.png]".. + "label[0,4.0;" .. minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))) .. "]" .. + "list[current_player;main;0,4.5;9,3;9]" .. + mcl_formspec.get_itemslot_bg(0,4.5,9,3) .. + "list[current_player;main;0,7.74;9,1;]" .. + mcl_formspec.get_itemslot_bg(0,7.74,9,1) .. + "list[context;diamond_item;1,2.5;1,1;]" .. + mcl_formspec.get_itemslot_bg(1,2.5,1,1) .. + "list[context;netherite;4,2.5;1,1;]" .. + mcl_formspec.get_itemslot_bg(4,2.5,1,1) .. + "list[context;upgraded_item;8,2.5;1,1;]" .. + mcl_formspec.get_itemslot_bg(8,2.5,1,1) .. + "label[3,0.1;" .. minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Upgrade Gear"))) .. "]" .. + "listring[context;output]".. + "listring[current_player;main]".. + "listring[context;input]".. + "listring[current_player;main]" + +local function reset_upgraded_item(pos) + local inv = minetest.get_meta(pos):get_inventory() + local upgraded_item + + if inv:get_stack("netherite", 1):get_name() == "mcl_nether:netherite_ingot" then + upgraded_item = mcl_smithing_table.upgrade_item(inv:get_stack("diamond_item", 1)) + end + + inv:set_stack("upgraded_item", 1, upgraded_item) +end + +minetest.register_node("mcl_smithing_table:table", { + description = S("Smithing table"), + -- ToDo: Add _doc_items_longdesc and _doc_items_usagehelp + + stack_max = 64, + groups = {pickaxey = 2, deco_block = 1}, + + tiles = { + "mcl_smithing_table_top.png", + "mcl_smithing_table_bottom.png", + "mcl_smithing_table_side.png", + "mcl_smithing_table_side.png", + "mcl_smithing_table_side.png", + "mcl_smithing_table_front.png", + }, + + sounds = mcl_sounds.node_sound_metal_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", formspec) + + local inv = meta:get_inventory() + + inv:set_size("diamond_item", 1) + inv:set_size("netherite", 1) + inv:set_size("upgraded_item", 1) + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "diamond_item" and mcl_smithing_table.upgrade_item(stack) or listname == "netherite" and stack:get_name() == "mcl_nether:netherite_ingot" then + return stack:get_count() + end + + return 0 + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + + on_metadata_inventory_put = reset_upgraded_item, + + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local inv = minetest.get_meta(pos):get_inventory() + + local function take_item(listname) + local itemstack = inv:get_stack(listname, 1) + itemstack:take_item() + inv:set_stack(listname, 1, itemstack) + end + + if listname == "upgraded_item" then + take_item("diamond_item") + take_item("netherite") + + -- ToDo: make epic sound + minetest.sound_play("mcl_smithing_table_upgrade", {pos = pos, max_hear_distance = 16}) + end + if listname == "upgraded_item" then + if stack:get_name() == "mcl_farming:hoe_netherite" then + awards.unlock(player:get_player_name(), "mcl:seriousDedication") + end + end + + reset_upgraded_item(pos) + end, + + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5 +}) + + +minetest.register_craft({ + output = "mcl_smithing_table:table", + recipe = { + {"mcl_core:iron_ingot", "mcl_core:iron_ingot", ""}, + {"group:wood", "group:wood", ""}, + {"group:wood", "group:wood", ""} + } +}) diff --git a/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.fr.tr b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.fr.tr new file mode 100644 index 000000000..4fcdc22a3 --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.fr.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_smithing_table +Smithing table=Table de forgeron diff --git a/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ja.tr b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ja.tr new file mode 100644 index 000000000..792b0afe0 --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ja.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_smithing_table +Smithing table=鍛冶台 diff --git a/mods/ITEMS/mcl_smithing_table/locale/template.txt b/mods/ITEMS/mcl_smithing_table/locale/template.txt new file mode 100644 index 000000000..48b407d97 --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/locale/template.txt @@ -0,0 +1,2 @@ +# textdomain: mcl_smithing_table +Smithing table= diff --git a/mods/ITEMS/mcl_smithing_table/mod.conf b/mods/ITEMS/mcl_smithing_table/mod.conf new file mode 100644 index 000000000..aee93fa65 --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/mod.conf @@ -0,0 +1,2 @@ +name = mcl_smithing_table +depends = mcl_colors, mcl_formspec diff --git a/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_bottom.png b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_bottom.png new file mode 100644 index 000000000..66a1a9a7a Binary files /dev/null and b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_bottom.png differ diff --git a/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_front.png b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_front.png new file mode 100644 index 000000000..15c0a943f Binary files /dev/null and b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_front.png differ diff --git a/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_inventory.png b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_inventory.png new file mode 100644 index 000000000..fdbb706d1 Binary files /dev/null and b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_inventory.png differ diff --git a/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_side.png b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_side.png new file mode 100644 index 000000000..37458771d Binary files /dev/null and b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_side.png differ diff --git a/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_top.png b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_top.png new file mode 100644 index 000000000..2ec0468c7 Binary files /dev/null and b/mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_top.png differ diff --git a/mods/ITEMS/mcl_smoker/init.lua b/mods/ITEMS/mcl_smoker/init.lua index e45a2712c..696df4917 100644 --- a/mods/ITEMS/mcl_smoker/init.lua +++ b/mods/ITEMS/mcl_smoker/init.lua @@ -288,7 +288,8 @@ local function smoker_node_timer(pos, elapsed) -- Cooking -- - local el = elapsed_game_time + -- Run the smoker at twice the speed of a furnace. + local el = elapsed_game_time * 2 -- Check if we have cookable content: cookable local aftercooked @@ -329,13 +330,12 @@ local function smoker_node_timer(pos, elapsed) elseif active then el = math.min(el, fuel_totaltime - fuel_time) -- The furnace is currently active and has enough fuel - fuel_time = ( fuel_time + el ) * 2 + fuel_time = fuel_time + el end -- If there is a cookable item then check if it is ready yet if cookable and active then - -- In the src_time variable, the *2 is the multiplication that makes the smoker work faster than a normal furnace. - src_time = (src_time + el)*2 + src_time = src_time + el -- Place result in dst list if done if src_time >= cooked.time then inv:add_item("dst", cooked.item) diff --git a/mods/ITEMS/mcl_smoker/locale/mcl_smoker.fr.tr b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.fr.tr new file mode 100644 index 000000000..55f6a2ba8 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.fr.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_smoker +Inventory=Inventaire +Smoker=Fumoir +Cooks food faster than furnace=Cuit la nourriture plus vite qu'un fourneau +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Utiliser le livre de recettes pour voir ce que vous pouvez fondre, ce que vous pouvez utiliser comme combustible et combien de temps ça va brûler. +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=Utiliser le fourneau pour ouvrir le menu.\nPlacer le combustible dans la case en bas et le matériau source dans la case du haut.\nLe fourneau utilisera son combustible pour fondre lentement l'objet.\nLe résultat sera placé dans la case de sortie à droite. +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=Les fumoirs cuisent plusieurs objets, surtout de la nourriture crue, en de la nourriture cuite. +Burning Smoker=Fumoir actif \ No newline at end of file diff --git a/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ja.tr b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ja.tr new file mode 100644 index 000000000..9c058c713 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_smoker +Inventory=インベントリ +Smoker=燻製器 +Cooks food faster than furnace=食料はかまどより早く調理可能 +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=レシピ本を使って、何を製錬できるか、何を燃料にできるか、どれくらい燃えるかを確認しましょう。 +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=かまどを使用してかまどのメニューを開きます。かまどの燃料を下スロットに、素材を上スロットに入れます。かまどはゆっくりと燃料を使い、アイテムを製錬します。製錬結果は右側の出力スロットに置かれます。 +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=燻製器は、生ものを中心とした数種類を調理品に仕上げますが、普通のかまどの2倍早く調理します。 +Burning Smoker=燻製器 燃焼中 diff --git a/mods/ITEMS/mcl_smoker/locale/template.txt b/mods/ITEMS/mcl_smoker/locale/template.txt new file mode 100644 index 000000000..dcf0be9b3 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/template.txt @@ -0,0 +1,8 @@ +# textdomain: mcl_smoker +Inventory= +Smoker= +Cooks food faster than furnace= +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.= +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.= +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.= +Burning Smoker= diff --git a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ja.tr b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ja.tr new file mode 100644 index 000000000..e2fa7d1dd --- /dev/null +++ b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ja.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_sponges +Sponge=スポンジ +Sponges are blocks which remove water around them when they are placed or come in contact with water, turning it into a wet sponge.=スポンジは、水に置いたり触れたりすると周囲の水分を奪い、濡れたスポンジに変化するブロックです。 +Waterlogged Sponge=水を吸ったスポンジ +A waterlogged sponge can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of a furnace, the water will pour into the bucket.=水を吸ったスポンジをかまどの中で乾燥させると、(乾いた)スポンジになります。かまどの燃料スロットに空のバケツがあると、バケツに水が流れ込みます。 +Riverwaterlogged Sponge=河川水を吸ったスポンジ +This is a sponge soaking wet with river water. It can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of the furnace, the river water will pour into the bucket.=河川水で濡れたスポンジです。かまどで乾燥させれば、(乾いた)スポンジになります。かまどの燃料スロットに空のバケツがあると、河川水がバケツに流れ込みます。 +A sponge becomes riverwaterlogged (instead of waterlogged) if it sucks up more river water than (normal) water.=スポンジが(通常の)水よりも河川水を多く吸い込むと、(水ではなく)河川水を吸った状態になります。 +Removes water on contact=接触している水を除去 +Can be dried in furnace=かまどで乾燥可能 diff --git a/mods/ITEMS/mcl_spyglass/init.lua b/mods/ITEMS/mcl_spyglass/init.lua new file mode 100644 index 000000000..fa1a82339 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/init.lua @@ -0,0 +1,73 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_tool("mcl_spyglass:spyglass",{ + description = S("Spyglass"), + _doc_items_longdesc = S("A spyglass is an item that can be used for zooming in on specific locations."), + inventory_image = "mcl_spyglass.png", + stack_max = 1, + _mcl_toollike_wield = true, +}) + +minetest.register_craft({ + output = "mcl_spyglass:spyglass", + recipe = { + {"mcl_amethyst:amethyst_shard"}, + {"mcl_copper:copper_ingot"}, + {"mcl_copper:copper_ingot"}, + } +}) + +local spyglass_scope = {} + +local function add_scope(player) + local wielditem = player:get_wielded_item() + if wielditem:get_name() == "mcl_spyglass:spyglass" then + spyglass_scope[player] = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -100, y = -100}, + text = "mcl_spyglass_scope.png", + }) + player:hud_set_flags({wielditem = false}) + end +end + +local function remove_scope(player) + if spyglass_scope[player] then + player:hud_remove(spyglass_scope[player]) + spyglass_scope[player] = nil + player:hud_set_flags({wielditem = true}) + player:set_fov(86.1) + end +end + +controls.register_on_press(function(player, key) + if key ~= "RMB" then return end + add_scope(player) +end) + +controls.register_on_release(function(player, key, time) + if key ~= "RMB" then return end + remove_scope(player) +end) + +controls.register_on_hold(function(player, key, time) + if key ~= "RMB" then return end + local wielditem = player:get_wielded_item() + if wielditem:get_name() == "mcl_spyglass:spyglass" then + player:set_fov(8, false, 0.1) + if spyglass_scope[player] == nil then + add_scope(player) + end + else + remove_scope(player) + end +end) + +minetest.register_on_dieplayer(function(player) + remove_scope(player) +end) + +minetest.register_on_leaveplayer(function(player) + spyglass_scope[player] = nil +end) diff --git a/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.fr.tr b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.fr.tr new file mode 100644 index 000000000..ecd181146 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.fr.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass=Longue-vue +A spyglass is an item that can be used for zooming in on specific locations.=Une longue-vue peut être utilisée pour zoomer sur des endroits spécifiques. diff --git a/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ja.tr b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ja.tr new file mode 100644 index 000000000..9c132604e --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass=望遠鏡 +A spyglass is an item that can be used for zooming in on specific locations.=望遠鏡は、特定の場所を拡大して見るためのアイテムです。 diff --git a/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ru.tr b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ru.tr new file mode 100644 index 000000000..32b7fa96a --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ru.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass=Подзорная труба +A spyglass is an item that can be used for zooming in on specific locations.=Подзорная труба это предмет который позволяет смотреть вдаль. \ No newline at end of file diff --git a/mods/ITEMS/mcl_spyglass/locale/template.txt b/mods/ITEMS/mcl_spyglass/locale/template.txt new file mode 100644 index 000000000..606b46455 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass= +A spyglass is an item that can be used for zooming in on specific locations.= diff --git a/mods/ITEMS/mcl_spyglass/mod.conf b/mods/ITEMS/mcl_spyglass/mod.conf new file mode 100644 index 000000000..c13b281e1 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/mod.conf @@ -0,0 +1,4 @@ +name = mcl_spyglass +author = NO11 +description = This mod adds a spyglass, which is an item that can be used for zooming in on specific locations. +depends = mcl_core, controls diff --git a/mods/ITEMS/mcl_spyglass/textures/mcl_spyglass.png b/mods/ITEMS/mcl_spyglass/textures/mcl_spyglass.png new file mode 100644 index 000000000..cc5eb4d96 Binary files /dev/null and b/mods/ITEMS/mcl_spyglass/textures/mcl_spyglass.png differ diff --git a/mods/ITEMS/mcl_spyglass/textures/mcl_spyglass_scope.png b/mods/ITEMS/mcl_spyglass/textures/mcl_spyglass_scope.png new file mode 100644 index 000000000..041a88feb Binary files /dev/null and b/mods/ITEMS/mcl_spyglass/textures/mcl_spyglass_scope.png differ diff --git a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.fr.tr b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.fr.tr index 4892122f6..5098986bb 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 Granit -Granite Slab=Dalle en Granit -Double Granite Slab=Double Dalle en Granit +Granite Stairs=Escalier en Granite +Granite Slab=Dalle en Granite +Double Granite Slab=Double Dalle en Granite Diorite Stairs=Escalier en Diorite Diorite Slab=Dalle en Diorite Double Diorite Slab=Double Dalle en Diorite @@ -90,12 +90,15 @@ Double Dark Prismarine Slab=Double Dalle en Prismarine Sombre Polished Andesite Slab=Dalle en Andésite Polie Double Polished Andesite Slab=Double Dalle en Andésite Polie Polished Andesite Stairs=Escalier en Andésite Polie -Polished Granite Slab=Dalle en Granit Poli -Double Polished Granite Slab=Double Dalle en Granit Poli -Polished Granite Stairs=Escalier en Granit Poli +Polished Granite Slab=Dalle en Granite Poli +Double Polished Granite Slab=Double Dalle en Granite Poli +Polished Granite Stairs=Escalier en Granite Poli Polished Diorite Slab=Dalle en Diorite Polie Double Polished Diorite Slab=Double Dalle en Diorite Polie Polished Diorite Stairs=Escalier en Diorite Polie Mossy Stone Brick Stairs=Escalier en Pierre Taillée Moussue Mossy Stone Brick Slab=Dalle en Pierre Taillée Moussue Double Mossy Stone Brick Slab=Double Dalle en Pierre Taillée Moussue +Mud Brick Stair=Escalier en Briques de Boue +Mud Brick Slab=Dalle en Briques de Boue +Double Mud Brick Slab=Double Dalle en Briques de Boue \ No newline at end of file diff --git a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ja.tr b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ja.tr new file mode 100644 index 000000000..630f382e9 --- /dev/null +++ b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ja.tr @@ -0,0 +1,104 @@ +# textdomain: mcl_stairs +Stairs are useful to reach higher places by walking over them; jumping is not required. Placing stairs in a corner pattern will create corner stairs. Stairs placed on the ceiling or at the upper half of the side of a block will be placed upside down.=階段は、その上を歩いて高いところに行くのに便利なものです(ジャンプは不要)。階段を隅に配置すると、隅階段になります。天井やブロックの側面の上半分に階段を設置すると、逆さまに設置されます。 +Double @1=2重 @1 +Slabs are half as high as their full block counterparts and occupy either the lower or upper part of a block, depending on how it was placed. Slabs can be easily stepped on without needing to jump. When a slab is placed on another slab of the same type, a double slab is created.=スラブは、高さがフルブロックの半分で、配置によってブロックの下部または上部を占めます。スラブはジャンプすることなく簡単に登れます。スラブの上に同種のスラブを置くと、2重スラブになります。 +Upper @1=上部 @1 +Double slabs are full blocks which are created by placing two slabs of the same kind on each other.=2重スラブとは、同種のスラブを2枚重ねて作るフルブロックのことです。 +Oak Wood Stairs=オーク材の階段 +Oak Wood Slab=オーク材のスラブ +Double Oak Wood Slab=オーク材2重スラブ +Jungle Wood Stairs=ジャングル材の階段 +Jungle Wood Slab=ジャングル材のスラブ +Double Jungle Wood Slab=ジャングル材の2重スラブ +Acacia Wood Stairs=アカシア材の階段 +Acacia Wood Slab=アカシア材のスラブ +Double Acacia Wood Slab=アカシア材の2重スラブ +Spruce Wood Stairs=トウヒ材の階段 +Spruce Wood Slab=トウヒ材のスラブ +Double Spruce Wood Slab=トウヒ材の2重スラブ +Birch Wood Stairs=シラカバ材の階段 +Birch Wood Slab=シラカバ材のスラブ +Double Birch Wood Slab=シラカバ材の2重スラブ +Dark Oak Wood Stairs=ダークオーク材の階段 +Dark Oak Wood Slab=ダークオーク材のスラブ +Double Dark Oak Wood Slab=ダークオーク材の2重スラブ +Stone Stairs=石の階段 +Stone Slab=石のスラブ +Double Stone Slab=石の2重スラブ +Polished Stone Slab=研がれた石のスラブ +Double Polished Stone Slab=研がれた石の2重スラブ +Andesite Stairs=安山岩の階段 +Andesite Slab=安山岩のスラブ +Double Andesite Slab=安山岩の2重スラブ +Granite Stairs=花崗岩の階段 +Granite Slab=花崗岩のスラブ +Double Granite Slab=花崗岩の2重スラブ +Diorite Stairs=閃緑岩の階段 +Diorite Slab=閃緑岩のスラブ +Double Diorite Slab=閃緑岩の2重スラブ +Cobblestone Stairs=丸石の階段 +Cobblestone Slab=丸石のスラブ +Double Cobblestone Slab=丸石の2重スラブ +Mossy Cobblestone Stairs=苔むした丸石の階段 +Mossy Cobblestone Slab=苔むした丸石のスラブ +Double Mossy Cobblestone Slab=苔むした丸石の2重スラブ +Brick Stairs=レンガの階段 +Brick Slab=レンガのスラブ +Double Brick Slab=レンガの2重スラブ +Sandstone Stairs=砂岩の階段 +Sandstone Slab=砂岩のスラブ +Double Sandstone Slab=砂岩の2重スラブ +Smooth Sandstone Stairs=滑らかな砂岩の階段 +Smooth Sandstone Slab=滑らかな砂岩のスラブ +Double Smooth Sandstone Slab=滑らかな砂岩の2重スラブ +Red Sandstone Stairs=赤い砂岩の階段 +Red Sandstone Slab=赤い砂岩のスラブ +Double Red Sandstone Slab=赤い砂岩の2重スラブ +Smooth Red Sandstone Stairs=滑らかな赤い砂岩の階段 +Smooth Red Sandstone Slab=滑らかな赤い砂岩のスラブ +Double Smooth Red Sandstone Slab=滑らかな赤い砂岩の2重スラブ +Stone Bricks Stairs=石レンガの階段 +Stone Bricks Slab=石レンガのスラブ +Double Stone Bricks Slab=石レンガの2重スラブ +Quartz Stairs=クォーツの階段 +Quartz Slab=クォーツのスラブ +Double Quartz Slab=クォーツの2重スラブ +Smooth Quartz Stairs=滑らかなクォーツの階段 +Smooth Quartz Slab=滑らかなクォーツのスラブ +Double Smooth Quartz Slab=滑らかなクォーツの2重スラブ +Nether Brick Stairs=ネザーレンガの階段 +Nether Brick Slab=ネザーレンガのスラブ +Double Nether Brick Slab=ネザーレンガの2重スラブ +Red Nether Brick Stairs=赤いネザーレンガの階段 +Red Nether Brick Slab=赤いネザーレンガのスラブ +Double Red Nether Brick Slab=赤いネザーレンガの2重スラブ +End Stone Brick Stairs=エンドストーンレンガの階段 +End Stone Brick Slab=エンドストーンレンガのスラブ +Double End Stone Brick Slab=エンドストーンレンガの2重スラブ +Purpur Stairs=プルプァの階段 +Purpur Slab=プルプァのスラブ +Double Purpur Slab=プルプァの2重スラブ +Prismarine Stairs=プリズマリンの階段 +Prismarine Slab=プリズマリンのスラブ +Double Prismarine Slab=プリズマリンの2重スラブ +Prismarine Brick Stairs=プリズマリンレンガの階段 +Prismarine Brick Slab=プリズマリンレンガのスラブ +Double Prismarine Brick Slab=プリズマリンレンガの2重スラブ +Dark Prismarine Stairs=暗色プリズマリンの階段 +Dark Prismarine Slab=暗色プリズマリンのスラブ +Double Dark Prismarine Slab=暗色プリズマリンの2重スラブ +Polished Andesite Slab=研がれた安山岩のスラブ +Double Polished Andesite Slab=研がれた安山岩の2重スラブ +Polished Andesite Stairs=研がれた安山岩の階段 +Polished Granite Slab=研がれた花崗岩のスラブ +Double Polished Granite Slab=研がれた花崗岩の2重スラブ +Polished Granite Stairs=研がれた花崗岩の階段 +Polished Diorite Slab=研がれた閃緑岩のスラブ +Double Polished Diorite Slab=研がれた閃緑岩の2重スラブ +Polished Diorite Stairs=研がれた閃緑岩の階段 +Mossy Stone Brick Stairs=苔むした石レンガの階段 +Mossy Stone Brick Slab=苔むした石レンガのスラブ +Double Mossy Stone Brick Slab=苔むした石レンガの2重スラブ +Mud Brick Stair=泥レンガの階段 +Mud Brick Slab=泥レンガのスラブ +Double Mud Brick Slab=泥レンガの2重スラブ \ No newline at end of file diff --git a/mods/ITEMS/mcl_stairs/locale/template.txt b/mods/ITEMS/mcl_stairs/locale/template.txt index 0638af3db..dfacc1b5c 100644 --- a/mods/ITEMS/mcl_stairs/locale/template.txt +++ b/mods/ITEMS/mcl_stairs/locale/template.txt @@ -99,3 +99,6 @@ Polished Diorite Stairs= Mossy Stone Brick Stairs= Mossy Stone Brick Slab= Double Mossy Stone Brick Slab= +Mud Brick Stair= +Mud Brick Slab= +Double Mud Brick Slab= \ No newline at end of file diff --git a/mods/ITEMS/mcl_stairs/mod.conf b/mods/ITEMS/mcl_stairs/mod.conf index a357c2c79..2fb3180b2 100644 --- a/mods/ITEMS/mcl_stairs/mod.conf +++ b/mods/ITEMS/mcl_stairs/mod.conf @@ -1,2 +1,2 @@ name = mcl_stairs -depends = mcl_core, mcl_sounds, mcl_nether, mcl_end, mcl_ocean +depends = mcl_core, mcl_sounds, mcl_nether, mcl_end, mcl_ocean, mcl_mud diff --git a/mods/ITEMS/mcl_stairs/register.lua b/mods/ITEMS/mcl_stairs/register.lua index 5de380585..eee4c5dc2 100644 --- a/mods/ITEMS/mcl_stairs/register.lua +++ b/mods/ITEMS/mcl_stairs/register.lua @@ -138,6 +138,8 @@ mcl_stairs.register_slab("purpur_block", "group:purpur_block", mcl_stairs.register_stair_and_slab_simple("prismarine", "mcl_ocean:prismarine", S("Prismarine Stairs"), S("Prismarine Slab"), S("Double Prismarine Slab")) +mcl_stairs.register_stair_and_slab_simple("mud_brick", "mcl_mud:mud_bricks", S("Mud Brick Stair"), S("Mud Brick Slab"), S("Double Mud Brick Slab")) + mcl_stairs.register_stair_and_slab_simple("prismarine_brick", "mcl_ocean:prismarine_brick", S("Prismarine Brick Stairs"), S("Prismarine Brick Slab"), S("Double Prismarine Brick Slab")) mcl_stairs.register_stair_and_slab_simple("prismarine_dark", "mcl_ocean:prismarine_dark", S("Dark Prismarine Stairs"), S("Dark Prismarine Slab"), S("Double Dark Prismarine Slab")) diff --git a/mods/ITEMS/mcl_stonecutter/README.md b/mods/ITEMS/mcl_stonecutter/README.md new file mode 100644 index 000000000..c6316a5a2 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/README.md @@ -0,0 +1,17 @@ +mcl_stonecutter +=============== +Adds the stonecutter block. Used to cut stone like materials into stairs, slabs, etc. Also used as the Stone Mason Villager's jobsite. + +License of code +--------------- +See the main MineClone 2 README.md file. +Author: PrairieWind + +License of media +---------------- +mcl_stonecutter_bottom.png +mcl_stonecutter_side.png +mcl_stonecutter_top.png +mcl_stonecutter_saw.png +License: CC0 1.0 Universal (CC0 1.0) +Author: RandomLegoBrick diff --git a/mods/ITEMS/mcl_stonecutter/init.lua b/mods/ITEMS/mcl_stonecutter/init.lua new file mode 100644 index 000000000..e75884990 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/init.lua @@ -0,0 +1,58 @@ +--||||||||||||||||||||||| +--||||| STONECUTTER ||||| +--||||||||||||||||||||||| + +-- TO-DO: +-- * Add GUI + +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_node("mcl_stonecutter:stonecutter", { + description = S("Stone Cutter"), + _tt_help = S("Used to cut stone like materials."), + _doc_items_longdesc = S("Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager."), + tiles = { + "mcl_stonecutter_top.png", + "mcl_stonecutter_bottom.png", + "mcl_stonecutter_side.png", + "mcl_stonecutter_side.png", + {name="mcl_stonecutter_saw.png", + animation={ + type="vertical_frames", + aspect_w=16, + aspect_h=16, + length=1 + }}, + {name="mcl_stonecutter_saw.png", + animation={ + type="vertical_frames", + aspect_w=16, + aspect_h=16, + length=1 + }} + }, + use_texture_alpha = "clip", + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = { pickaxey=1, material_stone=1 }, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.0625, 0.5}, -- NodeBox1 + {-0.4375, 0.0625, 0, 0.4375, 0.5, 0}, -- NodeBox2 + } + }, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + sounds = mcl_sounds.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "mcl_stonecutter:stonecutter", + recipe = { + { "", "", "" }, + { "", "mcl_core:iron_ingot", "" }, + { "mcl_core:stone", "mcl_core:stone", "mcl_core:stone" }, + } +}) diff --git a/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.fr.tr b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.fr.tr new file mode 100644 index 000000000..415093305 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_stonecutter +Stone Cutter=Tailleur de pierre +Used to cut stone like materials.=utilisé pour couper les matériaux similaires à la pierre. +Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager.=Les tailleurs de pierre sont utilisés pour créer des escaliers et dalles à partir de matériaux similaires à la pierre. C'est aussi le poste de travail du villageois maçon. diff --git a/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ja.tr b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ja.tr new file mode 100644 index 000000000..d26819d64 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_stonecutter +Stone Cutter=ストーンカッター +Used to cut stone like materials.=石のような素材を切断するのに使用します。 +Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager.=ストーンカッターは、石のような素材から階段やスラブを作れます。石工の村人の仕事場でもあります。 diff --git a/mods/ITEMS/mcl_stonecutter/locale/template.txt b/mods/ITEMS/mcl_stonecutter/locale/template.txt new file mode 100644 index 000000000..d9bd51c32 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: mcl_stonecutter +Stone Cutter= +Used to cut stone like materials.= +Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager.= diff --git a/mods/ITEMS/mcl_stonecutter/mod.conf b/mods/ITEMS/mcl_stonecutter/mod.conf new file mode 100644 index 000000000..d9781e474 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/mod.conf @@ -0,0 +1,4 @@ +name = mcl_stonecutter +author = PrairieWind +description = This mod adds a stonecutter, which is used to cut stone like materials, and used as the jobsite for the Stone Mason Villager. +depends = mcl_sounds diff --git a/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_bottom.png b/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_bottom.png new file mode 100644 index 000000000..7467d42be Binary files /dev/null and b/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_bottom.png differ diff --git a/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_saw.png b/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_saw.png new file mode 100644 index 000000000..0f2bc3dfc Binary files /dev/null and b/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_saw.png differ diff --git a/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_side.png b/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_side.png new file mode 100644 index 000000000..d97f84bae Binary files /dev/null and b/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_side.png differ diff --git a/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_top.png b/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_top.png new file mode 100644 index 000000000..0b63cb112 Binary files /dev/null and b/mods/ITEMS/mcl_stonecutter/textures/mcl_stonecutter_top.png differ diff --git a/mods/ITEMS/mcl_sus_stew/LICENSE b/mods/ITEMS/mcl_sus_stew/LICENSE new file mode 100644 index 000000000..d41c0bd98 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/LICENSE @@ -0,0 +1,232 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . + +The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . diff --git a/mods/ITEMS/mcl_sus_stew/Note b/mods/ITEMS/mcl_sus_stew/Note new file mode 100644 index 000000000..cbf07b1f8 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/Note @@ -0,0 +1 @@ +The texture for the suspicious stew is from the Minecraft resourcepack "Pixel Perfection Legacy" (https://www.curseforge.com/minecraft/texture-packs/pixel-perfection-legacy), wich is licensed under CC BY-SA 4.0 (Creative Commons license)! \ No newline at end of file diff --git a/mods/ITEMS/mcl_sus_stew/README.md b/mods/ITEMS/mcl_sus_stew/README.md new file mode 100644 index 000000000..374d80b92 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/README.md @@ -0,0 +1,3 @@ +# mcl_sus_stew + +This Mod adds Suspicious Stews for Mineclone \ No newline at end of file diff --git a/mods/ITEMS/mcl_sus_stew/init.lua b/mods/ITEMS/mcl_sus_stew/init.lua new file mode 100644 index 000000000..b605b8a45 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/init.lua @@ -0,0 +1,142 @@ + +-- ____________________________ +--_________________________________________/ Variables & Functions \_________ + +local eat = minetest.item_eat(6, "mcl_core:bowl") --6 hunger points, player receives mcl_core:bowl after eating + +local flower_effect = { + [ "mcl_flowers:allium" ] = "fire_resistance", + [ "mcl_flowers:tulip_white" ] = "poison", + [ "mcl_flowers:blue_orchid" ] = "hunger", + [ "mcl_flowers:dandelion" ] = "hunger", + [ "mcl_flowers:peony" ] = "jump", + [ "mcl_flowers:oxeye_daisy" ] = "regeneration", + [ "mcl_flowers:poppy" ] = "night_vision" +} + +local effects = { + [ "fire_resistance" ] = function(itemstack, placer, pointed_thing) + mcl_potions.fire_resistance_func(placer, 1, 4) + return eat(itemstack, placer, pointed_thing) + end, + [ "poison" ] = function(itemstack, placer, pointed_thing) + mcl_potions.poison_func(placer, 1, 12) + return eat(itemstack, placer, pointed_thing) + end, + + [ "hunger" ] = function(itemstack, placer, pointed_thing, player) + mcl_hunger.item_eat(6, "mcl_core:bowl", 3.5, 0, 100) + return eat(itemstack, placer, pointed_thing) + end, + + ["jump"] = function(itemstack, placer, pointed_thing) + mcl_potions.leaping_func(placer, 1, 6) + return eat(itemstack, placer, pointed_thing) + end, + + ["regeneration"] = function(itemstack, placer, pointed_thing) + mcl_potions.regeneration_func(placer, 1, 8) + return eat(itemstack, placer, pointed_thing) + end, + + ["night_vision"] = function(itemstack, placer, pointed_thing) + mcl_potions.night_vision_func(placer, 1, 5) + return eat(itemstack, placer, pointed_thing) + end, +} +local function get_random_effect() + local keys = {} + for k in pairs(effects) do + table.insert(keys, k) + end + return effects[keys[math.random(#keys)]] +end + +local function eat_stew(itemstack, placer, pointed_thing) + local e = itemstack:get_meta():get_string("effect") + local f = effects[e] + if not f then + f = get_random_effect() + end + if f(itemstack,placer,pointed_thing) then + return "mcl_core:bowl" + end +end + +minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) + if itemstack:get_name() ~= "mcl_sus_stew:stew" then return end + for f,e in pairs(flower_effect) do + for _,it in pairs(old_craft_grid) do + if it:get_name() == f then + itemstack:get_meta():set_string("effect",e) + return itemstack + end + end + end +end) + +-- ________________________ +--_________________________________________/ Item Regestration \_________________ +minetest.register_craftitem("mcl_sus_stew:stew",{ + description = "Suspicious Stew", + inventory_image = "sus_stew.png", + stack_max = 1, + on_place = eat_stew, + on_secondary_use = eat_stew, + groups = { food = 2, eatable = 4, can_eat_when_full = 1, not_in_creative_inventory=1,}, + _mcl_saturation = 7.2, +}) + +mcl_hunger.register_food("mcl_sus_stew:stew",6, "mcl_core:bowl") + +--compat with old (mcl5) sus_stew +minetest.register_alias("mcl_sus_stew:poison_stew", "mcl_sus_stew:stew") +minetest.register_alias("mcl_sus_stew:hunger_stew", "mcl_sus_stew:stew") +minetest.register_alias("mcl_sus_stew:jump_boost_stew", "mcl_sus_stew:stew") +minetest.register_alias("mcl_sus_stew:regneration_stew", "mcl_sus_stew:stew") +minetest.register_alias("mcl_sus_stew:night_vision_stew", "mcl_sus_stew:stew") + +-- ______________ +--_________________________________________/ Crafts \________________________________ + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:allium"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:tulip_white"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:blue_orchid"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:dandelion"} , +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:peony"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:oxeye_daisy"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:poppy"}, +}) diff --git a/mods/ITEMS/mcl_sus_stew/mod.conf b/mods/ITEMS/mcl_sus_stew/mod.conf new file mode 100644 index 000000000..c67a120ba --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/mod.conf @@ -0,0 +1,3 @@ +name = mcl_sus_stew +author = chmodsayshello, cora +depends = mcl_core, mcl_mushrooms, mcl_flowers, mcl_potions, mcl_hunger diff --git a/mods/ITEMS/mcl_sus_stew/textures/sus_stew.png b/mods/ITEMS/mcl_sus_stew/textures/sus_stew.png new file mode 100644 index 000000000..3580c35aa Binary files /dev/null and b/mods/ITEMS/mcl_sus_stew/textures/sus_stew.png differ diff --git a/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ja.tr b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ja.tr new file mode 100644 index 000000000..983002598 --- /dev/null +++ b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ja.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_throwing +@1 used the ender pearl too often.=@1 はエンダーパールを使いすぎました。 +Use the punch key to throw.=「パンチ」キーで投げる。 +Snowball=雪玉 +Snowballs can be thrown or launched from a dispenser for fun. Hitting something with a snowball does nothing.=雪玉は、投げたりディスペンサーから発射したりして楽しめます。雪玉を何かにぶつけても何も起こりません。 +Egg=卵 +Eggs can be thrown or launched from a dispenser and breaks on impact. There is a small chance that 1 or even 4 chicks will pop out of the egg.=卵は投げたりディスペンサーから発射したりでき、衝撃で割れます。 卵からヒナが 1 ~ 4 羽飛び出す可能性がわずかにあります。 +Ender Pearl=エンダーパール +An ender pearl is an item which can be used for teleportation at the cost of health. It can be thrown and teleport the thrower to its impact location when it hits a solid block or a plant. Each teleportation hurts the user by 5 hit points.=エンダーパールは、ヘルスを消費してテレポートができるアイテムです。投げることができ、固体ブロックや植物にぶつかると、投擲者がその衝突した場所にテレポートします。テレポートするたびに、使用者は5ヒットポイントずつダメージを受けます。 +Throwable=投擲可能 +Chance to hatch chicks when broken=壊れてもヒナが孵化するチャンス +Teleports you on impact for cost of 5 HP=HPを5消費し衝撃でテレポート diff --git a/mods/ITEMS/mcl_throwing/register.lua b/mods/ITEMS/mcl_throwing/register.lua index 413bc9d5f..43dedd33b 100644 --- a/mods/ITEMS/mcl_throwing/register.lua +++ b/mods/ITEMS/mcl_throwing/register.lua @@ -61,11 +61,9 @@ local function check_object_hit(self, pos, dmg) and entity.name ~= self.object:get_luaentity().name then if object:is_player() and self._thrower ~= object:get_player_name() then - -- TODO: Deal knockback self.object:remove() return true elseif (entity.is_mob == true or entity._hittable_by_projectile) and (self._thrower ~= object) then - -- FIXME: Knockback is broken object:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = dmg, @@ -142,24 +140,8 @@ local function egg_on_step(self, dtime) -- FIXME: Chicks have a quite good chance to spawn in walls local r = math.random(1,8) - -- Turn given object into a child - 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 }, - collisionbox = { - ent.base_colbox[1]/2, - ent.base_colbox[2]/2, - ent.base_colbox[3]/2, - ent.base_colbox[4]/2, - ent.base_colbox[5]/2, - ent.base_colbox[6]/2, - } - }) - ent.child = true - end if r == 1 then - make_child(minetest.add_entity(self._lastpos, "mobs_mc:chicken")) + mcl_mobs.spawn_child(self._lastpos, "mobs_mc:chicken") -- BONUS ROUND: 1/32 chance to spawn 3 additional chicks local r = math.random(1,32) @@ -171,7 +153,7 @@ local function egg_on_step(self, dtime) } for o=1, 3 do local pos = vector.add(self._lastpos, offsets[o]) - make_child(minetest.add_entity(pos, "mobs_mc:chicken")) + mcl_mobs.spawn_child(pos, "mobs_mc:chicken") end end end @@ -185,7 +167,7 @@ local function egg_on_step(self, dtime) end -- Destroy when hitting a mob or player (no chick spawning) - if check_object_hit(self, pos) then + if check_object_hit(self, pos, 0) then minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) self.object:remove() return diff --git a/mods/ITEMS/mcl_tnt/init.lua b/mods/ITEMS/mcl_tnt/init.lua index bf7b52385..83c962092 100644 --- a/mods/ITEMS/mcl_tnt/init.lua +++ b/mods/ITEMS/mcl_tnt/init.lua @@ -1,15 +1,25 @@ 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) - minetest.sound_play("tnt_ignite", {pos = pos,gain = 1.0,max_hear_distance = 15,}, true) - local tnt = minetest.add_entity(pos, entname) - tnt:set_armor_groups({immortal=1}) - return tnt -end - tnt = {} +tnt.BOOMTIMER = 4 +tnt.BLINKTIMER = 0.25 + +---@param pos Vector +---@param entname string +---@return ObjectRef? +local function spawn_tnt(pos, entname) + minetest.sound_play("tnt_ignite", { pos = pos, gain = 1.0, max_hear_distance = 15 }, true) + local ent = minetest.add_entity(pos, entname) + if ent then + ent:set_armor_groups({ immortal = 1 }) + end + return ent +end + +---@param pos Vector +---@return ObjectRef? function tnt.ignite(pos) minetest.remove_node(pos) local e = spawn_tnt(pos, "mcl_tnt:tnt") @@ -17,61 +27,73 @@ function tnt.ignite(pos) return e end --- Add smoke particle of entity at pos. --- Intended to be called every step +---Add smoke particle of entity at pos. +--- +---Intended to be called every step. +---@param pos Vector function tnt.smoke_step(pos) minetest.add_particle({ - pos = {x=pos.x,y=pos.y+0.5,z=pos.z}, - velocity = vector.new(math.random() * 0.2 - 0.1, 1.0 + math.random(), math.random() * 0.2 - 0.1), - acceleration = vector.new(0, -0.1, 0), - expirationtime = 0.15 + math.random() * 0.25, - size = 1.0 + math.random(), + pos = vector.offset(pos, 0, 0.5, 0), + velocity = vector.new(math.random() * 0.2 - 0.1, 1.0 + math.random(), math.random() * 0.2 - 0.1), + acceleration = vector.new(0, -0.1, 0), + expirationtime = 0.15 + math.random() * 0.25, + size = 1.0 + math.random(), collisiondetection = false, - texture = "mcl_particles_smoke.png" + texture = "mcl_particles_smoke.png" }) end -tnt.BOOMTIMER = 4 -tnt.BLINKTIMER = 0.25 - local TNT_RANGE = 3 local sounds if minetest.get_modpath("mcl_sounds") then sounds = mcl_sounds.node_sound_wood_defaults() end + local tnt_mesecons if minetest.get_modpath("mesecons") then - tnt_mesecons = {effector = { - action_on = tnt.ignite, - rules = mesecon.rules.alldirs, - }} + tnt_mesecons = { + effector = { + action_on = tnt.ignite, + rules = mesecon.rules.alldirs, + }, + } end local longdesc if tnt_griefing then - longdesc = S("An explosive device. When it explodes, it will hurt living beings and destroy blocks around it. TNT has an explosion radius of @1. With a small chance, blocks may drop as an item (as if being mined) rather than being destroyed. TNT can be ignited by tools, explosions, fire, lava and redstone signals.", TNT_RANGE) + longdesc = S("An explosive device. When it explodes, it will hurt living beings and destroy blocks around it. TNT has an explosion radius of @1. With a small chance, blocks may drop as an item (as if being mined) rather than being destroyed. TNT can be ignited by tools, explosions, fire, lava and redstone signals." + , TNT_RANGE) else - longdesc = S("An explosive device. When it explodes, it will hurt living beings. TNT has an explosion radius of @1. TNT can be ignited by tools, explosions, fire, lava and redstone signals.", TNT_RANGE) + longdesc = S("An explosive device. When it explodes, it will hurt living beings. TNT has an explosion radius of @1. TNT can be ignited by tools, explosions, fire, lava and redstone signals." + , TNT_RANGE) end minetest.register_node("mcl_tnt:tnt", { - tiles = {"default_tnt_top.png", "default_tnt_bottom.png", - "default_tnt_side.png", "default_tnt_side.png", - "default_tnt_side.png", "default_tnt_side.png"}, + tiles = { + "default_tnt_top.png", + "default_tnt_bottom.png", + "default_tnt_side.png", + "default_tnt_side.png", + "default_tnt_side.png", + "default_tnt_side.png", + }, is_ground_content = false, stack_max = 64, description = S("TNT"), paramtype = "light", sunlight_propagates = true, - _tt_help = S("Ignited by tools, explosions, fire, lava, redstone power").."\n"..S("Explosion radius: @1", tostring(TNT_RANGE)), + _tt_help = S("Ignited by tools, explosions, fire, lava, redstone power") .. + "\n" .. S("Explosion radius: @1", tostring(TNT_RANGE)), _doc_items_longdesc = longdesc, _doc_items_usagehelp = S("Place the TNT and ignite it with one of the methods above. Quickly get in safe distance. The TNT will start to be affected by gravity and explodes in 4 seconds."), - groups = { dig_immediate = 3, tnt = 1, enderman_takable=1, flammable=-1 }, + groups = { dig_immediate = 3, tnt = 1, enderman_takable = 1, flammable = -1 }, mesecons = tnt_mesecons, - on_blast = function(pos) - local e = tnt.ignite(pos) - e:get_luaentity().timer = tnt.BOOMTIMER - (0.5 + math.random()) + on_blast = function(pos, _) + local e = tnt.ignite(pos) + if e then + e:get_luaentity().timer = tnt.BOOMTIMER - (0.5 + math.random()) + end end, _on_ignite = function(player, pointed_thing) tnt.ignite(pointed_thing.under) @@ -84,7 +106,7 @@ minetest.register_node("mcl_tnt:tnt", { _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Place and ignite TNT if minetest.registered_nodes[dropnode.name].buildable_to then - minetest.set_node(droppos, {name = stack:get_name()}) + minetest.set_node(droppos, { name = stack:get_name() }) tnt.ignite(droppos) end end, @@ -94,24 +116,30 @@ minetest.register_node("mcl_tnt:tnt", { local TNT = { -- Static definition physical = true, -- Collides with things - --weight = -100, - collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, + --weight = -100, + collisionbox = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, visual = "cube", - textures = {"default_tnt_top.png", "default_tnt_bottom.png", - "default_tnt_side.png", "default_tnt_side.png", - "default_tnt_side.png", "default_tnt_side.png"}, + textures = { + "default_tnt_top.png", + "default_tnt_bottom.png", + "default_tnt_side.png", + "default_tnt_side.png", + "default_tnt_side.png", + "default_tnt_side.png", + }, -- Initial value for our timer timer = 0, blinktimer = 0, tnt_knockback = true, - blinkstatus = true,} + blinkstatus = true, +} -function TNT:on_activate(staticdata) - local phi = math.random(0, 65535) / 65535 * 2*math.pi +function TNT:on_activate(_, _) + local phi = math.random(0, 65535) / 65535 * 2 * math.pi local hdir_x = math.cos(phi) * 0.02 local hdir_z = math.sin(phi) * 0.02 - self.object:set_velocity({x=hdir_x, y=2, z=hdir_z}) - self.object:set_acceleration({x=0, y=-10, z=0}) + self.object:set_velocity(vector.new(hdir_x, 2, hdir_z)) + self.object:set_acceleration(vector.new(0, -10, 0)) self.object:set_texture_mod("^mcl_tnt_blink.png") end @@ -121,8 +149,8 @@ end time = 0.5, minpos = vector.subtract(pos, radius / 2), maxpos = vector.add(pos, radius / 2), - minvel = {x = -10, y = -10, z = -10}, - maxvel = {x = 10, y = 10, z = 10}, + minvel = vector.new(-10, -10, -10), + maxvel = vector.new(10, 10, 10), minacc = vector.new(), maxacc = vector.new(), minexptime = 1, @@ -152,9 +180,9 @@ end time = 0.1, minpos = vector.subtract(pos, radius / 2), maxpos = vector.add(pos, radius / 2), - minvel = {x = -3, y = 0, z = -3}, - maxvel = {x = 3, y = 5, z = 3}, - minacc = {x = 0, y = -10, z = 0}, + minvel = vector.new(-3, 0, -3), + maxvel = vector.new(3, 5, 3), + minacc = vector.new(0, -10, 0), minexptime = 0.8, maxexptime = 2.0, minsize = radius * 0.66, @@ -164,7 +192,7 @@ end }) end]] -function TNT:on_step(dtime) +function TNT:on_step(dtime, _) local pos = self.object:get_pos() tnt.smoke_step(pos) self.timer = self.timer + dtime @@ -190,10 +218,10 @@ if minetest.get_modpath("mcl_mobitems") then minetest.register_craft({ output = "mcl_tnt:tnt", recipe = { - {"mcl_mobitems:gunpowder", "group:sand", "mcl_mobitems:gunpowder"}, - {"group:sand", "mcl_mobitems:gunpowder", "group:sand"}, - {"mcl_mobitems:gunpowder", "group:sand", "mcl_mobitems:gunpowder"} - } + { "mcl_mobitems:gunpowder", "group:sand", "mcl_mobitems:gunpowder" }, + { "group:sand", "mcl_mobitems:gunpowder", "group:sand" }, + { "mcl_mobitems:gunpowder", "group:sand", "mcl_mobitems:gunpowder" } + }, }) end diff --git a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ja.tr b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ja.tr new file mode 100644 index 000000000..fbb2e76b3 --- /dev/null +++ b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_tnt +@1 was caught in an explosion.=@1 は爆発に巻き込まれました。 +TNT=TNT +An explosive device. When it explodes, it will hurt living beings and destroy blocks around it. TNT has an explosion radius of @1. With a small chance, blocks may drop as an item (as if being mined) rather than being destroyed. TNT can be ignited by tools, explosions, fire, lava and redstone signals.=爆破装置です。爆発すると、生物を傷つけ、周囲のブロックを破壊します。 TNTの爆発半径は@1です。 小確率で、ブロックは破壊されずにアイテムとして(採掘されるように)ドロップすることがあります。TNTは道具、爆発、火、溶岩、レッドストーン信号で着火できます。 +An explosive device. When it explodes, it will hurt living beings. TNT has an explosion radius of @1. TNT can be ignited by tools, explosions, fire, lava and redstone signals.=爆破装置です。爆発すると、生物を傷つけます。TNTの爆発半径は@1です。 TNTは道具、爆発、火、溶岩、レッドストーン信号で着火できます。 +Place the TNT and ignite it with one of the methods above. Quickly get in safe distance. The TNT will start to be affected by gravity and explodes in 4 seconds.=TNTを設置し、上記のいずれかの方法で点火します。速やかに安全な距離をとって。TNTは重力の影響を受け始め、4秒後に爆発します。 +Ignited by tools, explosions, fire, lava, redstone power=道具、爆発、火、溶岩、レッドストーン動力で点火 +Explosion radius: @1=爆発半径: @1 diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index cbee8e3d0..860ea756c 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -25,11 +25,11 @@ local groupcaps, hand_range, hand_groups if minetest.is_creative_enabled("") then -- Instant breaking in creative mode groupcaps = { creative_breakable = { times = {0}, uses = 0 } } - hand_range = 10 + hand_range = tonumber(minetest.settings:get("mcl_hand_range_creative")) or 10 hand_groups = { dig_speed_class = 7 } else groupcaps = {} - hand_range = 4 + hand_range = tonumber(minetest.settings:get("mcl_hand_range")) or 4.5 hand_groups = { dig_speed_class = 1 } end minetest.register_tool(":", { @@ -175,9 +175,32 @@ minetest.register_tool("mcl_tools:pick_diamond", { _mcl_diggroups = { pickaxey = { speed = 8, level = 5, uses = 1562 } }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_tools:pick_netherite" }) -local function make_grass_path(itemstack, placer, pointed_thing) +minetest.register_tool("mcl_tools:pick_netherite", { + description = S("Netherite Pickaxe"), + _doc_items_longdesc = pickaxe_longdesc, + inventory_image = "default_tool_netheritepick.png", + wield_scale = wield_scale, + groups = { tool=1, pickaxe=1, dig_speed_class=6, enchantability=10, fire_immune=1 }, + tool_capabilities = { + -- 1/1.2 + full_punch_interval = 0.83333333, + max_drop_level=5, + damage_groups = {fleshy=6}, + punch_attack_uses = 1016, + }, + sound = { breaks = "default_tool_breaks" }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 9.5, level = 6, uses = 2031 } + }, +}) + +local make_grass_path = function(itemstack, placer, pointed_thing) -- Use pointed node's on_rightclick function first, if present local node = minetest.get_node(pointed_thing.under) if placer and not placer:get_player_control().sneak then @@ -265,7 +288,7 @@ minetest.register_tool("mcl_tools:shovel_wood", { _repair_material = "group:wood", _mcl_toollike_wield = true, _mcl_diggroups = { - shovely = { speed = 2, level = 1, uses = 60 } + shovely = { speed = 2, level = 2, uses = 60 } }, }) minetest.register_tool("mcl_tools:shovel_stone", { @@ -351,6 +374,30 @@ minetest.register_tool("mcl_tools:shovel_diamond", { _mcl_diggroups = { shovely = { speed = 8, level = 5, uses = 1562 } }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_tools:shovel_netherite" +}) + +minetest.register_tool("mcl_tools:shovel_netherite", { + description = S("Netherite Shovel"), + _doc_items_longdesc = shovel_longdesc, + _doc_items_usagehelp = shovel_use, + inventory_image = "default_tool_netheriteshovel.png", + wield_scale = wield_scale, + groups = { tool=1, shovel=1, dig_speed_class=6, enchantability=10, fire_immune=1 }, + tool_capabilities = { + full_punch_interval = 1, + max_drop_level=5, + damage_groups = {fleshy=5}, + punch_attack_uses = 1016, + }, + on_place = make_grass_path, + sound = { breaks = "default_tool_breaks" }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 9, level = 6, uses = 2031 } + }, }) -- Axes @@ -483,6 +530,29 @@ minetest.register_tool("mcl_tools:axe_diamond", { _mcl_diggroups = { axey = { speed = 8, level = 5, uses = 1562 } }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_tools:axe_netherite" +}) + +minetest.register_tool("mcl_tools:axe_netherite", { + description = S("Netherite Axe"), + _doc_items_longdesc = axe_longdesc, + inventory_image = "default_tool_netheriteaxe.png", + wield_scale = wield_scale, + groups = { tool=1, axe=1, dig_speed_class=6, enchantability=10, fire_immune=1 }, + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=5, + damage_groups = {fleshy=10}, + punch_attack_uses = 1016, + }, + on_place = make_stripped_trunk, + sound = { breaks = "default_tool_breaks" }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 9, level = 6, uses = 2031 } + }, }) -- Swords @@ -586,6 +656,28 @@ minetest.register_tool("mcl_tools:sword_diamond", { swordy = { speed = 8, level = 5, uses = 1562 }, swordy_cobweb = { speed = 8, level = 5, uses = 1562 } }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_tools:sword_netherite" +}) +minetest.register_tool("mcl_tools:sword_netherite", { + description = S("Netherite Sword"), + _doc_items_longdesc = sword_longdesc, + inventory_image = "default_tool_netheritesword.png", + wield_scale = wield_scale, + groups = { weapon=1, sword=1, dig_speed_class=5, enchantability=10, fire_immune=1 }, + tool_capabilities = { + full_punch_interval = 0.625, + max_drop_level=5, + damage_groups = {fleshy=9}, + punch_attack_uses = 2031, + }, + sound = { breaks = "default_tool_breaks" }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 8, level = 5, uses = 2031 }, + swordy_cobweb = { speed = 8, level = 5, uses = 2031 } + }, }) --Shears diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr index 02cd7f2bd..f01c6c4fe 100644 --- a/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr @@ -1,32 +1,36 @@ # textdomain: mcl_tools -You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.=Vous utilisez votre main nue lorsque vous ne portez aucun objet. Avec votre main, vous pouvez miner la plupart des blocs, mais c'est la méthode la plus lente et seuls les blocs les plus faibles produiront un élément utile. La main inflige également des dégâts mineurs en frappant. L'utilisation de la main est souvent un dernier recours, car les outils et les armes d'extraction appropriés sont bien meilleurs. +You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.=Vous utilisez votre main nue lorsque vous ne portez aucun objet. Avec votre main, vous pouvez miner la plupart des blocs, mais c'est la méthode la plus lente et seuls les blocs les plus faibles donneront des éléments utiles. La main inflige également des dégâts mineurs en frappant. L'utilisation de la main est souvent un dernier recours, car les outils et les armes d'extraction appropriées sont bien meilleures. When you are wielding an item which is not a mining tool or a weapon, it will behave as if it were the hand when you start mining or punching.=Lorsque vous maniez un objet qui n'est ni un outil d'extraction ni une arme, il se comportera comme s'il s'agissait de la main lorsque vous commencez à extraire ou à frapper. In Creative Mode, the hand is able to break all blocks instantly.=En mode créatif, la main est capable de briser tous les blocs instantanément. Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.=Les pioches sont des outils d'extraction pour extraire des blocs durs, comme la pierre. Une pioche peut également être utilisée comme arme, mais elle est plutôt inefficace. An axe is your tool of choice to cut down trees, wood-based blocks and other blocks. Axes deal a lot of damage as well, but they are rather slow.=Une hache est votre outil de choix pour abattre des arbres, des blocs à base de bois et d'autres blocs. Les haches infligent également beaucoup de dégâts, mais elles sont plutôt lentes. Swords are great in melee combat, as they are fast, deal high damage and can endure countless battles. Swords can also be used to cut down a few particular blocks, such as cobwebs.=Les épées sont excellentes en combat de mêlée, car elles sont rapides, infligent des dégâts élevés et peuvent supporter d'innombrables batailles. Les épées peuvent également être utilisées pour couper quelques blocs particuliers, tels que les toiles d'araignées. -Shovels are tools for digging coarse blocks, such as dirt, sand and gravel. They can also be used to turn grass blocks to grass paths. Shovels can be used as weapons, but they are very weak.=Les pelles sont des outils pour creuser des blocs grossiers, tels que la terre, le sable et le gravier. Ils peuvent également être utilisés pour transformer des blocs d'herbe en chemins de terre. Les pelles peuvent être utilisées comme armes, mais elles sont très faibles. +Shovels are tools for digging coarse blocks, such as dirt, sand and gravel. They can also be used to turn grass blocks to grass paths. Shovels can be used as weapons, but they are very weak.=Les pelles sont des outils pour creuser des blocs grossiers, tels que la terre, le sable et le gravier. Elles peuvent également être utilisées pour transformer des blocs d'herbe en chemins de terre. Les pelles peuvent être utilisées comme armes, mais elles sont très faibles. To turn a grass block into a grass path, hold the shovel in your hand, then use (rightclick) the top or side of a grass block. This only works when there's air above the grass block.=Pour transformer un bloc d'herbe en chemin de terre, tenez la pelle dans votre main, puis utilisez (clic droit) le haut ou le côté d'un bloc d'herbe. Cela ne fonctionne que lorsqu'il y a de l'air au-dessus du bloc d'herbe. Shears are tools to shear sheep and to mine a few block types. Shears are a special mining tool and can be used to obtain the original item from grass, leaves and similar blocks that require cutting.=Les cisailles sont des outils pour tondre les moutons et pour extraire quelques types de blocs. Les cisailles sont un outil d'extraction spécial et peuvent être utilisées pour obtenir l'élément d'origine à partir d'herbe, de feuilles et de blocs similaires qui nécessitent une coupe. -To shear sheep or carve faceless pumpkins, use the “place” key on them. Faces can only be carved at the side of faceless pumpkins. Mining works as usual, but the drops are different for a few blocks.=Pour tondre des moutons ou tailler des citrouilles sans visage, utilisez la touche "placer" dessus. Les visages ne peuvent être sculptés que sur le côté des citrouilles sans visage. L'exploitation minière fonctionne comme d'habitude, mais les éléments sont différentes pour quelques blocs. +To shear sheep or carve faceless pumpkins, use the “place” key on them. Faces can only be carved at the side of faceless pumpkins. Mining works as usual, but the drops are different for a few blocks.=Pour tondre des moutons ou tailler des citrouilles sans visage, utilisez la touche "placer" dessus. Les visages ne peuvent être sculptés que sur le côté des citrouilles sans visage. L'exploitation minière fonctionne comme d'habitude, mais les éléments obtenus sont différentes pour quelques blocs. Wooden Pickaxe=Pioche en Bois Stone Pickaxe=Pioche en Pierre Iron Pickaxe=Pioche en Fer Golden Pickaxe=Pioche en Or Diamond Pickaxe=Pioche en Diamant +Netherite Pickaxe=Pioche en Netherite Wooden Shovel=Pelle en Bois Stone Shovel=Pelle en Pierre Iron Shovel=Pelle en Fer Golden Shovel=Pelle en Or Diamond Shovel=Pelle en Diamant +Netherite Shovel=Pelle en Netherite Wooden Axe=Hache en Bois Stone Axe=Hache en Pierre Iron Axe=Hache en Fer Golden Axe=Hache en Or Diamond Axe=Hache en Diamant +Netherite Axe=Hache en Netherite Wooden Sword=Épée en Bois Stone Sword=Épée en Pierre Iron Sword=Épée en Fer Golden Sword=Épée en Or Diamond Sword=Épée en Diamant +Netherite Sword=Épée en Netherite Shears=Cisailles diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.ja.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.ja.tr new file mode 100644 index 000000000..063bd8a48 --- /dev/null +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.ja.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_tools +You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.=何のアイテムも用いていないときは、いつだって素手を使います。手でほとんどのブロックを採掘できますが、この方法は最も時間がかかるうえ、有用なドロップをもたらすのは脆弱なブロックだけです。また、手で殴ることで小さなダメージを与えることもできます。 適切な採掘道具や武器の方がはるかに良いので、手を使うのは往々にして最後の手段です。 +When you are wielding an item which is not a mining tool or a weapon, it will behave as if it were the hand when you start mining or punching.=採掘道具でも武器でもないアイテムを手にしている場合、パンチや採掘にとりかかると、あたかも手であるかのように振る舞います。 +In Creative Mode, the hand is able to break all blocks instantly.=クリエイティブモードでは、手ですべてのブロックを瞬時に壊せます。 +Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.=ツルハシは、石のような硬いブロックを採掘するための道具です。武器としても使えますが、効率は良くありません。 +An axe is your tool of choice to cut down trees, wood-based blocks and other blocks. Axes deal a lot of damage as well, but they are rather slow.=斧は、木や木材ベースのブロック、その他お好みのものを切り倒すための道具です。 斧もやはり多大なダメージを与えますが、やや遅めです。 +Swords are great in melee combat, as they are fast, deal high damage and can endure countless battles. Swords can also be used to cut down a few particular blocks, such as cobwebs.=剣は速く近接戦闘に優れており、高いダメージを与え、数知れない戦闘に耐えられます。また、クモの巣のような特殊なブロックを切り払うのにも使えます。 +Shovels are tools for digging coarse blocks, such as dirt, sand and gravel. They can also be used to turn grass blocks to grass paths. Shovels can be used as weapons, but they are very weak.=シャベルは、土や砂、砂利などの粗いブロックを掘るための道具です。また、草原をオフロードにすることもできます。シャベルは武器としても使えますが、とても弱いです。 +To turn a grass block into a grass path, hold the shovel in your hand, then use (rightclick) the top or side of a grass block. This only works when there's air above the grass block.=草原をオフロードに変えるには、シャベルを手に持って、草原の上か横に使用(右クリック)します。 これは草原の上に空気があるときのみ有効です。 +Shears are tools to shear sheep and to mine a few block types. Shears are a special mining tool and can be used to obtain the original item from grass, leaves and similar blocks that require cutting.=ハサミは、羊毛を刈ったり数種類のブロックを採るための道具です。 ハサミは特殊な採掘道具で、草や葉などの切断を要するブロックから、あらたなアイテムを入手するために使えます。 +To shear sheep or carve faceless pumpkins, use the “place” key on them. Faces can only be carved at the side of faceless pumpkins. Mining works as usual, but the drops are different for a few blocks.=羊毛を刈ったり、顔のないカボチャを彫ったりするには「配置」キーを使ってください。顔のないカボチャの側面にだけ、顔が彫れます。 採掘作用は普通ながらも、いくつかのブロックからは、かわったものをドロップさせます。 +Wooden PickAxe=木製のツルハシ +Stone PickAxe=石のツルハシ +Iron PickAxe=鉄のツルハシ +Golden PickAxe=金のツルハシ +Diamond PickAxe=ダイヤモンドのツルハシ +Netherite PickAxe=ネザライトのツルハシ +Wooden Shovel=木製のシャベル +Stone Shovel=石のシャベル +Iron Shovel=鉄のシャベル +Golden Shovel=金のシャベル +Diamond Shovel=ダイヤモンドのシャベル +Netherite Shovel=ネザライトのシャベル +Wooden Axe=木製の斧 +Stone Axe=石の斧 +Iron Axe=鉄の斧 +Golden Axe=金の斧 +Diamond Axe=ダイヤモンドの斧 +Netherite Axe=ネザライトの斧 +Wooden Sword=木製の剣 +Stone Sword=石の剣 +Iron Sword=鉄の剣 +Golden Sword=金の剣 +Diamond Sword=ダイヤモンドの剣 +Netherite Sword=ネザライトの剣 +Shears=ハサミ diff --git a/mods/ITEMS/mcl_tools/locale/template.txt b/mods/ITEMS/mcl_tools/locale/template.txt index ecb94105f..2f5830312 100644 --- a/mods/ITEMS/mcl_tools/locale/template.txt +++ b/mods/ITEMS/mcl_tools/locale/template.txt @@ -14,19 +14,23 @@ Stone Pickaxe= Iron Pickaxe= Golden Pickaxe= Diamond Pickaxe= +Netherite Pickaxe= Wooden Shovel= Stone Shovel= Iron Shovel= Golden Shovel= Diamond Shovel= +Netherite Shovel= Wooden Axe= Stone Axe= Iron Axe= Golden Axe= Diamond Axe= +Netherite Axe= Wooden Sword= Stone Sword= Iron Sword= Golden Sword= Diamond Sword= +Netherite Sword= Shears= diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_netheriteaxe.png b/mods/ITEMS/mcl_tools/textures/default_tool_netheriteaxe.png new file mode 100644 index 000000000..d9657367b Binary files /dev/null and b/mods/ITEMS/mcl_tools/textures/default_tool_netheriteaxe.png differ diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_netheritepick.png b/mods/ITEMS/mcl_tools/textures/default_tool_netheritepick.png new file mode 100644 index 000000000..e4140dde7 Binary files /dev/null and b/mods/ITEMS/mcl_tools/textures/default_tool_netheritepick.png differ diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_netheriteshovel.png b/mods/ITEMS/mcl_tools/textures/default_tool_netheriteshovel.png new file mode 100644 index 000000000..9ae8654ff Binary files /dev/null and b/mods/ITEMS/mcl_tools/textures/default_tool_netheriteshovel.png differ diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_netheritesword.png b/mods/ITEMS/mcl_tools/textures/default_tool_netheritesword.png new file mode 100644 index 000000000..589637a62 Binary files /dev/null and b/mods/ITEMS/mcl_tools/textures/default_tool_netheritesword.png differ diff --git a/mods/ITEMS/mcl_torches/api.lua b/mods/ITEMS/mcl_torches/api.lua index dab508795..a2e49aa0d 100644 --- a/mods/ITEMS/mcl_torches/api.lua +++ b/mods/ITEMS/mcl_torches/api.lua @@ -1,3 +1,5 @@ +local flame_texture = {"mcl_particles_flame.png", "mcl_particles_soul_fire_flame.png"} + local smoke_pdef = { amount = 0.5, maxexptime = 2.0, @@ -9,7 +11,8 @@ local smoke_pdef = { maxrelpos = { x = 1/16, y = 0.06, z = 1/16 }, } -local function spawn_flames_floor(pos) +local function spawn_flames_floor(pos, flame_type) + -- Flames mcl_particles.add_node_particlespawner(pos, { amount = 8, @@ -22,14 +25,14 @@ local function spawn_flames_floor(pos) maxexptime = 0.6, minsize = 0.7, maxsize = 2, - texture = "mcl_particles_flame.png", + texture = flame_texture[flame_type], glow = minetest.registered_nodes[minetest.get_node(pos).name].light_source, }, "low") -- Smoke mcl_particles.spawn_smoke(pos, "torch", smoke_pdef) end -local function spawn_flames_wall(pos) +local function spawn_flames_wall(pos, flame_type) --local minrelpos, maxrelpos local node = minetest.get_node(pos) local dir = minetest.wallmounted_to_dir(node.param2) @@ -37,17 +40,17 @@ local function spawn_flames_wall(pos) local smoke_pdef = table.copy(smoke_pdef) if dir.x < 0 then - smoke_pdef.minrelpos = { x = -0.38, y = 0.04, z = -0.1 } - smoke_pdef.maxrelpos = { x = -0.2, y = 0.14, z = 0.1 } + smoke_pdef.minrelpos = { x = -0.38, y = 0.24, z = -0.1 } + smoke_pdef.maxrelpos = { x = -0.2, y = 0.34, z = 0.1 } elseif dir.x > 0 then - smoke_pdef.minrelpos = { x = 0.2, y = 0.04, z = -0.1 } - smoke_pdef.maxrelpos = { x = 0.38, y = 0.14, z = 0.1 } + smoke_pdef.minrelpos = { x = 0.2, y = 0.24, z = -0.1 } + smoke_pdef.maxrelpos = { x = 0.38, y = 0.34, z = 0.1 } elseif dir.z < 0 then - smoke_pdef.minrelpos = { x = -0.1, y = 0.04, z = -0.38 } - smoke_pdef.maxrelpos = { x = 0.1, y = 0.14, z = -0.2 } + smoke_pdef.minrelpos = { x = -0.1, y = 0.24, z = -0.38 } + smoke_pdef.maxrelpos = { x = 0.1, y = 0.34, z = -0.2 } elseif dir.z > 0 then - smoke_pdef.minrelpos = { x = -0.1, y = 0.04, z = 0.2 } - smoke_pdef.maxrelpos = { x = 0.1, y = 0.14, z = 0.38 } + smoke_pdef.minrelpos = { x = -0.1, y = 0.24, z = 0.2 } + smoke_pdef.maxrelpos = { x = 0.1, y = 0.34, z = 0.38 } else return end @@ -65,13 +68,25 @@ local function spawn_flames_wall(pos) maxexptime = 0.6, minsize = 0.7, maxsize = 2, - texture = "mcl_particles_flame.png", + texture = flame_texture[flame_type], glow = minetest.registered_nodes[node.name].light_source, }, "low") -- Smoke mcl_particles.spawn_smoke(pos, "torch", smoke_pdef) end +local function set_flames(pos, flame_type, attached_to) + if attached_to == "wall" then + return function(pos) + spawn_flames_wall(pos, flame_type) + end + end + + return function(pos) + spawn_flames_floor(pos, flame_type) + end +end + local function remove_flames(pos) mcl_particles.delete_node_particlespawners(pos) end @@ -124,6 +139,7 @@ function mcl_torches.register_torch(def) def.light = def.light or minetest.LIGHT_MAX def.mesh_floor = def.mesh_floor or "mcl_torches_torch_floor.obj" def.mesh_wall = def.mesh_wall or "mcl_torches_torch_wall.obj" + def.flame_type = def.flame_type or 1 local groups = def.groups or {} @@ -133,6 +149,7 @@ function mcl_torches.register_torch(def) groups.dig_by_water = 1 groups.destroy_by_lava_flow = 1 groups.dig_by_piston = 1 + groups.flame_type = def.flame_type or 1 local floordef = { description = def.description, @@ -145,7 +162,6 @@ function mcl_torches.register_torch(def) inventory_image = def.icon, wield_image = def.icon, tiles = def.tiles, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "wallmounted", sunlight_propagates = true, @@ -155,10 +171,10 @@ function mcl_torches.register_torch(def) light_source = def.light, groups = groups, drop = def.drop or itemstring, + use_texture_alpha = "clip", selection_box = { type = "wallmounted", - wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16}, - wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16}, + wall_bottom = {-2/16, -0.5, -2/16, 2/16, 1/16, 2/16}, }, sounds = def.sounds, node_placement_prediction = "", @@ -211,7 +227,11 @@ function mcl_torches.register_torch(def) return itemstack end, on_rotate = false, - on_construct = def.particles and spawn_flames_floor, + on_construct = function(pos) + if def.particles then + set_flames(pos, def.flame_type, "floor") + end + end, on_destruct = def.particles and remove_flames, } minetest.register_node(itemstring, floordef) @@ -223,7 +243,6 @@ function mcl_torches.register_torch(def) drawtype = "mesh", mesh = def.mesh_wall, tiles = def.tiles, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "wallmounted", sunlight_propagates = true, @@ -232,15 +251,18 @@ function mcl_torches.register_torch(def) light_source = def.light, groups = groups_wall, drop = def.drop or itemstring, + use_texture_alpha = "clip", selection_box = { type = "wallmounted", - wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1}, - wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1}, - wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1}, + wall_side = {-0.5, -0.3, -0.1, -0.2, 0.325, 0.1}, }, sounds = def.sounds, on_rotate = false, - on_construct = def.particles and spawn_flames_wall, + on_construct = function(pos) + if def.particles then + set_flames(pos, def.flame_type, "wall") + end + end, on_destruct = def.particles and remove_flames, } minetest.register_node(itemstring_wall, walldef) @@ -259,9 +281,9 @@ minetest.register_lbm({ action = function(pos, node) local torch_group = minetest.get_item_group(node.name, "torch") if torch_group == 1 then - spawn_flames_floor(pos) + spawn_flames_floor(pos, minetest.get_item_group(node.name, "flame_type")) elseif torch_group == 2 then - spawn_flames_wall(pos) + spawn_flames_wall(pos, minetest.get_item_group(node.name, "flame_type")) end end, }) diff --git a/mods/ITEMS/mcl_torches/locale/mcl_torches.ja.tr b/mods/ITEMS/mcl_torches/locale/mcl_torches.ja.tr new file mode 100644 index 000000000..eccc36053 --- /dev/null +++ b/mods/ITEMS/mcl_torches/locale/mcl_torches.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_torches +Torch=松明 +Torches are light sources which can be placed at the side or on the top of most blocks.=松明は光源で、ほとんどのブロックの側面や上部に設置できます。 diff --git a/mods/ITEMS/mcl_torches/models/mcl_torches_torch_floor.obj b/mods/ITEMS/mcl_torches/models/mcl_torches_torch_floor.obj index ac4234d3e..b0683b59c 100644 --- a/mods/ITEMS/mcl_torches/models/mcl_torches_torch_floor.obj +++ b/mods/ITEMS/mcl_torches/models/mcl_torches_torch_floor.obj @@ -1,29 +1,72 @@ -# Blender v2.76 (sub 0) OBJ File: 'torch_on_floor_node.blend' +# Blender 3.3.1 # www.blender.org -o torch_Cube_Cube.001_Cube_Cube.001_Material.001 +mtllib mcl_torches_torch_floor.mtl +o cube.004 +v -0.062500 0.437500 -0.500000 +v -0.062500 -0.562500 -0.500000 +v -0.062500 0.437500 0.500000 +v -0.062500 -0.562500 0.500000 v 0.062500 0.062500 0.062500 v 0.062500 0.062500 -0.062500 +v 0.062500 -0.562500 0.062500 +v 0.062500 -0.562500 -0.062500 v -0.062500 0.062500 -0.062500 v -0.062500 0.062500 0.062500 -v -0.062500 -0.500000 0.062500 -v 0.062500 -0.500000 0.062500 -v 0.062500 -0.500000 -0.062500 -v -0.062500 -0.500000 -0.062500 +v -0.062500 -0.562500 -0.062500 +v -0.062500 -0.562500 0.062500 +v 0.500000 0.437500 0.062500 +v 0.500000 -0.562500 0.062500 +v -0.500000 0.437500 0.062500 +v -0.500000 -0.562500 0.062500 +v 0.500000 0.437500 -0.062500 +v 0.500000 -0.562500 -0.062500 +v -0.500000 0.437500 -0.062500 +v -0.500000 -0.562500 -0.062500 +v 0.062500 0.437500 -0.500000 +v 0.062500 -0.562500 -0.500000 +v 0.062500 0.437500 0.500000 +v 0.062500 -0.562500 0.500000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 vt 0.562500 0.500000 vt 0.562500 0.625000 +vt 0.562500 0.125000 +vt 0.562500 0.000063 vt 0.437500 0.625000 vt 0.437500 0.500000 -vt 0.437500 0.000000 -vt 0.562500 0.000000 -vt 0.562500 0.125000 +vt 0.437500 0.000063 vt 0.437500 0.125000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 1.000000 0.000000 0.000000 -s 1 -f 1/1/1 2/2/1 3/3/1 4/4/1 -f 5/5/1 6/6/1 7/7/1 8/8/1 -f 1/2/2 6/6/2 5/5/2 4/3/2 -f 2/3/3 1/2/3 6/6/3 7/5/3 -f 3/2/2 2/3/2 7/5/2 8/6/2 -f 4/3/3 5/5/3 8/6/3 3/2/3 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +s 0 +usemtl m_0.002 +f 3/3/1 4/4/1 1/1/1 +f 4/4/1 2/2/1 1/1/1 +f 9/9/2 10/10/2 6/6/2 +f 10/10/2 5/5/2 6/6/2 +f 12/12/3 11/11/3 7/7/3 +f 11/11/3 8/8/3 7/7/3 +f 13/13/4 14/14/4 15/15/4 +f 14/14/4 16/16/4 15/15/4 +f 19/19/5 20/20/5 17/17/5 +f 20/20/5 18/18/5 17/17/5 +f 21/21/6 22/22/6 23/23/6 +f 22/22/6 24/24/6 23/23/6 diff --git a/mods/ITEMS/mcl_torches/models/mcl_torches_torch_wall.obj b/mods/ITEMS/mcl_torches/models/mcl_torches_torch_wall.obj index 824223e6d..35c192c25 100644 --- a/mods/ITEMS/mcl_torches/models/mcl_torches_torch_wall.obj +++ b/mods/ITEMS/mcl_torches/models/mcl_torches_torch_wall.obj @@ -1,29 +1,72 @@ -# Blender v2.76 (sub 0) OBJ File: 'torch_on_wall_node.blend' +# Blender 3.3.1 # www.blender.org -o torch_wall_Cube_Cube.001_Cube_Cube.001_Material.001 -v 0.062469 -0.303502 0.086070 -v 0.062469 -0.195248 0.023570 -v -0.062531 -0.195248 0.023570 -v -0.062531 -0.303502 0.086070 -v -0.062531 -0.584752 -0.401070 -v 0.062469 -0.584752 -0.401070 -v 0.062469 -0.476498 -0.463570 -v -0.062531 -0.476498 -0.463570 +mtllib mcl_torches_torch_wall.mtl +o cube +v -0.062500 -0.198340 0.273825 +v -0.062500 -0.313825 0.321660 +v -0.062500 -0.437517 -0.303600 +v -0.062500 -0.553002 -0.255765 +v 0.062500 -0.313825 0.321660 +v 0.062500 -0.198340 0.273825 +v 0.062500 -0.553002 -0.255765 +v 0.062500 -0.437517 -0.303600 +v -0.500000 -0.054833 0.620280 +v -0.500000 -0.437517 -0.303600 +v 0.500000 -0.054834 0.620280 +v 0.500000 -0.437517 -0.303600 +v -0.500000 -0.170318 0.668115 +v -0.500000 -0.553002 -0.255765 +v 0.500000 -0.170318 0.668115 +v 0.500000 -0.553002 -0.255765 +v -0.062500 -0.574516 0.835539 +v -0.062500 -0.957199 -0.088340 +v -0.062500 0.349364 0.452856 +v -0.062500 -0.033320 -0.471024 +v 0.062500 -0.574516 0.835539 +v 0.062500 -0.957199 -0.088340 +v 0.062500 0.349364 0.452856 +v 0.062500 -0.033320 -0.471024 +vn -0.0000 0.3827 0.9239 +vn -0.0000 -0.3827 -0.9239 +vn -0.0000 -0.9239 0.3827 +vn -0.0000 0.9239 -0.3827 +vn 1.0000 -0.0000 -0.0000 +vn -1.0000 -0.0000 -0.0000 vt 0.562500 0.500000 vt 0.562500 0.625000 +vt 0.562500 0.125000 +vt 0.562500 0.000063 vt 0.437500 0.625000 vt 0.437500 0.500000 -vt 0.437500 0.000000 -vt 0.562500 0.000000 -vt 0.562500 0.125000 +vt 0.437500 0.000063 vt 0.437500 0.125000 -vn 0.000000 0.500000 0.866000 -vn 0.000000 0.866000 -0.500000 -vn 1.000000 -0.000000 0.000000 -s 1 -f 1/1/1 2/2/1 3/3/1 4/4/1 -f 5/5/1 6/6/1 7/7/1 8/8/1 -f 1/2/2 6/6/2 5/5/2 4/3/2 -f 2/3/3 1/2/3 6/6/3 7/5/3 -f 3/2/2 2/3/2 7/5/2 8/6/2 -f 4/3/3 5/5/3 8/6/3 3/2/3 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +s 0 +usemtl m_0.001 +f 5/5/1 6/6/1 2/2/1 +f 6/6/1 1/1/1 2/2/1 +f 8/8/2 7/7/2 3/3/2 +f 7/7/2 4/4/2 3/3/2 +f 9/9/3 10/10/3 11/11/3 +f 10/10/3 12/12/3 11/11/3 +f 15/15/4 16/16/4 13/13/4 +f 16/16/4 14/14/4 13/13/4 +f 17/17/5 18/18/5 19/19/5 +f 18/18/5 20/20/5 19/19/5 +f 23/23/6 24/24/6 21/21/6 +f 24/24/6 22/22/6 21/21/6 diff --git a/mods/ITEMS/mcl_torches/register.lua b/mods/ITEMS/mcl_torches/register.lua index f8c34e6b5..4eead4024 100644 --- a/mods/ITEMS/mcl_torches/register.lua +++ b/mods/ITEMS/mcl_torches/register.lua @@ -15,6 +15,7 @@ mcl_torches.register_torch({ groups = {dig_immediate = 3, deco_block = 1}, sounds = mcl_sounds.node_sound_wood_defaults(), particles = true, + flame_type = 1, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_torches/textures/default_torch_on_floor.png b/mods/ITEMS/mcl_torches/textures/default_torch_on_floor.png index cb0ce15f1..e0656dbb0 100644 Binary files a/mods/ITEMS/mcl_torches/textures/default_torch_on_floor.png and b/mods/ITEMS/mcl_torches/textures/default_torch_on_floor.png differ diff --git a/mods/ITEMS/mcl_torches/textures/default_torch_on_floor_animated.png b/mods/ITEMS/mcl_torches/textures/default_torch_on_floor_animated.png index 28cdc64c7..a34b461c2 100644 Binary files a/mods/ITEMS/mcl_torches/textures/default_torch_on_floor_animated.png and b/mods/ITEMS/mcl_torches/textures/default_torch_on_floor_animated.png differ diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index 8e529c5d5..26874b50b 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -51,7 +51,8 @@ mcl_damage.register_modifier(function(obj, damage, reason) obj:set_wielded_item(wield) end end - + awards.unlock(obj:get_player_name(), "mcl:postMortal") + -- Effects minetest.sound_play({name = "mcl_totems_totem", gain = 1}, {pos=ppos, max_hear_distance = 16}, true) diff --git a/mods/ITEMS/mcl_totems/locale/mcl_totems.ja.tr b/mods/ITEMS/mcl_totems/locale/mcl_totems.ja.tr new file mode 100644 index 000000000..ff57aa264 --- /dev/null +++ b/mods/ITEMS/mcl_totems/locale/mcl_totems.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_totems +Totem of Undying=不死のトーテム +A totem of undying is a rare artifact which may safe you from certain death.=不死のトーテムはレアなアーティファクトで、あなたを絶命から救ってくれるかもです。 +The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=トーテムは手に持っている間だけ御利益があります。致命傷を受けても、死から救済され HP1で再チャンスを得られます。がしかし、その過程でトーテムは壊れてしまいます。 +Protects you from death while wielding it=それを手にしている間、死からあなたを守護 diff --git a/mods/ITEMS/mcl_walls/locale/mcl_walls.fr.tr b/mods/ITEMS/mcl_walls/locale/mcl_walls.fr.tr index 445c8f7b3..8fe748c81 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 Granit +Granite Wall=Muret de Granite Diorite Wall=Muret de Diorite Brick Wall=Muret en Brique Sandstone Wall=Muret de Grès @@ -14,3 +14,4 @@ Prismarine Wall=Muret de Prismarine End Stone Brick Wall=Muret de Brique de l'End Nether Brick Wall=Muret de Brique du Nether Red Nether Brick Wall=Muret de Brique Rouge du Nether +Mud Brick Wall=Muret de Brique de Boue \ No newline at end of file diff --git a/mods/ITEMS/mcl_walls/locale/mcl_walls.ja.tr b/mods/ITEMS/mcl_walls/locale/mcl_walls.ja.tr new file mode 100644 index 000000000..c568788a7 --- /dev/null +++ b/mods/ITEMS/mcl_walls/locale/mcl_walls.ja.tr @@ -0,0 +1,17 @@ +# textdomain: mcl_walls +A piece of wall. It cannot be jumped over with a simple jump. When multiple of these are placed to next to each other, they will automatically build a nice wall structure.=壁の一部。単なるジャンプでは飛び越えられません。これを複数個並べて置いたなら、自動的にイイ感じの壁面に仕上がるでしょう。 +Cobblestone Wall=丸石の壁 +Mossy Cobblestone Wall=苔むした丸石の壁 +Andesite Wall=安山岩の壁 +Granite Wall=花崗岩の壁 +Diorite Wall=閃緑岩の壁 +Brick Wall=レンガの壁 +Sandstone Wall=砂岩の壁 +Red Sandstone Wall=赤い砂岩の壁 +Stone Brick Wall=石レンガの壁 +Mossy Stone Brick Wall=苔むした石レンガの壁 +Prismarine Wall=プリズマリンの壁 +End Stone Brick Wall=エンドストーンレンガの壁 +Nether Brick Wall=ネザーレンガの壁 +Red Nether Brick Wall=赤いネザーレンガの壁 +Mud Brick Wall=泥レンガの壁 \ No newline at end of file diff --git a/mods/ITEMS/mcl_walls/locale/template.txt b/mods/ITEMS/mcl_walls/locale/template.txt index 765365997..e4bfa3602 100644 --- a/mods/ITEMS/mcl_walls/locale/template.txt +++ b/mods/ITEMS/mcl_walls/locale/template.txt @@ -14,3 +14,4 @@ Prismarine Wall= End Stone Brick Wall= Nether Brick Wall= Red Nether Brick Wall= +Mud Brick Wall= \ No newline at end of file diff --git a/mods/ITEMS/mcl_walls/mod.conf b/mods/ITEMS/mcl_walls/mod.conf index 8839312de..b6b221007 100644 --- a/mods/ITEMS/mcl_walls/mod.conf +++ b/mods/ITEMS/mcl_walls/mod.conf @@ -1,3 +1,3 @@ name = mcl_walls -depends = mcl_core, mcl_end, mcl_ocean, mcl_nether, mcl_sounds +depends = mcl_core, mcl_end, mcl_ocean, mcl_nether, mcl_sounds, mcl_mud optional_depends = doc diff --git a/mods/ITEMS/mcl_walls/register.lua b/mods/ITEMS/mcl_walls/register.lua index 483af493e..96a1b9b9f 100644 --- a/mods/ITEMS/mcl_walls/register.lua +++ b/mods/ITEMS/mcl_walls/register.lua @@ -14,3 +14,4 @@ mcl_walls.register_wall("mcl_walls:prismarine", S("Prismarine Wall"), "mcl_ocean mcl_walls.register_wall("mcl_walls:endbricks", S("End Stone Brick Wall"), "mcl_end:end_bricks") mcl_walls.register_wall("mcl_walls:netherbrick", S("Nether Brick Wall"), "mcl_nether:nether_brick") mcl_walls.register_wall("mcl_walls:rednetherbrick", S("Red Nether Brick Wall"), "mcl_nether:red_nether_brick") +mcl_walls.register_wall("mcl_walls:mudbrick", S("Mud Brick Wall"), "mcl_mud:mud_bricks") \ No newline at end of file diff --git a/mods/ITEMS/mcl_wool/locale/mcl_wool.ja.tr b/mods/ITEMS/mcl_wool/locale/mcl_wool.ja.tr new file mode 100644 index 000000000..9b8ed335a --- /dev/null +++ b/mods/ITEMS/mcl_wool/locale/mcl_wool.ja.tr @@ -0,0 +1,37 @@ +# textdomain: mcl_wool +Wool=羊毛 +Carpet=カーペット +White Wool=白色の羊毛 +White Carpet=白色のカーペット +Grey Wool=灰色の羊毛 +Grey Carpet=灰色のカーペット +Light Grey Wool=薄灰色の羊毛 +Light Grey Carpet=薄灰色のカーペット +Black Wool=黒色の羊毛 +Black Carpet=黒色のカーペット +Red Wool=赤色の羊毛 +Red Carpet=赤色のカーペット +Yellow Wool=黄色の羊毛 +Yellow Carpet=黄色のカーペット +Green Wool=緑色の羊毛 +Green Carpet=緑色のカーペット +Cyan Wool=青緑色の羊毛 +Cyan Carpet=青緑色のカーペット +Blue Wool=青色の羊毛 +Blue Carpet=青色のカーペット +Magenta Wool=赤紫色の羊毛 +Magenta Carpet=赤紫色のカーペット +Orange Wool=橙色の羊毛 +Orange Carpet=橙色のカーペット +Purple Wool=紫色の羊毛 +Purple Carpet=紫色のカーペット +Brown Wool=茶色の羊毛 +Brown Carpet=茶色のカーペット +Pink Wool=桃色の羊毛 +Pink Carpet=桃色のカーペット +Lime Wool=黄緑色の羊毛 +Lime Carpet=黄緑色のカーペット +Light Blue Wool=空色の羊毛 +Light Blue Carpet=空色のカーペット +Wool is a decorative block which comes in many different colors.=羊毛は、多彩なカラーバリエーションを持つ装飾ブロックです。 +Carpets are thin floor covers which come in many different colors.=カーペットは、多彩なカラーバリエーションを持つ薄い敷物です。 diff --git a/mods/ITEMS/mclx_core/init.lua b/mods/ITEMS/mclx_core/init.lua index 4bb40184a..9c46442c5 100644 --- a/mods/ITEMS/mclx_core/init.lua +++ b/mods/ITEMS/mclx_core/init.lua @@ -5,6 +5,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) local source = table.copy(minetest.registered_nodes["mcl_core:water_source"]) source.description = S("River Water Source") source.liquid_range = 2 +source.waving = 3 source.liquid_alternative_flowing = "mclx_core:river_water_flowing" source.liquid_alternative_source = "mclx_core:river_water_source" source.liquid_renewable = false @@ -28,6 +29,7 @@ source.special_tiles = { local flowing = table.copy(minetest.registered_nodes["mcl_core:water_flowing"]) flowing.description = S("Flowing River Water") flowing.liquid_range = 2 +flowing.waving = 3 flowing.liquid_alternative_flowing = "mclx_core:river_water_flowing" flowing.liquid_alternative_source = "mclx_core:river_water_source" flowing.liquid_renewable = false diff --git a/mods/ITEMS/mclx_core/locale/mclx_core.ja.tr b/mods/ITEMS/mclx_core/locale/mclx_core.ja.tr new file mode 100644 index 000000000..038ab5675 --- /dev/null +++ b/mods/ITEMS/mclx_core/locale/mclx_core.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mclx_core +River Water Source=河川水源 +River water has the same properties as water, but has a reduced flowing distance and is not renewable.=河川水は水と同じ性質を持っていますが、流れる距離が短く、再生も不可能です。 +River Water=河川水 +Flowing River Water=流れる河川水 diff --git a/mods/ITEMS/mclx_core/textures/default_river_water_flowing_animated.png b/mods/ITEMS/mclx_core/textures/default_river_water_flowing_animated.png index 9e126d3c1..317d6e368 100644 Binary files a/mods/ITEMS/mclx_core/textures/default_river_water_flowing_animated.png and b/mods/ITEMS/mclx_core/textures/default_river_water_flowing_animated.png differ diff --git a/mods/ITEMS/mclx_core/textures/default_river_water_source_animated.png b/mods/ITEMS/mclx_core/textures/default_river_water_source_animated.png index fb8ae17bd..d8ad149a6 100644 Binary files a/mods/ITEMS/mclx_core/textures/default_river_water_source_animated.png and b/mods/ITEMS/mclx_core/textures/default_river_water_source_animated.png differ diff --git a/mods/ITEMS/mclx_fences/locale/mclx_fences.ja.tr b/mods/ITEMS/mclx_fences/locale/mclx_fences.ja.tr new file mode 100644 index 000000000..3e1383cef --- /dev/null +++ b/mods/ITEMS/mclx_fences/locale/mclx_fences.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mclx_fences +Red Nether Brick Fence=赤いネザーレンガのフェンス +Red Nether Brick Fence Gate=赤いネザーレンガのフェンスゲート +Nether Brick Fence Gate=ネザーレンガのフェンスゲート diff --git a/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ja.tr b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ja.tr new file mode 100644 index 000000000..bbe2ee209 --- /dev/null +++ b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ja.tr @@ -0,0 +1,82 @@ +# textdomain: mclx_stairs +Oak Bark Stairs=オーク樹皮の階段 +Oak Bark Slab=オーク樹皮のスラブ +Double Oak Bark Slab=オーク樹皮の2重スラブ +Acacia Bark Stairs=アカシア樹皮の階段 +Acacia Bark Slab=アカシア樹皮のスラブ +Double Acacia Bark Slab=アカシア樹皮の2重スラブ +Spruce Bark Stairs=トウヒ樹皮の階段 +Spruce Bark Slab=トウヒ樹皮のスラブ +Double Spruce Bark Slab=トウヒ樹皮の2重スラブ +Birch Bark Stairs=シラカバ樹皮の階段 +Birch Bark Slab=シラカバ樹皮のスラブ +Double Birch Bark Slab=シラカバ樹皮の2重スラブ +Jungle Bark Stairs=ジャングル樹皮の階段 +Jungle Bark Slab=ジャングル樹皮のスラブ +Double Jungle Bark Slab=ジャングル樹皮の2重スラブ +Dark Oak Bark Stairs=ダークオーク樹皮の階段 +Dark Oak Bark Slab=ダークオーク樹皮のスラブ +Double Dark Oak Bark Slab=ダークオーク樹皮の2重スラブ +Lapis Lazuli Slab=ラピスラズリのスラブ +Double Lapis Lazuli Slab=ラピスラズリの2重スラブ +Lapis Lazuli Stairs=ラピスラズリの階段 +Slab of Gold=金のスラブ +Double Slab of Gold=金の2重スラブ +Stairs of Gold=金の階段 +Slab of Iron=鉄のスラブ +Double Slab of Iron=鉄の2重スラブ +Stairs of Iron=鉄の階段 +Cracked Stone Brick Stairs=ひび割れた石レンガの階段 +Cracked Stone Brick Slab=ひび割れた石レンガのスラブ +Double Cracked Stone Brick Slab=ひび割れた石レンガの2重スラブ +White Concrete Stairs=白色コンクリートの階段 +White Concrete Slab=白色コンクリートのスラブ +Double White Concrete Slab=白色コンクリートの2重スラブ +Grey Concrete Stairs=灰色コンクリートの階段 +Grey Concrete Slab=灰色コンクリートのスラブ +Double Grey Concrete Slab=灰色コンクリートの2重スラブ +Light Grey Concrete Stairs=薄灰色コンクリートの階段 +Light Grey Concrete Slab=薄灰色コンクリートのスラブ +Double Light Grey Concrete Slab=薄灰色コンクリートの2重スラブ +Black Concrete Stairs=黒色コンクリートの階段 +Black Concrete Slab=黒色コンクリートのスラブ +Double Black Concrete Slab=黒色コンクリートの2重スラブ +Red Concrete Stairs=赤色コンクリートの階段 +Red Concrete Slab=赤色コンクリートのスラブ +Double Red Concrete Slab=赤色コンクリートの2重スラブ +Yellow Concrete Stairs=黄色コンクリートの階段 +Yellow Concrete Slab=黄色コンクリートのスラブ +Double Yellow Concrete Slab=黄色コンクリートの2重スラブ +Green Concrete Stairs=緑色コンクリートの階段 +Green Concrete Slab=緑色コンクリートのスラブ +Double Green Concrete Slab=緑色コンクリートの2重スラブ +Cyan Concrete Stairs=青緑色コンクリートの階段 +Cyan Concrete Slab=青緑色コンクリートのスラブ +Double Cyan Concrete Slab=青緑色コンクリートの2重スラブ +Blue Concrete Stairs=青色コンクリートの階段 +Blue Concrete Slab=青色コンクリートのスラブ +Double Blue Concrete Slab=青色コンクリートの2重スラブ +Magenta Concrete Stairs=赤紫色コンクリートの階段 +Magenta Concrete Slab=赤紫色コンクリートのスラブ +Double Magenta Concrete Slab=赤紫色コンクリートの2重スラブ +Orange Concrete Stairs=橙色コンクリートの階段 +Orange Concrete Slab=橙色コンクリートのスラブ +Double Orange Concrete Slab=橙色コンクリートの2重スラブ +Purple Concrete Stairs=紫色コンクリートの階段 +Purple Concrete Slab=紫色コンクリートのスラブ +Double Purple Concrete Slab=紫色コンクリートの2重スラブ +Brown Concrete Stairs=茶色コンクリートの階段 +Brown Concrete Slab=茶色コンクリートのスラブ +Double Brown Concrete Slab=茶色コンクリートの2重スラブ +Pink Concrete Stairs=桃色コンクリートの階段 +Pink Concrete Slab=桃色コンクリートのスラブ +Double Pink Concrete Slab=桃色コンクリートの2重スラブ +Lime Concrete Stairs=黄緑色コンクリートの階段 +Lime Concrete Slab=黄緑色コンクリートのスラブ +Double Lime Concrete Slab=黄緑色コンクリートの2重スラブ +Light Blue Concrete Stairs=空色コンクリートの階段 +Light Blue Concrete Slab=空色コンクリートのスラブ +Double Light Blue Concrete Slab=空色コンクリートの2重スラブ +Concrete Slab=コンクリートのスラブ +Double Concrete Slab=コンクリートの2重スラブ +Concrete Stairs=コンクリートの階段 diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.ja.tr b/mods/ITEMS/screwdriver/locale/screwdriver.ja.tr new file mode 100644 index 000000000..dbb80fb61 --- /dev/null +++ b/mods/ITEMS/screwdriver/locale/screwdriver.ja.tr @@ -0,0 +1,2 @@ +#textdomain: screwdriver +Screwdriver=ドライバー diff --git a/mods/ITEMS/xpanes/init.lua b/mods/ITEMS/xpanes/init.lua index fe67934a1..85405308b 100644 --- a/mods/ITEMS/xpanes/init.lua +++ b/mods/ITEMS/xpanes/init.lua @@ -69,16 +69,16 @@ local function update_pane(pos) end minetest.register_on_placenode(function(pos, node) - if minetest.get_item_group(node, "pane") then - update_pane(pos) - end + if minetest.get_item_group(node.name, "pane") <= 0 then return end + update_pane(pos) for i = 0, 3 do local dir = minetest.facedir_to_dir(i) update_pane(vector.add(pos, dir)) end end) -minetest.register_on_dignode(function(pos) +minetest.register_on_dignode(function(pos,node) + if minetest.get_item_group(node.name, "pane") <= 0 then return end for i = 0, 3 do local dir = minetest.facedir_to_dir(i) update_pane(vector.add(pos, dir)) @@ -86,6 +86,7 @@ minetest.register_on_dignode(function(pos) end) xpanes = {} +xpanes.update_pane = update_pane function xpanes.register_pane(name, def) for i = 1, 15 do minetest.register_alias("xpanes:" .. name .. "_" .. i, "xpanes:" .. name .. "_flat") diff --git a/mods/ITEMS/xpanes/locale/xpanes.ja.tr b/mods/ITEMS/xpanes/locale/xpanes.ja.tr new file mode 100644 index 000000000..bd67ee498 --- /dev/null +++ b/mods/ITEMS/xpanes/locale/xpanes.ja.tr @@ -0,0 +1,23 @@ +# textdomain: xpanes +Glass panes are thin layers of glass which neatly connect to their neighbors as you build them.=ガラス板は、薄い層状のガラスで、組み立てると隣のガラスときれいにつながっていきます。 +Stained glass panes are thin layers of stained glass which neatly connect to their neighbors as you build them. They come in many different colors.=色ガラス板は、薄い層状の色ガラスで、組み立てると隣のガラスときれいにつながっていきます。カラーバリエーションも豊富です。 +Iron Bars=鉄格子 +Iron bars neatly connect to their neighbors as you build them.=鉄格子は、組み立てると隣の格子ときれいにつながっていきます。 +Glass Pane=ガラス板 +Stained Glass Pane=色ガラス板 +Red Stained Glass Pane=赤色ガラス板 +Green Stained Glass Pane=緑色ガラス板 +Blue Stained Glass Pane=青色ガラス板 +Light Blue Stained Glass Pane=空色ガラス板 +Black Stained Glass Pane=黒色ガラス板 +White Stained Glass Pane=白色ガラス板 +Yellow Stained Glass Pane=黃色ガラス板 +Brown Stained Glass Pane=茶色ガラス板 +Orange Stained Glass Pane=橙色ガラス板 +Pink Stained Glass Pane=桃色ガラス板 +Grey Stained Glass Pane=灰色ガラス板 +Lime Stained Glass Pane=黄緑色ガラス板 +Light Grey Stained Glass Pane=薄灰色ガラス板 +Magenta Stained Glass Pane=赤紫色ガラス板 +Purple Stained Glass Pane=紫色ガラス板 +Cyan Stained Glass Pane=青緑色ガラス板 diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index f198e09fa..25e8f3e34 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -9,9 +9,9 @@ local generate_fallen_logs = minetest.settings:get_bool("mcl_generate_fallen_log 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 = mod_mcl_core.."/schematics/mcl_core_jungle_bush_oak_leaves.mts" +local mod_mcl_crimson = minetest.get_modpath("mcl_crimson") +local mod_mcl_blackstone = minetest.get_modpath("mcl_blackstone") +local mod_mcl_mangrove = minetest.get_modpath("mcl_mangrove") local deco_id_chorus_plant @@ -42,6 +42,8 @@ local function register_classic_superflat_biome() heat_point = 50, _mcl_biome_type = "medium", _mcl_palette_index = 0, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) end @@ -125,8 +127,18 @@ local function register_biomes() "MesaBryce", "MesaPlateauF", "MesaPlateauFM", + "MangroveSwamp", } +local beach_skycolor = "#78A7FF" -- This is the case for all beach biomes except for the snowy ones! Those beaches will have their own colour instead of this one. +local ocean_skycolor = "#7BA4FF" -- This is the case for all ocean biomes except for non-deep frozen oceans! Those oceans will have their own colour instead of this one. +local overworld_fogcolor = "#C0D8FF" + +local nether_skycolor = "#6EB1FF" + +local end_fogcolor = "#A080A0" +local end_skycolor = "#000000" + -- Ice Plains Spikes (rare) minetest.register_biome({ name = "IcePlainsSpikes", @@ -145,6 +157,8 @@ local function register_biomes() heat_point = -5, _mcl_biome_type = "snowy", _mcl_palette_index = 2, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "IcePlainsSpikes_ocean", @@ -161,6 +175,8 @@ local function register_biomes() heat_point = -5, _mcl_biome_type = "snowy", _mcl_palette_index = 2, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Cold Taiga @@ -179,6 +195,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "snowy", _mcl_palette_index = 3, + _mcl_skycolor = "#839EFF", + _mcl_fogcolor = overworld_fogcolor }) -- A cold beach-like biome, implemented as low part of Cold Taiga @@ -199,6 +217,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "snowy", _mcl_palette_index = 3, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Water part of the beach. Added to prevent snow being on the ice. minetest.register_biome({ @@ -217,6 +237,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "snowy", _mcl_palette_index = 3, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ColdTaiga_ocean", @@ -233,9 +255,11 @@ local function register_biomes() vertical_blend = 1, _mcl_biome_type = "snowy", _mcl_palette_index = 3, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) - -- Mega Taiga + -- Mega Pine Taiga minetest.register_biome({ name = "MegaTaiga", node_top = "mcl_core:podzol", @@ -250,6 +274,8 @@ local function register_biomes() heat_point = 10, _mcl_biome_type = "cold", _mcl_palette_index = 4, + _mcl_skycolor = "#7CA3FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MegaTaiga_ocean", @@ -265,6 +291,8 @@ local function register_biomes() heat_point = 10, _mcl_biome_type = "cold", _mcl_palette_index = 4, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mega Spruce Taiga @@ -282,6 +310,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "cold", _mcl_palette_index = 5, + _mcl_skycolor = "#7DA3FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MegaSpruceTaiga_ocean", @@ -297,6 +327,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "cold", _mcl_palette_index = 5, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Extreme Hills @@ -315,6 +347,8 @@ local function register_biomes() heat_point = 45, _mcl_biome_type = "cold", _mcl_palette_index = 6, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ExtremeHills_beach", @@ -331,6 +365,8 @@ local function register_biomes() heat_point = 45, _mcl_biome_type = "cold", _mcl_palette_index = 6, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ExtremeHills_ocean", @@ -347,6 +383,8 @@ local function register_biomes() heat_point = 45, _mcl_biome_type = "cold", _mcl_palette_index = 6, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Extreme Hills M @@ -365,6 +403,8 @@ local function register_biomes() heat_point = 25, _mcl_biome_type = "cold", _mcl_palette_index = 7, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ExtremeHillsM_ocean", @@ -380,6 +420,8 @@ local function register_biomes() heat_point = 25, _mcl_biome_type = "cold", _mcl_palette_index = 7, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Extreme Hills+ @@ -400,6 +442,8 @@ local function register_biomes() vertical_blend = 6, _mcl_biome_type = "cold", _mcl_palette_index = 8, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) ---- Sub-biome for Extreme Hills+ for those snow forests minetest.register_biome({ @@ -418,6 +462,8 @@ local function register_biomes() heat_point = 25, _mcl_biome_type = "cold", _mcl_palette_index = 8, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ExtremeHills+_ocean", @@ -433,6 +479,8 @@ local function register_biomes() heat_point = 25, _mcl_biome_type = "cold", _mcl_palette_index = 8, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Stone beach @@ -448,6 +496,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "cold", _mcl_palette_index = 9, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ @@ -463,6 +513,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "cold", _mcl_palette_index = 9, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Ice Plains @@ -484,6 +536,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "snowy", _mcl_palette_index = 10, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "IcePlains_ocean", @@ -499,6 +553,8 @@ local function register_biomes() heat_point = 8, _mcl_biome_type = "snowy", _mcl_palette_index = 10, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Plains @@ -516,6 +572,8 @@ local function register_biomes() heat_point = 58, _mcl_biome_type = "medium", _mcl_palette_index = 0, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Plains_beach", @@ -531,6 +589,8 @@ local function register_biomes() heat_point = 58, _mcl_biome_type = "medium", _mcl_palette_index = 0, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Plains_ocean", @@ -546,6 +606,8 @@ local function register_biomes() heat_point = 58, _mcl_biome_type = "medium", _mcl_palette_index = 0, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Sunflower Plains @@ -563,6 +625,8 @@ local function register_biomes() heat_point = 45, _mcl_biome_type = "medium", _mcl_palette_index = 11, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "SunflowerPlains_ocean", @@ -578,6 +642,8 @@ local function register_biomes() heat_point = 45, _mcl_biome_type = "medium", _mcl_palette_index = 11, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Taiga @@ -595,6 +661,8 @@ local function register_biomes() heat_point = 22, _mcl_biome_type = "cold", _mcl_palette_index = 12, + _mcl_skycolor = "#7DA3FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Taiga_beach", @@ -610,6 +678,8 @@ local function register_biomes() heat_point = 22, _mcl_biome_type = "cold", _mcl_palette_index = 12, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Taiga_ocean", @@ -625,6 +695,8 @@ local function register_biomes() heat_point = 22, _mcl_biome_type = "cold", _mcl_palette_index = 12, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Forest @@ -642,6 +714,8 @@ local function register_biomes() heat_point = 45, _mcl_biome_type = "medium", _mcl_palette_index = 13, + _mcl_skycolor = "#79A6FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Forest_beach", @@ -657,6 +731,8 @@ local function register_biomes() heat_point = 45, _mcl_biome_type = "medium", _mcl_palette_index = 13, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Forest_ocean", @@ -672,6 +748,8 @@ local function register_biomes() heat_point = 45, _mcl_biome_type = "medium", _mcl_palette_index = 13, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Flower Forest @@ -689,6 +767,8 @@ local function register_biomes() heat_point = 32, _mcl_biome_type = "medium", _mcl_palette_index = 14, + _mcl_skycolor = "#79A6FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "FlowerForest_beach", @@ -704,6 +784,8 @@ local function register_biomes() heat_point = 32, _mcl_biome_type = "medium", _mcl_palette_index = 14, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "FlowerForest_ocean", @@ -719,6 +801,8 @@ local function register_biomes() heat_point = 32, _mcl_biome_type = "medium", _mcl_palette_index = 14, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Birch Forest @@ -736,6 +820,8 @@ local function register_biomes() heat_point = 31, _mcl_biome_type = "medium", _mcl_palette_index = 15, + _mcl_skycolor = "#7AA5FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "BirchForest_ocean", @@ -751,6 +837,8 @@ local function register_biomes() heat_point = 31, _mcl_biome_type = "medium", _mcl_palette_index = 15, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Birch Forest M @@ -768,6 +856,8 @@ local function register_biomes() heat_point = 27, _mcl_biome_type = "medium", _mcl_palette_index = 16, + _mcl_skycolor = "#7AA5FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "BirchForestM_ocean", @@ -783,6 +873,8 @@ local function register_biomes() heat_point = 27, _mcl_biome_type = "medium", _mcl_palette_index = 16, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Desert @@ -801,6 +893,8 @@ local function register_biomes() heat_point = 94, _mcl_biome_type = "hot", _mcl_palette_index = 17, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Desert_ocean", @@ -816,6 +910,8 @@ local function register_biomes() heat_point = 94, _mcl_biome_type = "hot", _mcl_palette_index = 17, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Roofed Forest @@ -833,6 +929,8 @@ local function register_biomes() heat_point = 27, _mcl_biome_type = "medium", _mcl_palette_index = 18, + _mcl_skycolor = "#79A6FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "RoofedForest_ocean", @@ -848,6 +946,8 @@ local function register_biomes() heat_point = 27, _mcl_biome_type = "medium", _mcl_palette_index = 18, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mesa: Starts with a couple of sand-covered layers (the "sandlevel"), @@ -866,6 +966,8 @@ local function register_biomes() heat_point = 100, _mcl_biome_type = "hot", _mcl_palette_index = 19, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Helper biome for the red sand at the bottom of Mesas. minetest.register_biome({ @@ -883,6 +985,8 @@ local function register_biomes() heat_point = 100, _mcl_biome_type = "hot", _mcl_palette_index = 19, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Mesa_ocean", @@ -899,6 +1003,8 @@ local function register_biomes() heat_point = 100, _mcl_biome_type = "hot", _mcl_palette_index = 19, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mesa Bryce: Variant of Mesa, but with perfect strata and a much smaller red sand desert @@ -916,6 +1022,8 @@ local function register_biomes() heat_point = 100, _mcl_biome_type = "hot", _mcl_palette_index = 20, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaBryce_sandlevel", @@ -932,6 +1040,8 @@ local function register_biomes() heat_point = 100, _mcl_biome_type = "hot", _mcl_palette_index = 20, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaBryce_ocean", @@ -948,6 +1058,8 @@ local function register_biomes() heat_point = 100, _mcl_biome_type = "hot", _mcl_palette_index = 20, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) @@ -969,6 +1081,8 @@ local function register_biomes() vertical_blend = 0, -- we want a sharp transition _mcl_biome_type = "hot", _mcl_palette_index = 21, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) -- The oak forest plateau of this biome. -- This is a plateau for grass blocks, dry shrubs, tall grass, coarse dirt and oaks. @@ -988,6 +1102,8 @@ local function register_biomes() heat_point = 60, _mcl_biome_type = "hot", _mcl_palette_index = 21, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaPlateauF_sandlevel", @@ -1004,6 +1120,8 @@ local function register_biomes() heat_point = 60, _mcl_biome_type = "hot", _mcl_palette_index = 21, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaPlateauF_ocean", @@ -1020,6 +1138,8 @@ local function register_biomes() heat_point = 60, _mcl_biome_type = "hot", _mcl_palette_index = 21, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mesa Plateau FM @@ -1041,6 +1161,8 @@ local function register_biomes() vertical_blend = 5, _mcl_biome_type = "hot", _mcl_palette_index = 22, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Grass plateau minetest.register_biome({ @@ -1058,6 +1180,8 @@ local function register_biomes() heat_point = 60, _mcl_biome_type = "hot", _mcl_palette_index = 22, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaPlateauFM_sandlevel", @@ -1076,6 +1200,8 @@ local function register_biomes() vertical_blend = 4, _mcl_biome_type = "hot", _mcl_palette_index = 22, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaPlateauFM_ocean", @@ -1092,6 +1218,8 @@ local function register_biomes() heat_point = 60, _mcl_biome_type = "hot", _mcl_palette_index = 22, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) @@ -1110,6 +1238,8 @@ local function register_biomes() heat_point = 79, _mcl_biome_type = "hot", _mcl_palette_index = 1, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Savanna_beach", @@ -1125,6 +1255,8 @@ local function register_biomes() heat_point = 79, _mcl_biome_type = "hot", _mcl_palette_index = 1, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Savanna_ocean", @@ -1140,6 +1272,8 @@ local function register_biomes() heat_point = 79, _mcl_biome_type = "hot", _mcl_palette_index = 1, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Savanna M @@ -1159,6 +1293,8 @@ local function register_biomes() heat_point = 100, _mcl_biome_type = "hot", _mcl_palette_index = 23, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "SavannaM_ocean", @@ -1174,6 +1310,8 @@ local function register_biomes() heat_point = 100, _mcl_biome_type = "hot", _mcl_palette_index = 23, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Jungle @@ -1191,6 +1329,8 @@ local function register_biomes() heat_point = 81, _mcl_biome_type = "medium", _mcl_palette_index = 24, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Jungle_shore", @@ -1206,6 +1346,8 @@ local function register_biomes() heat_point = 81, _mcl_biome_type = "medium", _mcl_palette_index = 24, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Jungle_ocean", @@ -1222,6 +1364,8 @@ local function register_biomes() heat_point = 81, _mcl_biome_type = "medium", _mcl_palette_index = 24, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Jungle M @@ -1240,6 +1384,8 @@ local function register_biomes() heat_point = 81, _mcl_biome_type = "medium", _mcl_palette_index = 25, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "JungleM_shore", @@ -1255,6 +1401,8 @@ local function register_biomes() heat_point = 81, _mcl_biome_type = "medium", _mcl_palette_index = 25, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "JungleM_ocean", @@ -1271,6 +1419,8 @@ local function register_biomes() heat_point = 81, _mcl_biome_type = "medium", _mcl_palette_index = 25, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Jungle Edge @@ -1288,6 +1438,8 @@ local function register_biomes() heat_point = 76, _mcl_biome_type = "medium", _mcl_palette_index = 26, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "JungleEdge_ocean", @@ -1303,6 +1455,8 @@ local function register_biomes() heat_point = 76, _mcl_biome_type = "medium", _mcl_palette_index = 26, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Jungle Edge M (very rare). @@ -1323,6 +1477,8 @@ local function register_biomes() heat_point = 79, _mcl_biome_type = "medium", _mcl_palette_index = 27, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "JungleEdgeM_ocean", @@ -1338,8 +1494,64 @@ local function register_biomes() heat_point = 79, _mcl_biome_type = "medium", _mcl_palette_index = 27, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) + -- Mangrove swamp + minetest.register_biome({ + name = "MangroveSwamp", + node_top = "mcl_mud:mud", + depth_top = 1, + node_filler = "mcl_mud:mud", + depth_filler = 3, + node_riverbed = "mcl_core:dirt", + depth_riverbed = 2, + y_min = 1, + -- Note: Limited in height! + y_max = 27, + humidity_point = 95, + heat_point = 94, + _mcl_biome_type = "hot", + _mcl_palette_index = 27, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "MangroveSwamp_shore", + node_top = "mcl_mud:mud", + depth_top = 1, + node_filler = "mcl_mud:mud", + depth_filler = 3, + node_riverbed = "mcl_core:dirt", + depth_riverbed = 2, + y_min = -5, + y_max = 0, + humidity_point = 95, + heat_point = 94, + _mcl_biome_type = "hot", + _mcl_palette_index = 27, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "MangroveSwamp_ocean", + node_top = "mcl_core:dirt", + depth_top = 1, + node_filler = "mcl_core:dirt", + depth_filler = 3, + node_riverbed = "mcl_core:gravel", + depth_riverbed = 2, + y_min = OCEAN_MIN, + y_max = -6, + vertical_blend = 1, + humidity_point = 95, + heat_point = 94, + _mcl_biome_type = "hot", + _mcl_palette_index = 27, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor + }) -- Swampland minetest.register_biome({ name = "Swampland", @@ -1356,6 +1568,8 @@ local function register_biomes() heat_point = 50, _mcl_biome_type = "medium", _mcl_palette_index = 28, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Swampland_shore", @@ -1371,6 +1585,8 @@ local function register_biomes() heat_point = 50, _mcl_biome_type = "medium", _mcl_palette_index = 28, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Swampland_ocean", @@ -1387,6 +1603,8 @@ local function register_biomes() heat_point = 50, _mcl_biome_type = "medium", _mcl_palette_index = 28, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mushroom Island / Mushroom Island Shore (rare) @@ -1407,6 +1625,8 @@ local function register_biomes() heat_point = 50, _mcl_biome_type = "medium", _mcl_palette_index = 29, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ @@ -1423,6 +1643,8 @@ local function register_biomes() heat_point = 50, _mcl_biome_type = "medium", _mcl_palette_index = 29, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MushroomIsland_ocean", @@ -1438,6 +1660,8 @@ local function register_biomes() heat_point = 50, _mcl_biome_type = "medium", _mcl_palette_index = 29, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Add deep ocean and underground biomes automatically. @@ -1460,6 +1684,8 @@ local function register_biomes() vertical_blend = 5, _mcl_biome_type = minetest.registered_biomes[biome]._mcl_biome_type, _mcl_palette_index = minetest.registered_biomes[biome]._mcl_palette_index, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Underground biomes are used to identify the underground and to prevent nodes from the surface @@ -1472,6 +1698,8 @@ local function register_biomes() y_max = DEEP_OCEAN_MIN - 1, _mcl_biome_type = minetest.registered_biomes[biome]._mcl_biome_type, _mcl_palette_index = minetest.registered_biomes[biome]._mcl_palette_index, + _mcl_skycolor = minetest.registered_biomes[biome]._mcl_skycolor, + _mcl_fogcolor = minetest.registered_biomes[biome]._mcl_fogcolor, }) end @@ -1482,21 +1710,227 @@ local function register_dimension_biomes() --[[ REALMS ]] --[[ THE NETHER ]] + -- the following decoration is a hack to cover exposed bedrock in netherrack - be careful not to put any ceiling decorations in a way that would apply to this (they would get generated regardless of biome) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:bedrock"}, + sidelen = 16, + fill_ratio = 10, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_max + 15, + height = 6, + max_height = 10, + decoration = "mcl_nether:netherrack", + flags = "all_ceilings", + param2 = 0, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:bedrock"}, + sidelen = 16, + fill_ratio = 10, + y_min = mcl_vars.mg_nether_min - 10, + y_max = mcl_vars.mg_lava_nether_max, + height = 7, + max_height = 14, + decoration = "mcl_nether:netherrack", + flags = "all_floors,force_placement", + param2 = 0, + }) + + minetest.register_biome({ name = "Nether", node_filler = "mcl_nether:netherrack", node_stone = "mcl_nether:netherrack", + node_top = "mcl_nether:netherrack", node_water = "air", node_river_water = "air", node_cave_liquid = "air", y_min = mcl_vars.mg_nether_min, - -- FIXME: For some reason the Nether stops generating early if this constant is not added. - -- Figure out why. + y_max = mcl_vars.mg_nether_max + 80, heat_point = 100, humidity_point = 0, _mcl_biome_type = "hot", _mcl_palette_index = 17, +-- _mcl_skycolor = nether_skycolor, +-- _mcl_fogcolor = "#330808" + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack","mcl_nether:glowstone","mcl_blackstone:nether_gold","mcl_nether:quartz_ore","mcl_core:gravel","mcl_nether:soul_sand","mcl_nether:glowstone","mcl_nether:magma"}, + sidelen = 16, + fill_ratio = 10, + biomes = { "Nether" }, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_nether:netherrack", + flags = "all_floors", + param2 = 0, + }) + + minetest.register_biome({ + name = "SoulsandValley", + node_filler = "mcl_nether:netherrack", + node_stone = "mcl_nether:netherrack", + node_top = "mcl_blackstone:soul_soil", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max + 80, + heat_point = 77, + humidity_point = 33, + _mcl_biome_type = "hot", + _mcl_palette_index = 17, +-- _mcl_skycolor = nether_skycolor, +-- _mcl_fogcolor = "#1B4745" + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack","mcl_nether:glowstone","mcl_nether:magma"}, + sidelen = 16, + fill_ratio = 10, + biomes = { "SoulsandValley" }, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_blackstone:soul_soil", + flags = "all_floors, all_ceilings", + param2 = 0, + }) + + minetest.register_ore({ + ore_type = "blob", + ore = "mcl_nether:soul_sand", + wherein = { "mcl_nether:netherrack", "mcl_blackstone:soul_soil" }, + clust_scarcity = 100, + clust_num_ores = 225, + clust_size = 15, + biomes = { "SoulsandValley" }, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + noise_params = { + offset = 0, + scale = 1, + spread = { x = 250, y = 250, z = 250 }, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } + }) + minetest.register_biome({ + name = "CrimsonForest", + node_filler = "mcl_nether:netherrack", + node_stone = "mcl_nether:netherrack", + node_top = "mcl_crimson:crimson_nylium", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max + 80, + heat_point = 60, + humidity_point = 47, + _mcl_biome_type = "hot", + _mcl_palette_index = 17, +-- _mcl_skycolor = nether_skycolor, +-- _mcl_fogcolor = "#330303" + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack","mcl_nether:glowstone","mcl_blackstone:nether_gold","mcl_nether:quartz_ore","mcl_core:gravel","mcl_nether:soul_sand","mcl_nether:magma","mcl_blackstone:blackstone"}, + sidelen = 16, + fill_ratio = 10, + biomes = { "CrimsonForest" }, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_crimson:crimson_nylium", + flags = "all_floors", + param2 = 0, + }) + minetest.register_biome({ + name = "WarpedForest", + node_filler = "mcl_nether:netherrack", + node_stone = "mcl_nether:netherrack", + node_top = "mcl_crimson:warped_nylium", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max + 80, + heat_point = 37, + humidity_point = 70, + _mcl_biome_type = "hot", + _mcl_palette_index = 17, +-- _mcl_skycolor = nether_skycolor, +-- _mcl_fogcolor = "#1A051A" + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack","mcl_nether:glowstone","mcl_blackstone:nether_gold","mcl_nether:quartz_ore","mcl_core:gravel","mcl_nether:soul_sand","mcl_nether:magma","mcl_blackstone:blackstone"}, + sidelen = 16, + fill_ratio = 10, + biomes = { "WarpedForest" }, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_crimson:warped_nylium", + flags = "all_floors", + param2 = 0, + }) + minetest.register_biome({ + name = "BasaltDelta", + node_filler = "mcl_nether:netherrack", + node_stone = "mcl_nether:netherrack", + node_top = "mcl_blackstone:basalt", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max + 80, + heat_point = 27, + humidity_point = 80, + _mcl_biome_type = "hot", + _mcl_palette_index = 17, +-- _mcl_skycolor = nether_skycolor, +-- _mcl_fogcolor = "#685F70" + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack","mcl_nether:glowstone","mcl_blackstone:nether_gold","mcl_nether:quartz_ore","mcl_core:gravel","mcl_nether:soul_sand","mcl_blackstone:blackstone","mcl_nether:magma"}, + sidelen = 16, + fill_ratio = 10, + biomes = { "BasaltDelta" }, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_blackstone:basalt", + flags = "all_floors", + param2 = 0, + }) + + minetest.register_ore({ + ore_type = "blob", + ore = "mcl_blackstone:blackstone", + wherein = {"mcl_nether:netherrack","mcl_nether:glowstone","mcl_core:gravel"}, + clust_scarcity = 100, + clust_num_ores = 400, + clust_size = 20, + biomes = { "BasaltDelta" }, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + noise_params = { + offset = 0, + scale = 1, + spread = { x = 250, y = 250, z = 250 }, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } }) --[[ THE END ]] @@ -1507,14 +1941,121 @@ local function register_dimension_biomes() node_water = "air", node_river_water = "air", node_cave_liquid = "air", - -- FIXME: For some reason the End stops generating early if this constant is not added. - -- Figure out why. y_min = mcl_vars.mg_end_min, y_max = mcl_vars.mg_end_max + 80, - heat_point = 50, - humidity_point = 50, + heat_point = 1000, --ridiculously high values so End Island always takes precedent + humidity_point = 1000, + vertical_blend = 16, _mcl_biome_type = "medium", _mcl_palette_index = 0, +-- _mcl_skycolor = end_skycolor, +-- _mcl_fogcolor = end_fogcolor + }) + minetest.register_biome({ + name = "EndBarrens", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_palette_index = 0, +-- _mcl_skycolor = end_skycolor, +-- _mcl_fogcolor = end_fogcolor + }) + minetest.register_biome({ + name = "EndMidlands", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_palette_index = 0, +-- _mcl_skycolor = end_skycolor, +-- _mcl_fogcolor = end_fogcolor + }) + minetest.register_biome({ + name = "EndHighlands", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_palette_index = 0, +-- _mcl_skycolor = end_skycolor, +-- _mcl_fogcolor = end_fogcolor + }) + minetest.register_biome({ + name = "EndSmallIslands", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_palette_index = 0, +-- _mcl_skycolor = end_skycolor, +-- _mcl_fogcolor = end_fogcolor + }) + + minetest.register_biome({ + name = "EndBorder", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 500, + humidity_point = 500, + vertical_blend = 16, + max_pos = {x = 1250, y = mcl_vars.mg_end_min + 512, z = 1250}, + min_pos = {x = -1250, y = mcl_vars.mg_end_min, z = -1250}, + _mcl_biome_type = "medium", + _mcl_palette_index = 0, +-- _mcl_skycolor = end_skycolor, +-- _mcl_fogcolor = end_fogcolor + }) + + minetest.register_biome({ + name = "EndIsland", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + max_pos = {x = 650, y = mcl_vars.mg_end_min + 512, z = 650}, + min_pos = {x = -650, y = mcl_vars.mg_end_min, z = -650}, + heat_point = 50, + humidity_point = 50, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_palette_index = 0, +-- _mcl_skycolor = end_skycolor, +-- _mcl_fogcolor = end_fogcolor }) end @@ -1581,6 +2122,39 @@ local function register_biome_ores() "MesaPlateauFM", "MesaPlateauFM_sandlevel", "MesaPlateauFM_ocean", }, }) end + --nether gold + if mg_name ~= "v6" then + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_blackstone:blackstone_gilded", + wherein = "mcl_blackstone:blackstone", + clust_scarcity = 4775, + clust_num_ores = 2, + clust_size = 2, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_blackstone:nether_gold", + wherein = "mcl_nether:netherrack", + clust_scarcity = 830, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_blackstone:nether_gold", + wherein = "mcl_nether:netherrack", + clust_scarcity = 1660, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + end end -- Register “fake” ores directly related to the biomes. These are mostly low-level landscape alternations @@ -2014,7 +2588,7 @@ local function register_dimension_ores() clust_scarcity = 26 * 26 * 26, clust_size = 5, y_min = mcl_vars.mg_lava_nether_max + 10, - y_max = mcl_vars.mg_nether_max, + y_max = mcl_vars.mg_nether_max - 13, noise_threshold = 0.0, noise_params = { offset = 0.5, @@ -2077,11 +2651,24 @@ local function register_dimension_ores() ore_type = "scatter", ore = "mcl_nether:nether_lava_source", wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 13500, --rare + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_max - 13, + }) + + local lava_biomes = {"BasaltDelta","Nether"} + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 500, clust_num_ores = 1, clust_size = 1, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_lava_nether_max + 1, + biomes = lava_biomes, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_lava_nether_max + 1, }) minetest.register_ore({ @@ -2091,6 +2678,7 @@ local function register_dimension_ores() clust_scarcity = 1000, clust_num_ores = 1, clust_size = 1, + biomes = lava_biomes, y_min = mcl_vars.mg_lava_nether_max + 2, y_max = mcl_vars.mg_lava_nether_max + 12, }) @@ -2102,6 +2690,7 @@ local function register_dimension_ores() clust_scarcity = 2000, clust_num_ores = 1, clust_size = 1, + biomes = lava_biomes, y_min = mcl_vars.mg_lava_nether_max + 13, y_max = mcl_vars.mg_lava_nether_max + 48, }) @@ -2112,8 +2701,9 @@ local function register_dimension_ores() clust_scarcity = 3500, clust_num_ores = 1, clust_size = 1, + biomes = lava_biomes, y_min = mcl_vars.mg_lava_nether_max + 49, - y_max = mcl_vars.mg_nether_max, + y_max = mcl_vars.mg_nether_max - 13, }) --[[ THE END ]] @@ -2129,10 +2719,47 @@ local function register_dimension_ores() end_wherein = {"air"} end + local mult = 1.0 + minetest.register_ore({ ore_type = "stratum", ore = "mcl_end:end_stone", wherein = end_wherein, + biomes = {"EndSmallIslands","Endborder"}, + y_min = mcl_vars.mg_end_min+64, + y_max = mcl_vars.mg_end_min+80, + clust_num_ores = 3375, + clust_size = 15, + + noise_params = { + offset = mcl_vars.mg_end_min+70, + scale = -1, + spread = {x=84, y=84, z=84}, + seed = 145, + octaves = 3, + persist = 0.6, + lacunarity = 2, + --flags = "defaults", + }, + + np_stratum_thickness = { + offset = 0, + scale = 15, + spread = {x=84, y=84, z=84}, + seed = 145, + octaves = 3, + persist = 0.6, + lacunarity = 2, + --flags = "defaults", + }, + clust_scarcity = 1, + }) + + minetest.register_ore({ + ore_type = "stratum", + ore = "mcl_end:end_stone", + wherein = end_wherein, + biomes = {"End","EndMidlands","EndHighlands","EndBarrens"}, y_min = mcl_vars.mg_end_min+64, y_max = mcl_vars.mg_end_min+80, @@ -2160,6 +2787,7 @@ local function register_dimension_ores() ore_type = "stratum", ore = "mcl_end:end_stone", wherein = end_wherein, + biomes = {"End","EndMidlands","EndHighlands","EndBarrens"}, y_min = mcl_vars.mg_end_min+64, y_max = mcl_vars.mg_end_min+80, @@ -2186,6 +2814,7 @@ local function register_dimension_ores() ore_type = "stratum", ore = "mcl_end:end_stone", wherein = end_wherein, + biomes = {"End","EndMidlands","EndHighlands","EndBarrens"}, y_min = mcl_vars.mg_end_min+64, y_max = mcl_vars.mg_end_min+80, @@ -2219,11 +2848,11 @@ local function register_grass_decoration(grasstype, offset, scale, biomes) local place_on, seed, node if grasstype == "fern" then node = "mcl_flowers:fern" - place_on = {"group:grass_block_no_snow", "mcl_core:podzol"} + place_on = {"group:grass_block_no_snow", "mcl_core:podzol","mcl_mud:mud"} seed = 333 elseif grasstype == "tallgrass" then node = "mcl_flowers:tallgrass" - place_on = {"group:grass_block_no_snow"} + place_on = {"group:grass_block_no_snow","mcl_mud:mud"} seed = 420 end local noise = { @@ -2292,9 +2921,218 @@ local function register_seagrass_decoration(grasstype, offset, scale, biomes) end end +local coral_min = OCEAN_MIN +local coral_max = -10 +local warm_oceans = { + "JungleEdgeM_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "Swampland_ocean", + "Mesa_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "MushroomIsland_ocean", + "SavannaM_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "Jungle_ocean", + "Desert_ocean", + "JungleM_ocean", + "MangroveSwamp_ocean" +} +local corals = { + "brain", + "horn", + "bubble", + "tube", + "fire" +} +local function register_coral_decos(ck) + local c = corals[ck] + local noise = { + offset = -0.0085, + scale = 0.002, + spread = {x = 25, y = 120, z = 25}, + seed = 235, + octaves = 5, + persist = 1.8, + lacunarity = 3.5, + flags = "absvalue" + } + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:sand","mcl_core:gravel","mcl_mud:mud"}, + sidelen = 80, + noise_params = noise, + biomes = warm_oceans, + y_min = coral_min, + y_max = coral_max, + schematic = mod_mcl_structures.."/schematics/mcl_structures_coral_"..c.."_1.mts", + rotation = "random", + flags = "all_floors,force_placement", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:sand","mcl_core:gravel","mcl_mud:mud"}, + noise_params = noise, + sidelen = 80, + biomes = warm_oceans, + y_min = coral_min, + y_max = coral_max, + schematic = mod_mcl_structures.."/schematics/mcl_structures_coral_"..c.."_2.mts", + rotation = "random", + flags = "all_floors,force_placement", + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:"..c.."_coral_block"}, + sidelen = 16, + fill_ratio = 3, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:"..c.."_coral", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:horn_coral_block"}, + sidelen = 16, + fill_ratio = 7, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:"..c.."_coral_fan", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + }) +end local function register_decorations() + -- Coral Reefs + for k,_ in pairs(corals) do + register_coral_decos(k) + end + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand","mcl_core:gravel","mcl_mud:mud"}, + sidelen = 16, + noise_params = { + offset = -0.0085, + scale = 0.002, + spread = {x = 25, y = 120, z = 25}, + seed = 235, + octaves = 5, + persist = 1.8, + lacunarity = 3.5, + flags = "absvalue" + }, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:dead_brain_coral_block"}, + sidelen = 16, + fill_ratio = 3, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:sea_pickle_1_dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:dead_brain_coral_block"}, + sidelen = 16, + fill_ratio = 3, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:sea_pickle_2_dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:dead_brain_coral_block"}, + sidelen = 16, + fill_ratio = 2, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:sea_pickle_3_dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:dead_brain_coral_block"}, + sidelen = 16, + fill_ratio = 2, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:sea_pickle_4_dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + --rare CORAl + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:sand","mcl_core:gravel"}, + fill_ratio = 0.0001, + sidelen = 80, + biomes = warm_oceans, + y_min = coral_min, + y_max = coral_max, + schematic = mod_mcl_structures.."/schematics/coral_cora.mts", + rotation = "random", + flags = "place_center_x,place_center_z, force_placement", + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt_with_grass","mcl_core:podzol"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.012, + spread = {x = 100, y = 100, z = 100}, + seed = 354, + octaves = 1, + persist = 0.5, + lacunarity = 1.0, + flags = "absvalue" + }, + biomes = {"Taiga","ColdTaiga","MegaTaiga","MegaSpruceTaiga", "Forest"}, + y_max = mcl_vars.mg_overworld_max, + y_min = 2, + decoration = "mcl_sweet_berry:sweet_berry_bush_3" + }) + -- Large ice spike minetest.register_decoration({ deco_type = "schematic", @@ -2540,7 +3378,48 @@ local function register_decorations() flags = "place_center_x, place_center_z", rotation = "random", }) - + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 16, + --[[noise_params = { + offset = 0.01, + scale = 0.00001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.33 + },]]-- + fill_ratio = 0.0002, + biomes = {"FlowerForest"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core.."/schematics/mcl_core_oak_classic_bee_nest.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + spawn_by = "group:flower", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 16, + --[[noise_params = { + offset = 0.01, + scale = 0.00001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.33 + },]]-- + fill_ratio = 0.00002, + biomes = {"Forest"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core.."/schematics/mcl_core_oak_classic_bee_nest.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + spawn_by = "group:flower", + }) -- Rare balloon oak minetest.register_decoration({ @@ -2584,15 +3463,155 @@ local function register_decorations() rotation = "random", }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_1", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.0065, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove.."/schematics/mcl_mangrove_tree_1.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_2", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.0045, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + y_min = -1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove.."/schematics/mcl_mangrove_tree_2.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_3", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.023, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + y_min = -1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove.."/schematics/mcl_mangrove_tree_3.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_4", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.023, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + y_min = -1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove.."/schematics/mcl_mangrove_tree_4.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_4", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.023, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + y_min = -1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove.."/schematics/mcl_mangrove_tree_5.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + --[[noise_params = { + offset = 0.01, + scale = 0.00001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.33 + },]]-- + fill_ratio = 0.0005, + biomes = {"MangroveSwamp"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove.."/schematics/mcl_mangrove_bee_nest.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + spawn_by = "group:flower", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.045, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + y_min = 0, + y_max = 0, + decoration = "mcl_mangrove:water_logged_roots", + flags = "place_center_x, place_center_z, force_placement", + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_mangrove:mangrove_roots"}, + spawn_by = {"group:water"}, + num_spawn_by = 2, + sidelen = 80, + fill_ratio = 10, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + y_min = 0, + y_max = 0, + decoration = "mcl_mangrove:water_logged_roots", + flags = "place_center_x, place_center_z, force_placement, all_ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.045, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + place_offset_y = -1, + decoration = "mcl_mangrove:mangrove_mud_roots", + flags = "place_center_x, place_center_z, force_placement", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.008, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + decoration = "mcl_core:deadbush", + flags = "place_center_x, place_center_z", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:water_source"}, + sidelen = 80, + fill_ratio = 0.035, + biomes = {"MangroveSwamp","MangroveSwamp_shore"}, + decoration = "mcl_flowers:waterlily", + flags = "place_center_x, place_center_z, liquid_surface", + }) + -- Jungle tree - -- Huge jungle tree (2 variants) - for i=1, 2 do + -- Huge jungle tree (4 variants) + for i=1, 4 do minetest.register_decoration({ deco_type = "schematic", place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, - fill_ratio = 0.00125, + fill_ratio = 0.0008, biomes = {"Jungle"}, y_min = 4, y_max = mcl_vars.mg_overworld_max, @@ -2604,7 +3623,7 @@ local function register_decorations() deco_type = "schematic", place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, - fill_ratio = 0.004, + fill_ratio = 0.003, biomes = {"JungleM"}, y_min = 4, y_max = mcl_vars.mg_overworld_max, @@ -2619,7 +3638,55 @@ local function register_decorations() deco_type = "schematic", place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, - fill_ratio = 0.045, + fill_ratio = 0.025, + biomes = {"Jungle"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + fill_ratio = 0.015, + biomes = {"Jungle"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_tree_2.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + fill_ratio = 0.005, + biomes = {"Jungle"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_tree_3.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + fill_ratio = 0.005, + biomes = {"Jungle"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_tree_4.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + fill_ratio = 0.025, biomes = {"Jungle"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, @@ -2648,11 +3715,10 @@ local function register_decorations() biomes = {"JungleM"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = mod_mcl_core.."/schematics/mcl_core_jungle_tree.mts", + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_tree_2.mts", flags = "place_center_x, place_center_z", rotation = "random", }) - -- Spruce local function quick_spruce(seed, offset, sprucename, biomes, y) if not y then @@ -2843,6 +3909,27 @@ local function register_decorations() schematic = mod_mcl_core.."/schematics/mcl_core_birch.mts", flags = "place_center_x, place_center_z", }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 16, + --[[noise_params = { + offset = 0.01, + scale = 0.00001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.33 + },]]-- + fill_ratio = 0.00002, + biomes = {"Forest", "BirchForest", "BirchForestM"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core.."/schematics/mcl_core_birch_bee_nest.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + spawn_by = "group:flower", + }) -- Dark Oak minetest.register_decoration({ @@ -2975,6 +4062,41 @@ local function register_decorations() rotation = "0", }) + --Snow on snowy dirt + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt_with_grass_snow"}, + sidelen = 80, + fill_ratio = 10, + flags = "all_floors", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:snow", + }) + + --Mushrooms in caves + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:material_stone"}, + sidelen = 80, + fill_ratio = 0.009, + noise_threshold = 2.0, + flags = "all_floors", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_mushrooms:mushroom_red", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:material_stone"}, + sidelen = 80, + fill_ratio = 0.009, + noise_threshold = 2.0, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_mushrooms:mushroom_brown", + }) + -- Mossy cobblestone boulder (3×3) minetest.register_decoration({ deco_type = "schematic", @@ -2993,6 +4115,7 @@ local function register_decorations() y_max = mcl_vars.mg_overworld_max, schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder.mts", flags = "place_center_x, place_center_z", + rotation = "random", }) -- Small mossy cobblestone boulder (2×2) @@ -3013,6 +4136,7 @@ local function register_decorations() y_max = mcl_vars.mg_overworld_max, schematic = mod_mcl_structures.."/schematics/mcl_structures_boulder_small.mts", flags = "place_center_x, place_center_z", + rotation = "random", }) -- Cacti @@ -3212,7 +4336,7 @@ local function register_decorations() sidelen = 80, noise_params = { offset = 0.0196, - scale = 0.025, + scale = 0.015, spread = {x = 250, y = 250, z = 250}, seed = 2930, octaves = 4, @@ -3221,7 +4345,25 @@ local function register_decorations() biomes = {"Jungle"}, y_min = 3, y_max = mcl_vars.mg_overworld_max, - schematic = jungle_bush_schematic, + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_bush_oak_leaves.mts", + flags = "place_center_x, place_center_z", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + noise_params = { + offset = 0.0196, + scale = 0.005, + spread = {x = 250, y = 250, z = 250}, + seed = 2930, + octaves = 4, + persist = 0.6, + }, + biomes = {"Jungle"}, + y_min = 3, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_bush_oak_leaves_2.mts", flags = "place_center_x, place_center_z", }) minetest.register_decoration({ @@ -3239,7 +4381,7 @@ local function register_decorations() biomes = {"JungleM"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = jungle_bush_schematic, + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_bush_oak_leaves.mts", flags = "place_center_x, place_center_z", }) minetest.register_decoration({ @@ -3257,7 +4399,7 @@ local function register_decorations() biomes = {"JungleEdge", "JungleEdgeM"}, y_min = 3, y_max = mcl_vars.mg_overworld_max, - schematic = jungle_bush_schematic, + schematic = mod_mcl_core.."/schematics/mcl_core_jungle_bush_oak_leaves.mts", flags = "place_center_x, place_center_z", }) @@ -3558,7 +4700,7 @@ local function register_decorations() -- Grasses and ferns local grass_forest = {"Plains", "Taiga", "Forest", "FlowerForest", "BirchForest", "BirchForestM", "RoofedForest", "Swampland", } local grass_mpf = {"MesaPlateauF_grasstop"} - local grass_plains = {"Plains", "SunflowerPlains", "JungleEdge", "JungleEdgeM" } + local grass_plains = {"Plains", "SunflowerPlains", "JungleEdge", "JungleEdgeM", "MangroveSwamp" } local grass_savanna = {"Savanna", "SavannaM"} local grass_sparse = {"ExtremeHills", "ExtremeHills+", "ExtremeHills+_snowtop", "ExtremeHillsM", "Jungle" } local grass_mpfm = {"MesaPlateauFM_grasstop" } @@ -3581,7 +4723,7 @@ local function register_decorations() register_grass_decoration("tallgrass", 0.05, -0.03, grass_sparse) register_grass_decoration("tallgrass", 0.05, 0.05, grass_mpfm) - local fern_minimal = { "Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "MegaTaiga", "MegaSpruceTaiga", "ColdTaiga" } + local fern_minimal = { "Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "MegaTaiga", "MegaSpruceTaiga", "ColdTaiga", "MangroveSwamp" } local fern_low = { "Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "MegaTaiga", "MegaSpruceTaiga" } local fern_Jungle = { "Jungle", "JungleM", "JungleEdge", "JungleEdgeM" } --local fern_JungleM = { "JungleM" }, @@ -3911,15 +5053,355 @@ end -- Decorations in non-Overworld dimensions local function register_dimension_decorations() --[[ NETHER ]] - -- TODO: Nether + --NETHER WASTES (Nether) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack","mcl_nether:magma"}, + sidelen = 16, + fill_ratio = 0.04, + biomes = {"Nether"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 1, + flags = "all_floors", + decoration = "mcl_fire:eternal_fire", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack"}, + sidelen = 16, + fill_ratio = 0.013, + biomes = {"Nether"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 1, + flags = "all_floors", + decoration = "mcl_mushrooms:mushroom_brown", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack"}, + sidelen = 16, + fill_ratio = 0.012, + biomes = {"Nether"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 1, + flags = "all_floors", + decoration = "mcl_mushrooms:mushroom_red", + }) + + -- WARPED FOREST + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.02, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 10, + flags = "all_floors", + decoration = "mcl_crimson:warped_fungus", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:warped_tree1", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.007, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 15, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson.."/schematics/warped_fungus_1.mts", + size = {x = 5, y = 11, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:warped_tree2", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.005, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 10, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson.."/schematics/warped_fungus_2.mts", + size = {x = 5, y = 6, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:warped_tree3", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.003, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 14, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson.."/schematics/warped_fungus_3.mts", + size = {x = 5, y = 12, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:warped_nylium","mcl_crimson:twisting_vines"}, + sidelen = 16, + fill_ratio = 0.032, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + height = 2, + height_max = 8, + decoration = "mcl_crimson:twisting_vines", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.0812, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + max_height = 5, + decoration = "mcl_crimson:warped_roots", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.052, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + decoration = "mcl_crimson:nether_sprouts", + }) + -- CRIMSON FOREST + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.02, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 10, + flags = "all_floors", + decoration = "mcl_crimson:crimson_fungus", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:crimson_tree", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.008, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 10, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson.."/schematics/crimson_fungus_1.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:crimson_tree2", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.006, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 15, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson.."/schematics/crimson_fungus_2.mts", + size = {x = 5, y = 12, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:crimson_tree3", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.004, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 20, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson.."/schematics/crimson_fungus_3.mts", + size = {x = 7, y = 13, z = 7}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:warped_nylium","mcl_crimson:weeping_vines","mcl_nether:netherrack"}, + sidelen = 16, + fill_ratio = 0.063, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_deco_max, + flags = "all_ceilings", + height = 2, + height_max = 8, + decoration = "mcl_crimson:weeping_vines", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.082, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + max_height = 5, + decoration = "mcl_crimson:crimson_roots", + }) + + --SOULSAND VALLEY + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_blackstone:soul_soil","mcl_nether:soul_sand"}, + sidelen = 16, + fill_ratio = 0.062, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + max_height = 5, + decoration = "mcl_blackstone:soul_fire", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_blackstone:soul_soil","mcl_nether:soulsand"}, + sidelen = 16, + fill_ratio = 0.000212, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_blackstone.."/schematics/mcl_blackstone_nether_fossil_1.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_blackstone:soul_soil","mcl_nether:soulsand"}, + sidelen = 16, + fill_ratio = 0.0002233, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_blackstone.."/schematics/mcl_blackstone_nether_fossil_2.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_blackstone:soul_soil","mcl_nether:soulsand"}, + sidelen = 16, + fill_ratio = 0.000225, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_blackstone.."/schematics/mcl_blackstone_nether_fossil_3.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_blackstone:soul_soil","mcl_nether:soulsand"}, + sidelen = 16, + fill_ratio = 0.00022323, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_blackstone.."/schematics/mcl_blackstone_nether_fossil_4.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + --BASALT DELTA + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_blackstone:basalt", + place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"}, + sidelen = 80, + height_max = 55, + noise_params={ + offset = -0.0085, + scale = 0.002, + spread = {x = 25, y = 120, z = 25}, + seed = 2325, + octaves = 5, + persist = 2, + lacunarity = 3.5, + flags = "absvalue" + }, + biomes = {"BasaltDelta"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_deco_max - 50, + flags = "all_floors, all ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_blackstone:basalt", + place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"}, + sidelen = 80, + height_max = 15, + noise_params={ + offset = -0.0085, + scale = 0.004, + spread = {x = 25, y = 120, z = 25}, + seed = 235, + octaves = 5, + persist = 2.5, + lacunarity = 3.5, + flags = "absvalue" + }, + biomes = {"BasaltDelta"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_deco_max - 15, + flags = "all_floors, all ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_blackstone:basalt", + place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"}, + sidelen = 80, + height_max = 3, + fill_ratio = 0.4, + biomes = {"BasaltDelta"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_deco_max - 15, + flags = "all_floors, all ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_nether:magma", + place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"}, + sidelen = 80, + fill_ratio = 0.082323, + biomes = {"BasaltDelta"}, + place_offset_y = -1, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, all ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_nether:nether_lava_source", + place_on = {"mcl_blackstone:basalt","mcl_nether:netherrack","mcl_blackstone:blackstone"}, + spawn_by = {"mcl_blackstone:basalt","mcl_blackstone:blackstone"}, + num_spawn_by = 14, + sidelen = 80, + fill_ratio = 4, + biomes = {"BasaltDelta"}, + place_offset_y = -1, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 5, + flags = "all_floors, force_placement", + }) --[[ THE END ]] -- Chorus plant minetest.register_decoration({ - name = "mcl_biomes:chorus_plant", + name = "mcl_biomes:chorus", deco_type = "simple", - place_on = {"mcl_end:end_stone", "air"}, + place_on = {"mcl_end:end_stone"}, flags = "all_floors", sidelen = 16, noise_params = { @@ -3932,9 +5414,31 @@ local function register_dimension_decorations() }, y_min = mcl_vars.mg_end_min, y_max = mcl_vars.mg_end_max, + decoration = "mcl_end:chorus_plant", + height = 1, + height_max = 8, + biomes = { "End", "EndMidlands", "EndHighlands", "EndBarrens", "EndSmallIslands" }, + }) + minetest.register_decoration({ + name = "mcl_biomes:chorus_plant", + deco_type = "simple", + place_on = {"mcl_end:chorus_plant"}, + flags = "all_floors", + sidelen = 16, + fill_ratio = 10, + --[[noise_params = { + offset = -0.012, + scale = 0.024, + spread = {x = 100, y = 100, z = 100}, + seed = 257, + octaves = 3, + persist = 0.6 + },--]] + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max, decoration = "mcl_end:chorus_flower", height = 1, - biomes = { "End" }, + biomes = { "End", "EndMidlands", "EndHighlands", "EndBarrens", "EndSmallIslands" }, }) deco_id_chorus_plant = minetest.get_decoration_id("mcl_biomes:chorus_plant") @@ -3975,14 +5479,53 @@ if mg_name ~= "singlenode" then -- Overworld decorations for v6 are handled in mcl_mapgen_core - if deco_id_chorus_plant then + local deco_ids_fungus ={ + minetest.get_decoration_id("mcl_biomes:crimson_tree1"), + minetest.get_decoration_id("mcl_biomes:crimson_tree2"), + minetest.get_decoration_id("mcl_biomes:crimson_tree3"), + minetest.get_decoration_id("mcl_biomes:warped_tree1"), + minetest.get_decoration_id("mcl_biomes:warped_tree2"), + minetest.get_decoration_id("mcl_biomes:warped_tree3") + } + local deco_ids_trees = { + minetest.get_decoration_id("mcl_biomes:mangrove_tree_1"), + minetest.get_decoration_id("mcl_biomes:mangrove_tree_2"), + minetest.get_decoration_id("mcl_biomes:mangrove_tree_3"), + } + for _,f in pairs(deco_ids_fungus) do + minetest.set_gen_notify({decoration=true}, { f }) + end + for _,f in pairs(deco_ids_trees) do + minetest.set_gen_notify({decoration=true}, { f }) + end + if deco_id_chorus_plant or deco_ids_fungus or deco_ids_trees then mcl_mapgen_core.register_generator("chorus_grow", nil, function(minp, maxp, blockseed) local gennotify = minetest.get_mapgen_object("gennotify") - --local poslist = {} local pr = PseudoRandom(blockseed + 14) + for _,f in pairs(deco_ids_trees) do + for _, pos in ipairs(gennotify["decoration#"..f] or {}) do + local nn=minetest.find_nodes_in_area(vector.offset(pos,-8,-1,-8),vector.offset(pos,8,0,8),{"mcl_mangrove:mangrove_roots"}) + for _,v in pairs(nn) do + local l = pr:next(2,16) + local n = minetest.get_node(vector.offset(v,0,-1,0)).name + if minetest.get_item_group(n,"water") > 0 then + local wl = "mcl_mangrove:water_logged_roots" + if n:find("river") then + wl = "mcl_mangrove:river_water_logged_roots" + end + minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(v,0,0,0),vector.offset(v,0,-l,0),{"group:water"}),{name=wl}) + elseif n == "mcl_mud:mud" then + minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(v,0,0,0),vector.offset(v,0,-l,0),{"mcl_mud:mud"}),{name="mcl_mangrove:mangrove_mud_roots"}) + elseif n == "air" then + minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(v,0,0,0),vector.offset(v,0,-l,0),{"air"}),{name="mcl_mangrove:mangrove_roots"}) + end + end + end + end + if minp.y > -26900 then return end for _, pos in ipairs(gennotify["decoration#"..deco_id_chorus_plant] or {}) do local x, y, z = pos.x, pos.y, pos.z - if x < -2 or x > 2 or z < -2 or z > 2 then + if x < -10 or x > 10 or z < -10 or z > 10 then local realpos = { x = x, y = y + 1, z = z } local node = minetest.get_node(realpos) if node and node.name == "mcl_end:chorus_flower" then @@ -3990,8 +5533,13 @@ if mg_name ~= "singlenode" then end end end + if minp.y > mcl_vars.mg_nether_max then return end + for _,f in pairs(deco_ids_fungus) do + for _, pos in ipairs(gennotify["decoration#"..f] or {}) do + minetest.fix_light(vector.offset(pos,-8,-8,-8),vector.offset(pos,8,8,8)) + end + end end) end end - diff --git a/mods/MAPGEN/mcl_biomes/mod.conf b/mods/MAPGEN/mcl_biomes/mod.conf index 0c6095f3d..6cce58bf4 100644 --- a/mods/MAPGEN/mcl_biomes/mod.conf +++ b/mods/MAPGEN/mcl_biomes/mod.conf @@ -1,4 +1,4 @@ name = mcl_biomes author = maikerumine description = Adds the various biomes and biome-related things for non-v6 map generators. -depends = mcl_init, mcl_mapgen_core, mcl_core, mcl_worlds, mcl_farming, mcl_flowers, mcl_end, mcl_ocean +depends = mcl_init, mcl_mapgen_core, mcl_core, mcl_worlds, mcl_farming, mcl_flowers, mcl_end, mcl_ocean, mcl_crimson, mcl_blackstone, mcl_mangrove diff --git a/mods/MAPGEN/mcl_end_island/init.lua b/mods/MAPGEN/mcl_end_island/init.lua index 730176257..434c3c6ef 100644 --- a/mods/MAPGEN/mcl_end_island/init.lua +++ b/mods/MAPGEN/mcl_end_island/init.lua @@ -1,34 +1,40 @@ +local width = 200 + local noisemap = PerlinNoiseMap({ offset = 0.5, scale = 0.5, - spread = {x = 84, y = 84, z = 84}, + spread = {x = width + 10, y = width + 10, z = width + 10}, seed = minetest.get_mapgen_setting("seed") + 99999, octaves = 4, persist = 0.85, -}, {x = 151, y = 30, z = 151}):get_3d_map({x = 0, y = 0, z = 0}) +}, {x = (width*2)+1, y = 30, z = (width * 2) + 1}):get_3d_map({x = 0, y = 0, z = 0}) local c_end_stone = minetest.get_content_id("mcl_end:end_stone") local y_offset = -2 -minetest.register_on_generated(function(minp, maxp) - if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < -75 or minp.x > 75 or maxp.z < -75 or minp.z > 75 then +mcl_mapgen_core.register_generator("end_island", function(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < -width or minp.x > width or maxp.z < -width or minp.z > width then return end - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") - local data = vm:get_data() - local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) - - for idx in area:iter(math.max(minp.x, -75), math.max(minp.y, -27025 + y_offset + 4), math.max(minp.z, -75), math.min(maxp.x, 75), math.min(maxp.y, -27000 + y_offset), math.min(maxp.z, 75)) do + for idx in area:iter(math.max(minp.x, -width), math.max(minp.y, -27025 + y_offset + 4), math.max(minp.z, -width), math.min(maxp.x, width), math.min(maxp.y, -27000 + y_offset), math.min(maxp.z, width)) do local pos = area:position(idx) local y = 27025 + pos.y - y_offset - if noisemap[pos.x + 75 + 1][y + 1][pos.z + 75 + 1] > (math.abs(1 - y / 25) ^ 2 + math.abs(pos.x / 75) ^ 2 + math.abs(pos.z / 75) ^ 2) then + if noisemap[pos.x + width + 1][y + 1][pos.z + width + 1] > (math.abs(1 - y / 25) ^ 2 + math.abs(pos.x / width) ^ 2 + math.abs(pos.z / width) ^ 2) then data[idx] = c_end_stone end end - - vm:set_data(data) - vm:calc_lighting() - vm:update_liquids() - vm:write_to_map() -end) + return true,false,false +end, function(minp,maxp,blockseed) + if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < -width or minp.x > width or maxp.z < -width or minp.z > width then + return + end + local nn = minetest.find_nodes_in_area_under_air(minp,maxp,{"mcl_end:end_stone"}) + local pr = PseudoRandom(blockseed) + table.shuffle(nn) + if nn and #nn > 0 then + for i=1,pr:next(1,math.min(5,#nn)) do + minetest.add_entity(vector.offset(nn[i],0,1,0),"mobs_mc:enderman") + end + end +end, 15, true) diff --git a/mods/MAPGEN/mcl_end_island/mod.conf b/mods/MAPGEN/mcl_end_island/mod.conf index 90432792c..1d39622d6 100644 --- a/mods/MAPGEN/mcl_end_island/mod.conf +++ b/mods/MAPGEN/mcl_end_island/mod.conf @@ -1,4 +1,4 @@ name = mcl_end_island author = Fleckenstein -depends = mcl_mapgen_core, mcl_end +depends = mcl_mapgen_core, mcl_end, mcl_mobs description = Generate the end main island for MCL2 diff --git a/mods/MAPGEN/mcl_mapgen_core/api.lua b/mods/MAPGEN/mcl_mapgen_core/api.lua new file mode 100644 index 000000000..630270444 --- /dev/null +++ b/mods/MAPGEN/mcl_mapgen_core/api.lua @@ -0,0 +1,129 @@ +local registered_generators = {} + +local lvm, nodes, param2 = 0, 0, 0 +local lvm_buffer = {} + +local logging = minetest.settings:get_bool("mcl_logging_mapgen",false) + +local function roundN(n, d) + if type(n) ~= "number" then return n end + local m = 10^d + return math.floor(n * m + 0.5) / m +end + +minetest.register_on_generated(function(minp, maxp, blockseed) + local t1 = os.clock() + local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z} + if lvm > 0 then + local lvm_used, shadow, deco_used, deco_table, ore_used, ore_table = false, false, false, false, false, false + local lb2 = {} -- param2 + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local e1, e2 = {x=emin.x, y=emin.y, z=emin.z}, {x=emax.x, y=emax.y, z=emax.z} + local data2 + local data = vm:get_data(lvm_buffer) + if param2 > 0 then + data2 = vm:get_param2_data(lb2) + end + local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2}) + + for _, rec in ipairs(registered_generators) do + if rec.vf then + local lvm_used0, shadow0, deco, ore = rec.vf(vm, data, data2, e1, e2, area, p1, p2, blockseed) + if lvm_used0 then + lvm_used = true + end + if shadow0 then + shadow = true + end + if deco and type(deco) == "table" then + deco_table = deco + elseif deco then + deco_used = true + end + if ore and type(ore) == "table" then + ore_table = ore + elseif deco then + ore_used = true + end + end + end + + if lvm_used then + -- Write stuff + vm:set_data(data) + if param2 > 0 then + vm:set_param2_data(data2) + end + if deco_table then + minetest.generate_decorations(vm,vector.new(minp.x,deco_table.min,minp.z),vector.new(maxp.x,deco_table.max,maxp.z)) + elseif deco_used then + minetest.generate_decorations(vm) + end + if ore_table then + minetest.generate_ores(vm,vector.new(minp.x,ore_table.min,minp.z),vector.new(maxp.x,ore_table.max,maxp.z)) + elseif ore_used then + minetest.generate_ores(vm) + end + vm:calc_lighting(p1, p2, shadow) + vm:write_to_map() + vm:update_liquids() + end + end + + if nodes > 0 then + for _, rec in ipairs(registered_generators) do + if rec.nf then + rec.nf(p1, p2, blockseed) + end + end + end + + mcl_vars.add_chunk(minp) + if logging then + minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp).."..."..tostring(roundN(((os.clock() - t1)*1000),2)).."ms") + end +end) + +function minetest.register_on_generated(node_function) + mcl_mapgen_core.register_generator("mod_"..minetest.get_current_modname().."_"..tostring(#registered_generators+1), nil, node_function) +end + +function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2) + if not id then return end + + local priority = priority or 5000 + + if lvm_function then lvm = lvm + 1 end + if node_function then nodes = nodes + 1 end + if needs_param2 then param2 = param2 + 1 end + + local new_record = { + id = id, + i = priority, + vf = lvm_function, + nf = node_function, + needs_param2 = needs_param2, + } + + table.insert(registered_generators, new_record) + table.sort(registered_generators, function(a, b) + return (a.i < b.i) or ((a.i == b.i) and a.vf and (b.vf == nil)) + end) +end + +function mcl_mapgen_core.unregister_generator(id) + local index + for i, gen in ipairs(registered_generators) do + if gen.id == id then + index = i + break + end + end + if not index then return end + local rec = registered_generators[index] + table.remove(registered_generators, index) + if rec.vf then lvm = lvm - 1 end + if rec.nf then nodes = nodes - 1 end + if rec.needs_param2 then param2 = param2 - 1 end + --if rec.needs_level0 then level0 = level0 - 1 end +end diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index d9494d18b..03c5aeb13 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -2,8 +2,12 @@ mcl_mapgen_core = {} local registered_generators = {} local lvm, nodes, param2 = 0, 0, 0 +local lvm_used = false local lvm_buffer = {} +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + -- -- Aliases for map generator outputs -- @@ -49,14 +53,12 @@ minetest.register_alias("mapgen_stair_sandstonebrick", "mcl_stairs:stair_sandsto minetest.register_alias("mapgen_stair_sandstone_block", "mcl_stairs:stair_sandstone") minetest.register_alias("mapgen_stair_desert_stone", "mcl_stairs:stair_sandstone") +dofile(modpath.."/api.lua") +dofile(modpath.."/ores.lua") + local mg_name = minetest.get_mapgen_setting("mg_name") local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true" -local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor - --- End exit portal position -local END_EXIT_PORTAL_POS = vector.new(-3, -27003, -3) - -- Content IDs local c_bedrock = minetest.get_content_id("mcl_core:bedrock") local c_obsidian = minetest.get_content_id("mcl_core:obsidian") @@ -87,1041 +89,6 @@ local c_cocoa_3 = minetest.get_content_id("mcl_cocoas:cocoa_3") local c_vine = minetest.get_content_id("mcl_core:vine") local c_air = minetest.CONTENT_AIR --- --- Ore generation --- - --- Diorite, andesite and granite -local specialstones = { "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" } -for s=1, #specialstones do - local node = specialstones[s] - minetest.register_ore({ - ore_type = "blob", - ore = node, - wherein = {"mcl_core:stone"}, - clust_scarcity = 15*15*15, - clust_num_ores = 33, - clust_size = 5, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - noise_params = { - offset = 0, - scale = 1, - spread = {x=250, y=250, z=250}, - seed = 12345, - octaves = 3, - persist = 0.6, - lacunarity = 2, - flags = "defaults", - } - }) - minetest.register_ore({ - ore_type = "blob", - ore = node, - wherein = {"mcl_core:stone"}, - clust_scarcity = 10*10*10, - clust_num_ores = 58, - clust_size = 7, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - noise_params = { - offset = 0, - scale = 1, - spread = {x=250, y=250, z=250}, - seed = 12345, - octaves = 3, - persist = 0.6, - lacunarity = 2, - flags = "defaults", - } - }) -end - -local stonelike = {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"} - --- Dirt -minetest.register_ore({ - ore_type = "blob", - ore = "mcl_core:dirt", - wherein = stonelike, - clust_scarcity = 15*15*15, - clust_num_ores = 33, - clust_size = 4, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - noise_params = { - offset = 0, - scale = 1, - spread = {x=250, y=250, z=250}, - seed = 12345, - octaves = 3, - persist = 0.6, - lacunarity = 2, - flags = "defaults", - } -}) - --- Gravel -minetest.register_ore({ - ore_type = "blob", - ore = "mcl_core:gravel", - wherein = stonelike, - clust_scarcity = 14*14*14, - clust_num_ores = 33, - clust_size = 5, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(111), - noise_params = { - offset = 0, - scale = 1, - spread = {x=250, y=250, z=250}, - seed = 12345, - octaves = 3, - persist = 0.6, - lacunarity = 2, - flags = "defaults", - } -}) - -if minetest.settings:get_bool("mcl_generate_ores", true) then - -- - -- Coal - -- - - -- Common spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 525*3, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 510*3, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 12, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), - }) - - -- Medium-rare spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 550*3, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 525*3, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), - }) - - -- Rare spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 600*3, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 550*3, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), - }) - - -- - -- Iron - -- - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_iron", - wherein = stonelike, - clust_scarcity = 830, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(39), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_iron", - wherein = stonelike, - clust_scarcity = 1660, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(40), - y_max = mcl_worlds.layer_to_y(63), - }) - - -- - -- Gold - -- - - -- Common spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 4775, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(30), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 6560, - clust_num_ores = 7, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(30), - }) - - -- Rare spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 13000, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(31), - y_max = mcl_worlds.layer_to_y(33), - }) - - -- - -- Diamond - -- - - -- Common spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 5000, - clust_num_ores = 2, - clust_size = 2, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), - }) - - -- Rare spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 20000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 20000, - clust_num_ores = 2, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), - }) - - -- - -- Redstone - -- - - -- Common spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 500, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(13), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 800, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(13), - }) - - -- Rare spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 1000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 1600, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), - }) - - -- - -- Emerald - -- - - if mg_name == "v6" then - -- Generate everywhere in v6, but rarely. - - -- Common spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_emerald", - wherein = stonelike, - clust_scarcity = 14340, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(29), - }) - -- Rare spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_emerald", - wherein = stonelike, - clust_scarcity = 21510, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(30), - y_max = mcl_worlds.layer_to_y(32), - }) - end - - -- - -- Lapis Lazuli - -- - - -- Common spawn (in the center) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_worlds.layer_to_y(14), - y_max = mcl_worlds.layer_to_y(16), - }) - - -- Rare spawn (below center) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 12000, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(10), - y_max = mcl_worlds.layer_to_y(13), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 14000, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(6), - y_max = mcl_worlds.layer_to_y(9), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 16000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(2), - y_max = mcl_worlds.layer_to_y(5), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 18000, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(0), - y_max = mcl_worlds.layer_to_y(2), - }) - - -- Rare spawn (above center) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 12000, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(17), - y_max = mcl_worlds.layer_to_y(20), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 14000, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(21), - y_max = mcl_worlds.layer_to_y(24), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 16000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(25), - y_max = mcl_worlds.layer_to_y(28), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 18000, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(29), - y_max = mcl_worlds.layer_to_y(32), - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 32000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(31), - y_max = mcl_worlds.layer_to_y(32), - }) -end - -if not superflat then --- Water and lava springs (single blocks of lava/water source) --- Water appears at nearly every height, but not near the bottom -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:water_source", - wherein = {"mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:dirt"}, - clust_scarcity = 9000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(5), - y_max = mcl_worlds.layer_to_y(128), -}) - --- Lava springs are rather common at -31 and below -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 2000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(1), - y_max = mcl_worlds.layer_to_y(10), -}) - -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 9000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(11), - y_max = mcl_worlds.layer_to_y(31), -}) - --- Lava springs will become gradually rarer with increasing height -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 32000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(32), - y_max = mcl_worlds.layer_to_y(47), -}) - -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 72000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(48), - y_max = mcl_worlds.layer_to_y(61), -}) - --- Lava may even appear above surface, but this is very rare -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 96000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(62), - y_max = mcl_worlds.layer_to_y(127), -}) -end - -local function register_mgv6_decorations() - - -- Cacti - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:sand"}, - sidelen = 16, - noise_params = { - offset = -0.012, - scale = 0.024, - spread = {x = 100, y = 100, z = 100}, - seed = 257, - octaves = 3, - persist = 0.6 - }, - y_min = 4, - y_max = mcl_vars.mg_overworld_max, - decoration = "mcl_core:cactus", - height = 1, - height_max = 3, - }) - - -- Sugar canes - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:dirt", "mcl_core:coarse_dirt", "group:grass_block_no_snow", "group:sand", "mcl_core:podzol", "mcl_core:reeds"}, - sidelen = 16, - noise_params = { - offset = -0.3, - scale = 0.7, - spread = {x = 100, y = 100, z = 100}, - seed = 465, - octaves = 3, - persist = 0.7 - }, - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - decoration = "mcl_core:reeds", - height = 1, - height_max = 3, - spawn_by = { "mcl_core:water_source", "group:frosted_ice" }, - num_spawn_by = 1, - }) - - -- Doubletall grass - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:double_grass", param1 = 255, }, - { name = "mcl_flowers:double_grass_top", param1 = 255, }, - }, - }, - place_on = {"group:grass_block_no_snow"}, - sidelen = 8, - noise_params = { - offset = -0.0025, - scale = 0.03, - spread = {x = 100, y = 100, z = 100}, - seed = 420, - octaves = 3, - persist = 0.0, - }, - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - }) - - -- Large ferns - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:double_fern", param1=255, }, - { name = "mcl_flowers:double_fern_top", param1=255, }, - }, - }, - -- v6 hack: This makes sure large ferns only appear in jungles - spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, - num_spawn_by = 1, - place_on = {"group:grass_block_no_snow"}, - - sidelen = 16, - noise_params = { - offset = 0, - scale = 0.01, - spread = {x = 250, y = 250, z = 250}, - seed = 333, - octaves = 2, - persist = 0.66, - }, - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - }) - - -- Large flowers - local function register_large_flower(name, seed, offset) - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:"..name, param1=255, }, - { name = "mcl_flowers:"..name.."_top", param1=255, }, - }, - }, - place_on = {"group:grass_block_no_snow"}, - - sidelen = 16, - noise_params = { - offset = offset, - scale = 0.01, - spread = {x = 300, y = 300, z = 300}, - seed = seed, - octaves = 5, - persist = 0.62, - }, - y_min = 1, - y_max = mcl_vars.overworld_max, - flags = "", - }) - end - - register_large_flower("rose_bush", 9350, -0.008) - register_large_flower("peony", 10450, -0.008) - register_large_flower("lilac", 10600, -0.007) - register_large_flower("sunflower", 2940, -0.005) - - -- Lily pad - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "mcl_core:water_source", prob = 0 }, - { name = "mcl_core:water_source" }, - { name = "mcl_flowers:waterlily", param1 = 255 }, - }, - }, - place_on = "mcl_core:dirt", - sidelen = 16, - noise_params = { - offset = -0.12, - scale = 0.3, - spread = {x = 200, y = 200, z = 200}, - seed = 503, - octaves = 6, - persist = 0.7, - }, - y_min = 0, - y_max = 0, - rotation = "random", - }) - - -- Pumpkin - minetest.register_decoration({ - deco_type = "simple", - decoration = "mcl_farming:pumpkin", - param2 = 0, - param2_max = 3, - place_on = {"group:grass_block_no_snow"}, - sidelen = 16, - noise_params = { - offset = -0.008, - scale = 0.00666, - spread = {x = 250, y = 250, z = 250}, - seed = 666, - octaves = 6, - persist = 0.666 - }, - y_min = 1, - y_max = mcl_vars.overworld_max, - }) - - -- Melon - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 16, - noise_params = { - offset = 0.002, - scale = 0.006, - spread = {x = 250, y = 250, z = 250}, - seed = 333, - octaves = 3, - persist = 0.6 - }, - -- Small trick to make sure melon spawn in jungles - spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, - num_spawn_by = 1, - y_min = 1, - y_max = 40, - decoration = "mcl_farming:melon", - }) - - -- Tall grass - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 8, - noise_params = { - offset = 0.01, - scale = 0.3, - spread = {x = 100, y = 100, z = 100}, - seed = 420, - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = mcl_vars.overworld_max, - decoration = "mcl_flowers:tallgrass", - }) - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 8, - noise_params = { - offset = 0.04, - scale = 0.03, - spread = {x = 100, y = 100, z = 100}, - seed = 420, - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = mcl_vars.overworld_max, - decoration = "mcl_flowers:tallgrass", - }) - - -- Seagrass and kelp - local materials = {"dirt","sand"} - for i=1, #materials do - local mat = materials[i] - - minetest.register_decoration({ - deco_type = "simple", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:"..mat}, - sidelen = 8, - noise_params = { - offset = 0.04, - scale = 0.3, - spread = {x = 100, y = 100, z = 100}, - seed = 421, - octaves = 3, - persist = 0.6 - }, - flags = "force_placement", - place_offset_y = -1, - y_min = mcl_vars.overworld_min, - y_max = 0, - decoration = "mcl_ocean:seagrass_"..mat, - }) - minetest.register_decoration({ - deco_type = "simple", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:mat"}, - sidelen = 8, - noise_params = { - offset = 0.08, - scale = 0.03, - spread = {x = 100, y = 100, z = 100}, - seed = 421, - octaves = 3, - persist = 0.6 - }, - flags = "force_placement", - place_offset_y = -1, - y_min = mcl_vars.overworld_min, - y_max = -5, - decoration = "mcl_ocean:seagrass_"..mat, - }) - - minetest.register_decoration({ - deco_type = "simple", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:"..mat}, - sidelen = 16, - noise_params = { - offset = 0.01, - scale = 0.01, - spread = {x = 300, y = 300, z = 300}, - seed = 505, - octaves = 5, - persist = 0.62, - }, - flags = "force_placement", - place_offset_y = -1, - y_min = mcl_vars.overworld_min, - y_max = -6, - decoration = "mcl_ocean:kelp_"..mat, - param2 = 16, - param2_max = 96, - }) - minetest.register_decoration({ - deco_type = "simple", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:"..mat}, - sidelen = 16, - noise_params = { - offset = 0.01, - scale = 0.01, - spread = {x = 100, y = 100, z = 100}, - seed = 506, - octaves = 5, - persist = 0.62, - }, - flags = "force_placement", - place_offset_y = -1, - y_min = mcl_vars.overworld_min, - y_max = -15, - decoration = "mcl_ocean:kelp_"..mat, - param2 = 32, - param2_max = 160, - }) - - end - - -- Wet Sponge - -- TODO: Remove this when we got ocean monuments - minetest.register_decoration({ - deco_type = "simple", - decoration = "mcl_sponges:sponge_wet", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:dirt","mcl_core:sand"}, - sidelen = 16, - noise_params = { - offset = 0.00295, - scale = 0.006, - spread = {x = 250, y = 250, z = 250}, - seed = 999, - octaves = 3, - persist = 0.666 - }, - flags = "force_placement", - y_min = mcl_vars.mg_lava_overworld_max + 5, - y_max = -20, - }) - - -- Add a small amount of tall grass everywhere to avoid areas completely empty devoid of tall grass - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 8, - fill_ratio = 0.004, - y_min = 1, - y_max = mcl_vars.overworld_max, - decoration = "mcl_flowers:tallgrass", - }) - - local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"} - local mseeds = { 7133, 8244 } - for m=1, #mushrooms do - -- Mushrooms next to trees - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:mycelium", "mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite"}, - sidelen = 16, - noise_params = { - offset = 0.04, - scale = 0.04, - spread = {x = 100, y = 100, z = 100}, - seed = mseeds[m], - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - decoration = mushrooms[m], - spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", }, - num_spawn_by = 1, - }) - end - - -- Dead bushes - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"}, - sidelen = 16, - noise_params = { - offset = 0, - scale = 0.035, - spread = {x = 100, y = 100, z = 100}, - seed = 1972, - octaves = 3, - persist = 0.6 - }, - y_min = 4, - y_max = mcl_vars.mg_overworld_max, - decoration = "mcl_core:deadbush", - }) - - local function register_mgv6_flower(name, seed, offset, y_max) - if offset == nil then - offset = 0 - end - if y_max == nil then - y_max = mcl_vars.mg_overworld_max - end - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 16, - noise_params = { - offset = offset, - scale = 0.006, - spread = {x = 100, y = 100, z = 100}, - seed = seed, - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = y_max, - decoration = "mcl_flowers:"..name, - }) - end - - register_mgv6_flower("tulip_red", 436) - register_mgv6_flower("tulip_orange", 536) - register_mgv6_flower("tulip_pink", 636) - register_mgv6_flower("tulip_white", 736) - register_mgv6_flower("azure_bluet", 800) - register_mgv6_flower("dandelion", 8) - -- Allium is supposed to only appear in flower forest in MC. There are no flower forests in v6. - -- We compensate by making it slightly rarer in v6. - register_mgv6_flower("allium", 0, -0.001) - --[[ Blue orchid is supposed to appear in swamplands. There are no swamplands in v6. - We emulate swamplands by limiting the height to 5 levels above sea level, - which should be close to the water. ]] - register_mgv6_flower("blue_orchid", 64500, nil, mcl_worlds.layer_to_y(67)) - register_mgv6_flower("oxeye_daisy", 3490) - register_mgv6_flower("poppy", 9439) - - -- Put top snow on snowy grass blocks. The v6 mapgen does not generate the top snow on its own. - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_snow"}, - sidelen = 16, - fill_ratio = 11.0, -- complete coverage - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - decoration = "mcl_core:snow", - }) - -end - local mg_flags = minetest.settings:get_flags("mg_flags") -- Inform other mods of dungeon setting for MCL2-style dungeons @@ -1130,16 +97,32 @@ mcl_vars.mg_dungeons = mg_flags.dungeons and not superflat -- Disable builtin dungeons, we provide our own dungeons mg_flags.dungeons = false --- Apply mapgen-specific mapgen code -if mg_name == "v6" then - register_mgv6_decorations() -elseif superflat then +if superflat then -- Enforce superflat-like mapgen: no caves, decor, lakes and hills mg_flags.caves = false mg_flags.decorations = false minetest.set_mapgen_setting("mgflat_spflags", "nolakes,nohills", true) end +if mg_name == "v7" then + minetest.set_mapgen_setting("mgv7_cavern_threshold", "0.20", true) + mg_flags.caverns = true +elseif mg_name == "valleys" then + minetest.set_mapgen_setting("mgvalleys_cavern_threshold", "0.20", true) + mg_flags.caverns = true +elseif mg_name == "carpathian" then + minetest.set_mapgen_setting("mgcarpathian_cavern_threshold", "0.20", true) + mg_flags.caverns = true +elseif mg_name == "v5" then + minetest.set_mapgen_setting("mgv5_cavern_threshold", "0.20", true) + mg_flags.caverns = true +elseif mg_name == "fractal" then + minetest.set_mapgen_setting("mgfractal_cavern_threshold", "0.20", true) + mg_flags.caverns = true +end + + + local mg_flags_str = "" for k,v in pairs(mg_flags) do if v == false then @@ -1152,6 +135,37 @@ if string.len(mg_flags_str) > 0 then end minetest.set_mapgen_setting("mg_flags", mg_flags_str, true) +local function between(x, y, z) -- x is between y and z (inclusive) + return y <= x and x <= z +end + +local function in_cube(tpos,wpos1,wpos2) + local xmax=wpos2.x + local xmin=wpos1.x + + local ymax=wpos2.y + local ymin=wpos1.y + + local zmax=wpos2.z + local zmin=wpos1.z + if wpos1.x > wpos2.x then + xmax=wpos1.x + xmin=wpos2.x + end + if wpos1.y > wpos2.y then + ymax=wpos1.y + ymin=wpos2.y + end + if wpos1.z > wpos2.z then + zmax=wpos1.z + zmin=wpos2.z + end + if between(tpos.x,xmin,xmax) and between(tpos.y,ymin,ymax) and between(tpos.z,zmin,zmax) then + return true + end + return false +end + -- Helper function for converting a MC probability to MT, with -- regards to MapBlocks. -- Some MC generated structures are generated on per-chunk @@ -1166,18 +180,6 @@ local function minecraft_chunk_probability(x, minp, maxp) return x * (((maxp.x-minp.x+1)*(maxp.z-minp.z+1)) / 256) end --- Takes an index of a biomemap table (from minetest.get_mapgen_object), --- minp and maxp (from an on_generated callback) and returns the real world coordinates --- as X, Z. --- Inverse function of xz_to_biomemap ---[[local function biomemap_to_xz(index, minp, maxp) - local xwidth = maxp.x - minp.x + 1 - local zwidth = maxp.z - minp.z + 1 - local x = ((index-1) % xwidth) + minp.x - local z = ((index-1) / zwidth) + minp.z - return x, z -end]] - -- Takes x and z coordinates and minp and maxp of a generated chunk -- (in on_generated callback) and returns a biomemap index) -- Inverse function of biomemap_to_xz @@ -1190,721 +192,6 @@ local function xz_to_biomemap_index(x, z, minp, maxp) return (minix + miniz * zwidth) + 1 end --- Perlin noise objects -local perlin_structures -local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density -local perlin_clay - -local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_area, lvm_used) - -- TODO: Make clay generation reproducible for same seed. - if maxp.y < -5 or minp.y > 0 then - return lvm_used - end - - local pr = PseudoRandom(blockseed) - - perlin_clay = perlin_clay or minetest.get_perlin({ - offset = 0.5, - scale = 0.2, - spread = {x = 5, y = 5, z = 5}, - seed = -316, - octaves = 1, - persist = 0.0 - }) - - for y=math.max(minp.y, 0), math.min(maxp.y, -8), -1 do - -- Assume X and Z lengths are equal - local divlen = 4 - local divs = (maxp.x-minp.x)/divlen+1; - for divx=0+1,divs-2 do - for divz=0+1,divs-2 do - -- Get position and shift it a bit randomly so the clay do not obviously appear in a grid - local cx = minp.x + math.floor((divx+0.5)*divlen) + pr:next(-1,1) - local cz = minp.z + math.floor((divz+0.5)*divlen) + pr:next(-1,1) - - local water_pos = voxelmanip_area:index(cx, y+1, cz) - local waternode = voxelmanip_data[water_pos] - local surface_pos = voxelmanip_area:index(cx, y, cz) - local surfacenode = voxelmanip_data[surface_pos] - - local genrnd = pr:next(1, 20) - if genrnd == 1 and perlin_clay:get_3d({x=cx,y=y,z=cz}) > 0 and waternode == c_water and - (surfacenode == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(surfacenode), "sand") == 1) then - local diamondsize = pr:next(1, 3) - for x1 = -diamondsize, diamondsize do - for z1 = -(diamondsize - math.abs(x1)), diamondsize - math.abs(x1) do - local ccpos = voxelmanip_area:index(cx+x1, y, cz+z1) - local claycandidate = voxelmanip_data[ccpos] - if voxelmanip_data[ccpos] == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(claycandidate), "sand") == 1 then - voxelmanip_data[ccpos] = c_clay - lvm_used = true - end - end - end - end - end - end - end - return lvm_used -end - -local function generate_end_exit_portal(pos) - local obj = minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon") - if obj then - local dragon_entity = obj:get_luaentity() - dragon_entity._initial = true - dragon_entity._portal_pos = pos - else - minetest.log("error", "[mcl_mapgen_core] ERROR! Ender dragon doesn't want to spawn") - end - mcl_structures.call_struct(pos, "end_exit_portal") -end - --- TODO: Try to use more efficient structure generating code -local function generate_structures(minp, maxp, blockseed, biomemap) - local chunk_has_desert_well = false - local chunk_has_desert_temple = false - local chunk_has_igloo = false - local struct_min, struct_max = -3, 111 --64 - - if maxp.y >= struct_min and minp.y <= struct_max then - -- Generate structures - local pr = PcgRandom(blockseed) - perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100) - -- Assume X and Z lengths are equal - local divlen = 5 - for x0 = minp.x, maxp.x, divlen do for z0 = minp.z, maxp.z, divlen do - -- Determine amount from perlin noise - local amount = math.floor(perlin_structures:get_2d({x=x0, y=z0}) * 9) - -- Find random positions based on this random - local p, ground_y - for i=0, amount do - p = {x = pr:next(x0, x0+divlen-1), y = 0, z = pr:next(z0, z0+divlen-1)} - -- Find ground level - ground_y = nil - local nn - for y = struct_max, struct_min, -1 do - p.y = y - local checknode = minetest.get_node(p) - if checknode then - nn = checknode.name - local def = minetest.registered_nodes[nn] - if def and def.walkable then - ground_y = y - break - end - end - end - - if ground_y then - p.y = ground_y+1 - local nn0 = minetest.get_node(p).name - -- Check if the node can be replaced - if minetest.registered_nodes[nn0] and minetest.registered_nodes[nn0].buildable_to then - -- Desert temples and desert wells - if nn == "mcl_core:sand" or (nn == "mcl_core:sandstone") then - if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then - -- Spawn desert temple - -- TODO: Check surface - if pr:next(1,12000) == 1 then - mcl_structures.call_struct(p, "desert_temple", nil, pr) - chunk_has_desert_temple = true - end - end - if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then - local desert_well_prob = minecraft_chunk_probability(1000, minp, maxp) - - -- Spawn desert well - if pr:next(1, desert_well_prob) == 1 then - -- Check surface - local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, {x=p.x+5, y=p.y-1, z=p.z+5}, "mcl_core:sand") - if #surface >= 25 then - mcl_structures.call_struct(p, "desert_well", nil, pr) - chunk_has_desert_well = true - end - end - end - - -- Igloos - elseif not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or (minetest.get_item_group(nn, "grass_block_snow") == 1)) then - if pr:next(1, 4400) == 1 then - -- Check surface - local floor = {x=p.x+9, y=p.y-1, z=p.z+9} - local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:snowblock") - local surface2 = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:dirt_with_grass_snow") - if #surface + #surface2 >= 63 then - mcl_structures.call_struct(p, "igloo", nil, pr) - chunk_has_igloo = true - end - end - end - - -- Fossil - if nn == "mcl_core:sandstone" or nn == "mcl_core:sand" and not chunk_has_desert_temple and ground_y > 3 then - local fossil_prob = minecraft_chunk_probability(64, minp, maxp) - - if pr:next(1, fossil_prob) == 1 then - -- Spawn fossil below desert surface between layers 40 and 49 - local p1 = {x=p.x, y=pr:next(mcl_worlds.layer_to_y(40), mcl_worlds.layer_to_y(49)), z=p.z} - -- Very rough check of the environment (we expect to have enough stonelike nodes). - -- Fossils may still appear partially exposed in caves, but this is O.K. - local p2 = vector.add(p1, 4) - local nodes = minetest.find_nodes_in_area(p1, p2, {"mcl_core:sandstone", "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:dirt", "mcl_core:gravel"}) - - if #nodes >= 100 then -- >= 80% - mcl_structures.call_struct(p1, "fossil", nil, pr) - end - end - end - - -- Witch hut - if ground_y <= 0 and nn == "mcl_core:dirt" then - local prob = minecraft_chunk_probability(48, minp, maxp) - if pr:next(1, prob) == 1 then - - local swampland = minetest.get_biome_id("Swampland") - local swampland_shore = minetest.get_biome_id("Swampland_shore") - - -- Where do witches live? - - local here_be_witches = false - if mg_name == "v6" then - -- v6: In Normal biome - if biomeinfo.get_v6_biome(p) == "Normal" then - here_be_witches = true - end - else - -- Other mapgens: In swampland biome - local bi = xz_to_biomemap_index(p.x, p.z, minp, maxp) - if biomemap[bi] == swampland or biomemap[bi] == swampland_shore then - here_be_witches = true - end - end - - if here_be_witches then - local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270" - local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1} - local size - if r == "0" or r == "180" then - size = {x=10, y=4, z=8} - else - size = {x=8, y=4, z=10} - end - local p2 = vector.add(p1, size) - - -- This checks free space at the “body” of the hut and a bit around. - -- ALL nodes must be free for the placement to succeed. - local free_nodes = minetest.find_nodes_in_area(p1, p2, {"air", "mcl_core:water_source", "mcl_flowers:waterlily"}) - if #free_nodes >= ((size.x+1)*(size.y+1)*(size.z+1)) then - local place = {x=p.x, y=WITCH_HUT_HEIGHT-1, z=p.z} - - -- FIXME: For some mysterious reason (black magic?) this - -- function does sometimes NOT spawn the witch hut. One can only see the - -- oak wood nodes in the water, but no hut. :-/ - mcl_structures.call_struct(place, "witch_hut", r, pr) - - -- TODO: Spawn witch in or around hut when the mob sucks less. - - local function place_tree_if_free(pos, prev_result) - local nn = minetest.get_node(pos).name - if nn == "mcl_flowers:waterlily" or nn == "mcl_core:water_source" or nn == "mcl_core:water_flowing" or nn == "air" then - minetest.set_node(pos, {name="mcl_core:tree", param2=0}) - return prev_result - else - return false - end - end - local offsets - if r == "0" then - offsets = { - {x=1, y=0, z=1}, - {x=1, y=0, z=5}, - {x=6, y=0, z=1}, - {x=6, y=0, z=5}, - } - elseif r == "180" then - offsets = { - {x=2, y=0, z=1}, - {x=2, y=0, z=5}, - {x=7, y=0, z=1}, - {x=7, y=0, z=5}, - } - elseif r == "270" then - offsets = { - {x=1, y=0, z=1}, - {x=5, y=0, z=1}, - {x=1, y=0, z=6}, - {x=5, y=0, z=6}, - } - elseif r == "90" then - offsets = { - {x=1, y=0, z=2}, - {x=5, y=0, z=2}, - {x=1, y=0, z=7}, - {x=5, y=0, z=7}, - } - end - for o=1, #offsets do - local ok = true - for y=place.y-1, place.y-64, -1 do - local tpos = vector.add(place, offsets[o]) - tpos.y = y - ok = place_tree_if_free(tpos, ok) - if not ok then - break - end - end - end - end - end - end - end - - -- Ice spikes in v6 - -- In other mapgens, ice spikes are generated as decorations. - if mg_name == "v6" and not chunk_has_igloo and nn == "mcl_core:snowblock" then - local spike = pr:next(1,58000) - if spike < 3 then - -- Check surface - local floor = {x=p.x+4, y=p.y-1, z=p.z+4} - local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock"}) - -- Check for collision with spruce - local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) - - if #surface >= 9 and #spruce_collisions == 0 then - mcl_structures.call_struct(p, "ice_spike_large", nil, pr) - end - elseif spike < 100 then - -- Check surface - local floor = {x=p.x+6, y=p.y-1, z=p.z+6} - local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock", "mcl_core:dirt_with_grass_snow"}) - - -- Check for collision with spruce - local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) - - if #surface >= 25 and #spruce_collisions == 0 then - mcl_structures.call_struct(p, "ice_spike_small", nil, pr) - end - end - end - end - end - - end - end end - -- End exit portal - elseif minp.y <= END_EXIT_PORTAL_POS.y and maxp.y >= END_EXIT_PORTAL_POS.y and - minp.x <= END_EXIT_PORTAL_POS.x and maxp.x >= END_EXIT_PORTAL_POS.x and - minp.z <= END_EXIT_PORTAL_POS.z and maxp.z >= END_EXIT_PORTAL_POS.z then - for y=maxp.y, minp.y, -1 do - local p = {x=END_EXIT_PORTAL_POS.x, y=y, z=END_EXIT_PORTAL_POS.z} - if minetest.get_node(p).name == "mcl_end:end_stone" then - generate_end_exit_portal(p) - return - end - end - generate_end_exit_portal(END_EXIT_PORTAL_POS) - end -end - --- Buffers for LuaVoxelManip --- local lvm_buffer = {} --- local lvm_buffer_param2 = {} - --- Generate tree decorations in the bounding box. This adds: --- * Cocoa at jungle trees --- * Jungle tree vines --- * Oak vines in swamplands -local function generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used, pr) - if maxp.y < 0 then - return lvm_used - end - - local oaktree, oakleaves, jungletree, jungleleaves = {}, {}, {}, {} - local swampland = minetest.get_biome_id("Swampland") - local swampland_shore = minetest.get_biome_id("Swampland_shore") - local jungle = minetest.get_biome_id("Jungle") - local jungle_shore = minetest.get_biome_id("Jungle_shore") - local jungle_m = minetest.get_biome_id("JungleM") - local jungle_m_shore = minetest.get_biome_id("JungleM_shore") - local jungle_edge = minetest.get_biome_id("JungleEdge") - local jungle_edge_shore = minetest.get_biome_id("JungleEdge_shore") - local jungle_edge_m = minetest.get_biome_id("JungleEdgeM") - local jungle_edge_m_shore = minetest.get_biome_id("JungleEdgeM_shore") - - -- Modifier for Jungle M biome: More vines and cocoas - local dense_vegetation = false - - if biomemap then - -- Biome map available: Check if the required biome (jungle or swampland) - -- is in this mapchunk. We are only interested in trees in the correct biome. - -- The nodes are added if the correct biome is *anywhere* in the mapchunk. - -- TODO: Strictly generate vines in the correct biomes only. - local swamp_biome_found, jungle_biome_found = false, false - for b=1, #biomemap do - local id = biomemap[b] - - if not swamp_biome_found and (id == swampland or id == swampland_shore) then - oaktree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:tree"}) - oakleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:leaves"}) - swamp_biome_found = true - end - if not jungle_biome_found and (id == jungle or id == jungle_shore or id == jungle_m or id == jungle_m_shore or id == jungle_edge or id == jungle_edge_shore or id == jungle_edge_m or id == jungle_edge_m_shore) then - jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"}) - jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"}) - jungle_biome_found = true - end - if not dense_vegetation and (id == jungle_m or id == jungle_m_shore) then - dense_vegetation = true - end - if swamp_biome_found and jungle_biome_found and dense_vegetation then - break - end - end - else - -- If there is no biome map, we just count all jungle things we can find. - -- Oak vines will not be generated. - jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"}) - jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"}) - end - - local pos, treepos, dir - - local cocoachance = 40 - if dense_vegetation then - cocoachance = 32 - end - - -- Pass 1: Generate cocoas at jungle trees - for n = 1, #jungletree do - - pos = table.copy(jungletree[n]) - treepos = table.copy(pos) - - if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then - - dir = pr:next(1, cocoachance) - - if dir == 1 then - pos.z = pos.z + 1 - elseif dir == 2 then - pos.z = pos.z - 1 - elseif dir == 3 then - pos.x = pos.x + 1 - elseif dir == 4 then - pos.x = pos.x -1 - end - - local p_pos = area:index(pos.x, pos.y, pos.z) - local l = minetest.get_node_light(pos) - - if dir < 5 - and data[p_pos] == c_air - and l and l > 12 then - local c = pr:next(1, 3) - if c == 1 then - data[p_pos] = c_cocoa_1 - elseif c == 2 then - data[p_pos] = c_cocoa_2 - else - data[p_pos] = c_cocoa_3 - end - param2_data[p_pos] = minetest.dir_to_facedir(vector.subtract(treepos, pos)) - lvm_used = true - end - - end - end - - -- Pass 2: Generate vines at jungle wood, jungle leaves in jungle and oak wood, oak leaves in swampland - perlin_vines = perlin_vines or minetest.get_perlin(555, 4, 0.6, 500) - perlin_vines_fine = perlin_vines_fine or minetest.get_perlin(43000, 3, 0.6, 1) - perlin_vines_length = perlin_vines_length or minetest.get_perlin(435, 4, 0.6, 75) - perlin_vines_upwards = perlin_vines_upwards or minetest.get_perlin(436, 3, 0.6, 10) - perlin_vines_density = perlin_vines_density or minetest.get_perlin(436, 3, 0.6, 500) - - -- Extra long vines in Jungle M - local maxvinelength = 7 - if dense_vegetation then - maxvinelength = 14 - end - local treething - for i=1, 4 do - if i==1 then - treething = jungletree - elseif i == 2 then - treething = jungleleaves - elseif i == 3 then - treething = oaktree - elseif i == 4 then - treething = oakleaves - end - - for n = 1, #treething do - pos = treething[n] - - treepos = table.copy(pos) - - local dirs = { - {x=1,y=0,z=0}, - {x=-1,y=0,z=0}, - {x=0,y=0,z=1}, - {x=0,y=0,z=-1}, - } - - for d = 1, #dirs do - local pos = vector.add(pos, dirs[d]) - local p_pos = area:index(pos.x, pos.y, pos.z) - - local vine_threshold = math.max(0.33333, perlin_vines_density:get_2d(pos)) - if dense_vegetation then - vine_threshold = vine_threshold * (2/3) - end - - if perlin_vines:get_2d(pos) > -1.0 and perlin_vines_fine:get_3d(pos) > vine_threshold and data[p_pos] == c_air then - - local rdir = {} - rdir.x = -dirs[d].x - rdir.y = dirs[d].y - rdir.z = -dirs[d].z - local param2 = minetest.dir_to_wallmounted(rdir) - - -- Determine growth direction - local grow_upwards = false - -- Only possible on the wood, not on the leaves - if i == 1 then - grow_upwards = perlin_vines_upwards:get_3d(pos) > 0.8 - end - if grow_upwards then - -- Grow vines up 1-4 nodes, even through jungleleaves. - -- This may give climbing access all the way to the top of the tree :-) - -- But this will be fairly rare. - local length = math.ceil(math.abs(perlin_vines_length:get_3d(pos)) * 4) - for l=0, length-1 do - local t_pos = area:index(treepos.x, treepos.y, treepos.z) - - if (data[p_pos] == c_air or data[p_pos] == c_jungleleaves or data[p_pos] == c_leaves) and mcl_core.supports_vines(minetest.get_name_from_content_id(data[t_pos])) then - data[p_pos] = c_vine - param2_data[p_pos] = param2 - lvm_used = true - - else - break - end - pos.y = pos.y + 1 - p_pos = area:index(pos.x, pos.y, pos.z) - treepos.y = treepos.y + 1 - end - else - -- Grow vines down, length between 1 and maxvinelength - local length = math.ceil(math.abs(perlin_vines_length:get_3d(pos)) * maxvinelength) - for l=0, length-1 do - if data[p_pos] == c_air then - data[p_pos] = c_vine - param2_data[p_pos] = param2 - lvm_used = true - - else - break - end - pos.y = pos.y - 1 - p_pos = area:index(pos.x, pos.y, pos.z) - end - end - end - end - - end - end - return lvm_used -end - --- Generate mushrooms in caves manually. --- Minetest's API does not support decorations in caves yet. :-( -local function generate_underground_mushrooms(minp, maxp, seed) - local pr_shroom = PseudoRandom(seed-24359) - -- Generate rare underground mushrooms - -- TODO: Make them appear in groups, use Perlin noise - local min, max = mcl_vars.mg_lava_overworld_max + 4, 0 - if minp.y > max or maxp.y < min then - return - end - - local bpos - local stone = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_core:stone", "mcl_core:dirt", "mcl_core:mycelium", "mcl_core:podzol", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:stone_with_iron", "mcl_core:stone_with_gold"}) - - for n = 1, #stone do - bpos = {x = stone[n].x, y = stone[n].y + 1, z = stone[n].z } - - local l = minetest.get_node_light(bpos, 0.5) - if bpos.y >= min and bpos.y <= max and l and l <= 12 and pr_shroom:next(1,1000) < 4 then - if pr_shroom:next(1,2) == 1 then - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) - else - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) - end - end - end -end - -local nether_wart_chance -if mg_name == "v6" then - nether_wart_chance = 85 -else - nether_wart_chance = 170 -end --- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart --- Minetest's API does not support decorations in caves yet. :-( -local function generate_nether_decorations(minp, maxp, seed) - local pr_nether = PseudoRandom(seed+667) - - if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then - return - end - - minetest.log("action", "[mcl_mapgen_core] Nether decorations " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp)) - - -- TODO: Generate everything based on Perlin noise instead of PseudoRandom - - local bpos - local rack = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:netherrack"}) - local magma = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:magma"}) - local ssand = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:soul_sand"}) - - -- Helper function to spawn “fake” decoration - local function special_deco(nodes, spawn_func) - for n = 1, #nodes do - bpos = {x = nodes[n].x, y = nodes[n].y + 1, z = nodes[n].z } - - spawn_func(bpos) - end - - end - - -- Eternal fire on netherrack - special_deco(rack, function(bpos) - -- Eternal fire on netherrack - if pr_nether:next(1,100) <= 3 then - minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"}) - end - end) - - -- Eternal fire on magma cubes - special_deco(magma, function(bpos) - if pr_nether:next(1,150) == 1 then - minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"}) - end - end) - - -- Mushrooms on netherrack - -- Note: Spawned *after* the fire because of light level checks - special_deco(rack, function(bpos) - local l = minetest.get_node_light(bpos, 0.5) - if bpos.y > mcl_vars.mg_lava_nether_max + 6 and l and l <= 12 and pr_nether:next(1,1000) <= 4 then - -- TODO: Make mushrooms appear in groups, use Perlin noise - if pr_nether:next(1,2) == 1 then - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) - else - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) - end - end - end) - - -- Nether wart on soul sand - -- TODO: Spawn in Nether fortresses - special_deco(ssand, function(bpos) - if pr_nether:next(1, nether_wart_chance) == 1 then - minetest.set_node(bpos, {name = "mcl_nether:nether_wart"}) - end - end) - -end - -minetest.register_on_generated(function(minp, maxp, blockseed) - minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp)) - local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z} - if lvm > 0 then - local lvm_used, shadow = false, false - local lb2 = {} -- param2 - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") - local e1, e2 = {x=emin.x, y=emin.y, z=emin.z}, {x=emax.x, y=emax.y, z=emax.z} - local data2 - local data = vm:get_data(lvm_buffer) - if param2 > 0 then - data2 = vm:get_param2_data(lb2) - end - local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2}) - - for _, rec in pairs(registered_generators) do - if rec.vf then - local lvm_used0, shadow0 = rec.vf(vm, data, data2, e1, e2, area, p1, p2, blockseed) - if lvm_used0 then - lvm_used = true - end - if shadow0 then - shadow = true - end - end - end - - if lvm_used then - -- Write stuff - vm:set_data(data) - if param2 > 0 then - vm:set_param2_data(data2) - end - vm:calc_lighting(p1, p2, shadow) - vm:write_to_map() - vm:update_liquids() - end - end - - if nodes > 0 then - for _, rec in pairs(registered_generators) do - if rec.nf then - rec.nf(p1, p2, blockseed) - end - end - end - - mcl_vars.add_chunk(minp) -end) - -function minetest.register_on_generated(node_function) - mcl_mapgen_core.register_generator("mod_"..tostring(#registered_generators+1), nil, node_function) -end - -function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2) - if not id then return end - - local priority = priority or 5000 - - if lvm_function then lvm = lvm + 1 end - if lvm_function then nodes = nodes + 1 end - if needs_param2 then param2 = param2 + 1 end - - local new_record = { - i = priority, - vf = lvm_function, - nf = node_function, - needs_param2 = needs_param2, - } - - 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 and (b.vf == nil)) - end) -end - -function mcl_mapgen_core.unregister_generator(id) - if not registered_generators[id] then return end - local rec = registered_generators[id] - registered_generators[id] = nil - if rec.vf then lvm = lvm - 1 end - if rec.nf then nodes = nodes - 1 end - if rec.needs_param2 then param2 = param2 - 1 end - --if rec.needs_level0 then level0 = level0 - 1 end -end -- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc. -- Also perform some basic node replacements. @@ -1981,8 +268,29 @@ local function set_layers(data, area, content_id, check, min, max, minp, maxp, l return lvm_used end +local function set_palette(minp,maxp,data2,area,biomemap,nodes) + -- Flat area at y=0 to read biome 3 times faster than 5.3.0.get_biome_data(pos).biome: 43us vs 125us per iteration: + if not biomemap then return end + local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) + local nodes = minetest.find_nodes_in_area(minp, maxp, nodes) + for n=1, #nodes do + local n = nodes[n] + local p_pos = area:index(n.x, n.y, n.z) + local b_pos = aream:index(n.x, 0, n.z) + local bn = minetest.get_biome_name(biomemap[b_pos]) + if bn then + local biome = minetest.registered_biomes[bn] + if biome and biome._mcl_biome_type then + data2[p_pos] = biome._mcl_palette_index + lvm_used = true + end + end + end + return lvm_used +end + -- Below the bedrock, generate air/void -local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) +local function world_structure(vm, data, data2, emin, emax, area, minp, maxp, blockseed) local biomemap --ymin, ymax local lvm_used = false local pr = PseudoRandom(blockseed) @@ -2023,188 +331,89 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) lvm_used = set_layers(data, area, c_lava, c_air, mcl_vars.mg_overworld_min, mcl_vars.mg_lava_overworld_max, minp, maxp, lvm_used, pr) lvm_used = set_layers(data, area, c_nether_lava, c_air, mcl_vars.mg_nether_min, mcl_vars.mg_lava_nether_max, minp, maxp, lvm_used, pr) end + end + local deco = false + local ores = false + if minp.y > mcl_vars.mg_nether_deco_max - 64 and maxp.y < mcl_vars.mg_nether_max + 128 then + deco = {min=mcl_vars.mg_nether_deco_max,max=mcl_vars.mg_nether_max} + end + if minp.y < mcl_vars.mg_nether_min + 10 or maxp.y < mcl_vars.mg_nether_min + 60 then + deco = {min=mcl_vars.mg_nether_min - 10,max=mcl_vars.mg_nether_min + 20} + ores = {min=mcl_vars.mg_nether_min - 10,max=mcl_vars.mg_nether_min + 20} + end + return lvm_used, lvm_used, deco, ores +end - -- Clay, vines, cocoas - lvm_used = generate_clay(minp, maxp, blockseed, data, area, lvm_used) - - biomemap = minetest.get_mapgen_object("biomemap") - lvm_used = generate_tree_decorations(minp, maxp, blockseed, data, data2, area, biomemap, lvm_used, pr) - - ----- Interactive block fixing section ----- - ----- The section to perform basic block overrides of the core mapgen generated world. ----- - - -- Snow and sand fixes. This code implements snow consistency - -- and fixes floating sand and cut plants. - -- A snowy grass block must be below a top snow or snow block at all times. - if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then - -- v6 mapgen: - if mg_name == "v6" then - - --[[ Remove broken double plants caused by v6 weirdness. - v6 might break the bottom part of double plants because of how it works. - There are 3 possibilities: - 1) Jungle: Top part is placed on top of a jungle tree or fern (=v6 jungle grass). - This is because the schematic might be placed even if some nodes of it - could not be placed because the destination was already occupied. - TODO: A better fix for this would be if schematics could abort placement - altogether if ANY of their nodes could not be placed. - 2) Cavegen: Removes the bottom part, the upper part floats - 3) Mudflow: Same as 2) ]] - local plants = minetest.find_nodes_in_area(minp, maxp, "group:double_plant") - for n = 1, #plants do - local node = vm:get_node_at(plants[n]) - local is_top = minetest.get_item_group(node.name, "double_plant") == 2 - if is_top then - local p_pos = area:index(plants[n].x, plants[n].y-1, plants[n].z) - if p_pos then - node = vm:get_node_at({x=plants[n].x, y=plants[n].y-1, z=plants[n].z}) - local is_bottom = minetest.get_item_group(node.name, "double_plant") == 1 - if not is_bottom then - p_pos = area:index(plants[n].x, plants[n].y, plants[n].z) - data[p_pos] = c_air - lvm_used = true - end - end - end - end +local function block_fixes(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + local biomemap = minetest.get_mapgen_object("biomemap") + local lvm_used = false + local pr = PseudoRandom(blockseed) + if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then + -- Set param2 (=color) of sugar cane and grass + lvm_used = set_palette(minp,maxp,data2,area,biomemap,{"mcl_core:reeds","mcl_core:dirt_with_grass"}) + end + return lvm_used +end - -- Non-v6 mapgens: - else - -- Set param2 (=color) of grass blocks. - -- Clear snowy grass blocks without snow above to ensure consistency. - local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow"}) - - -- Flat area at y=0 to read biome 3 times faster than 5.3.0.get_biome_data(pos).biome: 43us vs 125us per iteration: - local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) - for n=1, #nodes do - local n = nodes[n] - local p_pos = area:index(n.x, n.y, n.z) - local p_pos_above = area:index(n.x, n.y+1, n.z) - --local p_pos_below = area:index(n.x, n.y-1, 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 - if data[p_pos] == c_dirt_with_grass_snow and p_pos_above and data[p_pos_above] ~= c_top_snow and data[p_pos_above] ~= c_snow_block then - data[p_pos] = c_dirt_with_grass - lvm_used = true - end - end - - -- 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: - -- * Replace water with Nether lava. - -- * Replace stone, sand dirt in v6 so the Nether works in v6. - elseif emin.y <= mcl_vars.mg_nether_max and emax.y >= mcl_vars.mg_nether_min then - if mg_name == "v6" then - local nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) - for n=1, #nodes do - local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) - if data[p_pos] == c_water then - data[p_pos] = c_nether_lava - lvm_used = true - elseif data[p_pos] == c_stone then - data[p_pos] = c_netherrack - lvm_used = true - elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then - data[p_pos] = c_soul_sand - lvm_used = true - end - end - else - local nodes = minetest.find_nodes_in_area(emin, emax, {"group:water"}) - for _, n in pairs(nodes) do - data[area:index(n.x, n.y, n.z)] = c_nether_lava - end - end - - -- End block fixes: - -- * Replace water with end stone or air (depending on height). - -- * Remove stone, sand, dirt in v6 so our End map generator works in v6. - -- * Generate spawn platform (End portal destination) - elseif minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min then - local nodes - if mg_name == "v6" then - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) - else - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"}) - end - if #nodes > 0 then - lvm_used = true - for _,n in pairs(nodes) do - data[area:index(n.x, n.y, n.z)] = c_air - end - end - - -- Obsidian spawn platform - if minp.y <= mcl_vars.mg_end_platform_pos.y and maxp.y >= mcl_vars.mg_end_platform_pos.y and - minp.x <= mcl_vars.mg_end_platform_pos.x and maxp.x >= mcl_vars.mg_end_platform_pos.z and - minp.z <= mcl_vars.mg_end_platform_pos.z and maxp.z >= mcl_vars.mg_end_platform_pos.z then - - --local pos1 = {x = math.max(minp.x, mcl_vars.mg_end_platform_pos.x-2), y = math.max(minp.y, mcl_vars.mg_end_platform_pos.y), z = math.max(minp.z, mcl_vars.mg_end_platform_pos.z-2)} - --local pos2 = {x = math.min(maxp.x, mcl_vars.mg_end_platform_pos.x+2), y = math.min(maxp.y, mcl_vars.mg_end_platform_pos.y+2), z = math.min(maxp.z, mcl_vars.mg_end_platform_pos.z+2)} - - for x=math.max(minp.x, mcl_vars.mg_end_platform_pos.x-2), math.min(maxp.x, mcl_vars.mg_end_platform_pos.x+2) do - for z=math.max(minp.z, mcl_vars.mg_end_platform_pos.z-2), math.min(maxp.z, mcl_vars.mg_end_platform_pos.z+2) do - for y=math.max(minp.y, mcl_vars.mg_end_platform_pos.y), math.min(maxp.y, mcl_vars.mg_end_platform_pos.y+2) do - local p_pos = area:index(x, y, z) - if y == mcl_vars.mg_end_platform_pos.y then - data[p_pos] = c_obsidian - else - data[p_pos] = c_air - end - end - end - end - lvm_used = true +-- End block fixes: +local function end_basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + if maxp.y < mcl_vars.mg_end_min or minp.y > mcl_vars.mg_end_max then return end + local biomemap --ymin, ymax + local lvm_used = false + local pr = PseudoRandom(blockseed) + local nodes + if mg_name ~= "v6" then + nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"}) + if #nodes > 0 then + lvm_used = true + for _,n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_air end end end - - -- Final hackery: Set sun light level in the End. - -- -26912 is at a mapchunk border. - local shadow = true - if minp.y >= -26912 and maxp.y <= mcl_vars.mg_end_max then - vm:set_lighting({day=15, night=15}) - lvm_used = true - end - if minp.y >= mcl_vars.mg_end_min and maxp.y <= -26911 then - shadow = false - lvm_used = true - end - - return lvm_used, shadow + return true, false 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, minetest.get_mapgen_object("biomemap")) - end + +mcl_mapgen_core.register_generator("world_structure", world_structure, nil, 1, true) +mcl_mapgen_core.register_generator("end_fixes", end_basic, function(minp,maxp) + if maxp.y < mcl_vars.mg_end_min or minp.y > mcl_vars.mg_end_max then return end +end, 9999, true) + +if mg_name ~= "v6" and mg_name ~= "singlenode" then + mcl_mapgen_core.register_generator("block_fixes", block_fixes, nil, 9999, true) end -mcl_mapgen_core.register_generator("main", basic, basic_node, 1, true) +if mg_name == "v6" then + dofile(modpath.."/v6.lua") +end + +-- This should be moved to mcl_structures eventually if the dependencies can be sorted out. +mcl_mapgen_core.register_generator("structures",nil, function(minp, maxp, blockseed) + local gennotify = minetest.get_mapgen_object("gennotify") + local has_struct = {} + local has = false + local poshash = minetest.hash_node_position(minp) + for _,struct in pairs(mcl_structures.registered_structures) do + local pr = PseudoRandom(blockseed + 42) + if struct.deco_id then + for _, pos in pairs(gennotify["decoration#"..struct.deco_id] or {}) do + local realpos = vector.offset(pos,0,1,0) + minetest.remove_node(realpos) + minetest.fix_light(vector.offset(pos,-1,-1,-1),vector.offset(pos,1,3,1)) + if struct.chunk_probability == nil or (not has and pr:next(1,struct.chunk_probability) == 1 ) then + mcl_structures.place_structure(realpos,struct,pr,blockseed) + has=true + end + end + elseif struct.static_pos then + for _,p in pairs(struct.static_pos) do + if in_cube(p,minp,maxp) then + mcl_structures.place_structure(p,struct,pr,blockseed) + end + end + end + end + return false, false, false +end, 100, true) diff --git a/mods/MAPGEN/mcl_mapgen_core/mod.conf b/mods/MAPGEN/mcl_mapgen_core/mod.conf index 9f7d9ebaa..6c001c1e3 100644 --- a/mods/MAPGEN/mcl_mapgen_core/mod.conf +++ b/mods/MAPGEN/mcl_mapgen_core/mod.conf @@ -1,5 +1,5 @@ name = mcl_mapgen_core author = Wuzzy description = The core of the MCL2 mapgen -depends = mcl_init, mcl_core, biomeinfo, mcl_worlds, mcl_cocoas, mcl_sponges, mcl_ocean, mcl_stairs, mcl_monster_eggs, mcl_structures -optional_depends = mclx_core +depends = mcl_init, mcl_core, mcl_deepslate, biomeinfo, mcl_worlds, mcl_cocoas, mcl_sponges, mcl_ocean, mcl_stairs, mcl_monster_eggs, mcl_structures +optional_depends = mclx_core, mcl_copper diff --git a/mods/MAPGEN/mcl_mapgen_core/ores.lua b/mods/MAPGEN/mcl_mapgen_core/ores.lua new file mode 100644 index 000000000..118806a47 --- /dev/null +++ b/mods/MAPGEN/mcl_mapgen_core/ores.lua @@ -0,0 +1,816 @@ + +local deepslate_max = mcl_worlds.layer_to_y(16) +local deepslate_min = mcl_vars.mg_overworld_min + +local copper_mod = minetest.get_modpath("mcl_copper") + +local mg_name = minetest.get_mapgen_setting("mg_name") +local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true" + +local mountains = { + "ExtremeHills", "ExtremeHills_beach", "ExtremeHills_ocean", "ExtremeHills_deep_ocean", "ExtremeHills_underground", + "ExtremeHills+", "ExtremeHills+_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills+_underground", + "ExtremeHillsM", "ExtremeHillsM_ocean", "ExtremeHillsM_deep_ocean", "ExtremeHillsM_underground", +} + +--Clay +minetest.register_ore({ + ore_type = "blob", + ore = "mcl_core:clay", + wherein = {"mcl_core:sand","mcl_core:stone","mcl_core:gravel"}, + clust_scarcity = 15*15*15, + clust_num_ores = 33, + clust_size = 5, + y_min = -5, + y_max = 0, + noise_params = { + offset = 0, + scale = 1, + spread = {x=250, y=250, z=250}, + seed = 34843, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } +}) + +-- Diorite, andesite and granite +local specialstones = { "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" } +for s=1, #specialstones do + local node = specialstones[s] + minetest.register_ore({ + ore_type = "blob", + ore = node, + wherein = {"mcl_core:stone"}, + clust_scarcity = 15*15*15, + clust_num_ores = 33, + clust_size = 5, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + noise_params = { + offset = 0, + scale = 1, + spread = {x=250, y=250, z=250}, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } + }) + minetest.register_ore({ + ore_type = "blob", + ore = node, + wherein = {"mcl_core:stone"}, + clust_scarcity = 10*10*10, + clust_num_ores = 58, + clust_size = 7, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + noise_params = { + offset = 0, + scale = 1, + spread = {x=250, y=250, z=250}, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } + }) +end + +local stonelike = {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"} + +-- Dirt +minetest.register_ore({ + ore_type = "blob", + ore = "mcl_core:dirt", + wherein = stonelike, + clust_scarcity = 15*15*15, + clust_num_ores = 33, + clust_size = 4, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + noise_params = { + offset = 0, + scale = 1, + spread = {x=250, y=250, z=250}, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } +}) + +-- Gravel +minetest.register_ore({ + ore_type = "blob", + ore = "mcl_core:gravel", + wherein = stonelike, + clust_scarcity = 14*14*14, + clust_num_ores = 33, + clust_size = 5, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(111), + noise_params = { + offset = 0, + scale = 1, + spread = {x=250, y=250, z=250}, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } +}) + + +minetest.register_ore({ + ore_type = "blob", + ore = "mcl_deepslate:deepslate", + wherein = { "mcl_core:stone" }, + clust_scarcity = 200, + clust_num_ores = 100, + clust_size = 10, + y_min = deepslate_min, + y_max = deepslate_max, + noise_params = { + offset = 0, + scale = 1, + spread = { x = 250, y = 250, z = 250 }, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } +}) + +minetest.register_ore({ + ore_type = "blob", + ore = "mcl_deepslate:tuff", + wherein = { "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_deepslate:deepslate" }, + clust_scarcity = 10*10*10, + clust_num_ores = 58, + clust_size = 7, + y_min = deepslate_min, + y_max = deepslate_max, + noise_params = { + offset = 0, + scale = 1, + spread = {x=250, y=250, z=250}, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } +}) + +-- DEEPSLATE +if minetest.settings:get_bool("mcl_generate_deepslate", true) then + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_deepslate:infested_deepslate", + wherein = "mcl_deepslate:deepslate", + clust_scarcity = 26 * 26 * 26, + clust_num_ores = 3, + clust_size = 2, + y_min = deepslate_min, + y_max = deepslate_max, + biomes = mountains, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:water_source", + wherein = "mcl_deepslate:deepslate", + clust_scarcity = 9000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(5), + y_max = deepslate_max, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = "mcl_deepslate:deepslate", + clust_scarcity = 2000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(1), + y_max = mcl_worlds.layer_to_y(10), + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = "mcl_deepslate:deepslate", + clust_scarcity = 9000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(11), + y_max = deepslate_max, + }) + +end + +if minetest.settings:get_bool("mcl_generate_ores", true) then + -- + -- Coal + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 525*3, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(50), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 510*3, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(50), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 12, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(50), + }) + + -- Medium-rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 550*3, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 525*3, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 600*3, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 550*3, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + + -- + -- Iron + -- + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_iron", + wherein = stonelike, + clust_scarcity = 830, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(39), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_iron", + wherein = stonelike, + clust_scarcity = 1660, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(40), + y_max = mcl_worlds.layer_to_y(63), + }) + + -- + -- Gold + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 4775, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(30), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 6560, + clust_num_ores = 7, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(30), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 13000, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(31), + y_max = mcl_worlds.layer_to_y(33), + }) + + -- + -- Diamond + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 5000, + clust_num_ores = 2, + clust_size = 2, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 20000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 20000, + clust_num_ores = 2, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + + -- + -- Ancient debris + -- + local ancient_debris_wherein = {"mcl_nether:netherrack","mcl_blackstone:blackstone","mcl_blackstone:basalt"} + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:ancient_debris", + wherein = ancient_debris_wherein, + clust_scarcity = 25000, -- 0.004% chance + clust_num_ores = 3, + clust_size = 3, + y_min = mcl_vars.mg_nether_min + 8, + y_max = mcl_vars.mg_nether_min + 22, + }) + + -- Rare spawn (below) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:ancient_debris", + wherein = ancient_debris_wherein, + clust_scarcity = 32000, + clust_num_ores = 2, + clust_size = 3, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_min + 8, + }) + + -- Rare spawn (above) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:ancient_debris", + wherein = ancient_debris_wherein, + clust_scarcity = 32000, + clust_num_ores = 2, + clust_size = 3, + y_min = mcl_vars.mg_nether_min + 22, + y_max = mcl_vars.mg_nether_min + 119, + }) + + -- + -- Redstone + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 500, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(13), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 800, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(13), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 1000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 1600, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + + -- + -- Emerald + -- + + if mg_name == "v6" then + -- Generate everywhere in v6, but rarely. + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_emerald", + wherein = stonelike, + clust_scarcity = 14340, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(29), + }) + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_emerald", + wherein = stonelike, + clust_scarcity = 21510, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(30), + y_max = mcl_worlds.layer_to_y(32), + }) + end + + -- + -- Lapis Lazuli + -- + + -- Common spawn (in the center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_worlds.layer_to_y(14), + y_max = mcl_worlds.layer_to_y(16), + }) + + -- Rare spawn (below center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 12000, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(10), + y_max = mcl_worlds.layer_to_y(13), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 14000, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(6), + y_max = mcl_worlds.layer_to_y(9), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 16000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(2), + y_max = mcl_worlds.layer_to_y(5), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 18000, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(0), + y_max = mcl_worlds.layer_to_y(2), + }) + + -- Rare spawn (above center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 12000, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(17), + y_max = mcl_worlds.layer_to_y(20), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 14000, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(21), + y_max = mcl_worlds.layer_to_y(24), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 16000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(25), + y_max = mcl_worlds.layer_to_y(28), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 18000, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(29), + y_max = mcl_worlds.layer_to_y(32), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 32000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(31), + y_max = mcl_worlds.layer_to_y(32), + }) + + if minetest.settings:get_bool("mcl_generate_deepslate", true) then + local stonelike = { "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" } + local function register_ore_mg(ore, scarcity, num, size, y_min, y_max, biomes) + biomes = biomes or "" + minetest.register_ore({ + ore_type = "scatter", + ore = ore, + wherein = { "mcl_deepslate:deepslate", "mcl_deepslate:tuff" }, + clust_scarcity = scarcity, + clust_num_ores = num, + clust_size = size, + y_min = y_min, + y_max = y_max, + biomes = biomes, + }) + end + local ore_mapgen = { + { "coal", 1575, 5, 3, deepslate_min, deepslate_max }, + { "coal", 1530, 8, 3, deepslate_min, deepslate_max }, + { "coal", 1500, 12, 3, deepslate_min, deepslate_max }, + { "iron", 830, 5, 3, deepslate_min, deepslate_max }, + { "gold", 4775, 5, 3, deepslate_min, deepslate_max }, + { "gold", 6560, 7, 3, deepslate_min, deepslate_max }, + { "diamond", 10000, 4, 3, deepslate_min, mcl_worlds.layer_to_y(12) }, + { "diamond", 5000, 2, 3, deepslate_min, mcl_worlds.layer_to_y(12) }, + { "diamond", 10000, 8, 3, deepslate_min, mcl_worlds.layer_to_y(12) }, + { "diamond", 20000, 1, 1, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, + { "diamond", 20000, 2, 2, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, + { "redstone", 500, 4, 3, deepslate_min, mcl_worlds.layer_to_y(13) }, + { "redstone", 800, 7, 4, deepslate_min, mcl_worlds.layer_to_y(13) }, + { "redstone", 1000, 4, 3, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, + { "redstone", 1600, 7, 4, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, + { "lapis", 10000, 7, 4, mcl_worlds.layer_to_y(14), deepslate_max }, + { "lapis", 12000, 6, 3, mcl_worlds.layer_to_y(10), mcl_worlds.layer_to_y(13) }, + { "lapis", 14000, 5, 3, mcl_worlds.layer_to_y(6), mcl_worlds.layer_to_y(9) }, + { "lapis", 16000, 4, 3, mcl_worlds.layer_to_y(2), mcl_worlds.layer_to_y(5) }, + { "lapis", 18000, 3, 2, mcl_worlds.layer_to_y(0), mcl_worlds.layer_to_y(2) }, + } + for _, o in pairs(ore_mapgen) do + register_ore_mg("mcl_deepslate:deepslate_with_"..o[1], o[2], o[3], o[4], o[5], o[6]) + end + if minetest.get_mapgen_setting("mg_name") == "v6" then + register_ore_mg("mcl_deepslate:deepslate_with_emerald", 14340, 1, 1, deepslate_min, deepslate_max) + else + register_ore_mg("mcl_deepslate:deepslate_with_emerald", 16384, 1, 1, mcl_worlds.layer_to_y(4), deepslate_max, mountains) + end + if copper_mod then + register_ore_mg("mcl_deepslate:deepslate_with_copper", 830, 5, 3, deepslate_min, deepslate_max) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_copper:stone_with_copper", + wherein = stonelike, + clust_scarcity = 830, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(39), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_copper:stone_with_copper", + wherein = stonelike, + clust_scarcity = 1660, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(40), + y_max = mcl_worlds.layer_to_y(63), + }) + end + end +end + +if not superflat then +-- Water and lava springs (single blocks of lava/water source) +-- Water appears at nearly every height, but not near the bottom +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:water_source", + wherein = {"mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:dirt"}, + clust_scarcity = 9000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(5), + y_max = mcl_worlds.layer_to_y(128), +}) + +-- Lava springs are rather common at -31 and below +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 2000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(1), + y_max = mcl_worlds.layer_to_y(10), +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 9000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(11), + y_max = mcl_worlds.layer_to_y(31), +}) + +-- Lava springs will become gradually rarer with increasing height +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 32000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(32), + y_max = mcl_worlds.layer_to_y(47), +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 72000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(48), + y_max = mcl_worlds.layer_to_y(61), +}) + +-- Lava may even appear above surface, but this is very rare +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 96000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(62), + y_max = mcl_worlds.layer_to_y(127), +}) +end diff --git a/mods/MAPGEN/mcl_mapgen_core/v6.lua b/mods/MAPGEN/mcl_mapgen_core/v6.lua new file mode 100644 index 000000000..bfdc14c06 --- /dev/null +++ b/mods/MAPGEN/mcl_mapgen_core/v6.lua @@ -0,0 +1,832 @@ +local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor + +local function register_mgv6_decorations() + -- Cacti + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand"}, + sidelen = 16, + noise_params = { + offset = -0.012, + scale = 0.024, + spread = {x = 100, y = 100, z = 100}, + seed = 257, + octaves = 3, + persist = 0.6 + }, + y_min = 4, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:cactus", + height = 1, + height_max = 3, + }) + + -- Sugar canes + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt", "mcl_core:coarse_dirt", "group:grass_block_no_snow", "group:sand", "mcl_core:podzol", "mcl_core:reeds"}, + sidelen = 16, + noise_params = { + offset = -0.3, + scale = 0.7, + spread = {x = 100, y = 100, z = 100}, + seed = 465, + octaves = 3, + persist = 0.7 + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:reeds", + height = 1, + height_max = 3, + spawn_by = { "mcl_core:water_source", "group:frosted_ice" }, + num_spawn_by = 1, + }) + + -- Doubletall grass + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:double_grass", param1 = 255, }, + { name = "mcl_flowers:double_grass_top", param1 = 255, }, + }, + }, + place_on = {"group:grass_block_no_snow"}, + sidelen = 8, + noise_params = { + offset = -0.0025, + scale = 0.03, + spread = {x = 100, y = 100, z = 100}, + seed = 420, + octaves = 3, + persist = 0.0, + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + }) + + -- Large ferns + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:double_fern", param1=255, }, + { name = "mcl_flowers:double_fern_top", param1=255, }, + }, + }, + -- v6 hack: This makes sure large ferns only appear in jungles + spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, + num_spawn_by = 1, + place_on = {"group:grass_block_no_snow"}, + + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.01, + spread = {x = 250, y = 250, z = 250}, + seed = 333, + octaves = 2, + persist = 0.66, + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + }) + + -- Large flowers + local function register_large_flower(name, seed, offset) + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:"..name, param1=255, }, + { name = "mcl_flowers:"..name.."_top", param1=255, }, + }, + }, + place_on = {"group:grass_block_no_snow"}, + + sidelen = 16, + noise_params = { + offset = offset, + scale = 0.01, + spread = {x = 300, y = 300, z = 300}, + seed = seed, + octaves = 5, + persist = 0.62, + }, + y_min = 1, + y_max = mcl_vars.overworld_max, + flags = "", + }) + end + + register_large_flower("rose_bush", 9350, -0.008) + register_large_flower("peony", 10450, -0.008) + register_large_flower("lilac", 10600, -0.007) + register_large_flower("sunflower", 2940, -0.005) + + -- Lily pad + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "mcl_core:water_source", prob = 0 }, + { name = "mcl_core:water_source" }, + { name = "mcl_flowers:waterlily", param1 = 255 }, + }, + }, + place_on = "mcl_core:dirt", + sidelen = 16, + noise_params = { + offset = -0.12, + scale = 0.3, + spread = {x = 200, y = 200, z = 200}, + seed = 503, + octaves = 6, + persist = 0.7, + }, + y_min = 0, + y_max = 0, + rotation = "random", + }) + + -- Pumpkin + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_farming:pumpkin", + param2 = 0, + param2_max = 3, + place_on = {"group:grass_block_no_snow"}, + sidelen = 16, + noise_params = { + offset = -0.008, + scale = 0.00666, + spread = {x = 250, y = 250, z = 250}, + seed = 666, + octaves = 6, + persist = 0.666 + }, + y_min = 1, + y_max = mcl_vars.overworld_max, + }) + + -- Melon + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 16, + noise_params = { + offset = 0.002, + scale = 0.006, + spread = {x = 250, y = 250, z = 250}, + seed = 333, + octaves = 3, + persist = 0.6 + }, + -- Small trick to make sure melon spawn in jungles + spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, + num_spawn_by = 1, + y_min = 1, + y_max = 40, + decoration = "mcl_farming:melon", + }) + + -- Tall grass + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 8, + noise_params = { + offset = 0.01, + scale = 0.3, + spread = {x = 100, y = 100, z = 100}, + seed = 420, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.overworld_max, + decoration = "mcl_flowers:tallgrass", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 8, + noise_params = { + offset = 0.04, + scale = 0.03, + spread = {x = 100, y = 100, z = 100}, + seed = 420, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.overworld_max, + decoration = "mcl_flowers:tallgrass", + }) + + -- Seagrass and kelp + local materials = {"dirt","sand"} + for i=1, #materials do + local mat = materials[i] + + minetest.register_decoration({ + deco_type = "simple", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:"..mat}, + sidelen = 8, + noise_params = { + offset = 0.04, + scale = 0.3, + spread = {x = 100, y = 100, z = 100}, + seed = 421, + octaves = 3, + persist = 0.6 + }, + flags = "force_placement", + place_offset_y = -1, + y_min = mcl_vars.overworld_min, + y_max = 0, + decoration = "mcl_ocean:seagrass_"..mat, + }) + minetest.register_decoration({ + deco_type = "simple", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:mat"}, + sidelen = 8, + noise_params = { + offset = 0.08, + scale = 0.03, + spread = {x = 100, y = 100, z = 100}, + seed = 421, + octaves = 3, + persist = 0.6 + }, + flags = "force_placement", + place_offset_y = -1, + y_min = mcl_vars.overworld_min, + y_max = -5, + decoration = "mcl_ocean:seagrass_"..mat, + }) + + minetest.register_decoration({ + deco_type = "simple", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:"..mat}, + sidelen = 16, + noise_params = { + offset = 0.01, + scale = 0.01, + spread = {x = 300, y = 300, z = 300}, + seed = 505, + octaves = 5, + persist = 0.62, + }, + flags = "force_placement", + place_offset_y = -1, + y_min = mcl_vars.overworld_min, + y_max = -6, + decoration = "mcl_ocean:kelp_"..mat, + param2 = 16, + param2_max = 96, + }) + minetest.register_decoration({ + deco_type = "simple", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:"..mat}, + sidelen = 16, + noise_params = { + offset = 0.01, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 506, + octaves = 5, + persist = 0.62, + }, + flags = "force_placement", + place_offset_y = -1, + y_min = mcl_vars.overworld_min, + y_max = -15, + decoration = "mcl_ocean:kelp_"..mat, + param2 = 32, + param2_max = 160, + }) + + end + + -- Wet Sponge + -- TODO: Remove this when we got ocean monuments + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_sponges:sponge_wet", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:dirt","mcl_core:sand"}, + sidelen = 16, + noise_params = { + offset = 0.00295, + scale = 0.006, + spread = {x = 250, y = 250, z = 250}, + seed = 999, + octaves = 3, + persist = 0.666 + }, + flags = "force_placement", + y_min = mcl_vars.mg_lava_overworld_max + 5, + y_max = -20, + }) + + -- Add a small amount of tall grass everywhere to avoid areas completely empty devoid of tall grass + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 8, + fill_ratio = 0.004, + y_min = 1, + y_max = mcl_vars.overworld_max, + decoration = "mcl_flowers:tallgrass", + }) + + local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"} + local mseeds = { 7133, 8244 } + for m=1, #mushrooms do + -- Mushrooms next to trees + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:mycelium", "mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite"}, + sidelen = 16, + noise_params = { + offset = 0.04, + scale = 0.04, + spread = {x = 100, y = 100, z = 100}, + seed = mseeds[m], + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = mushrooms[m], + spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", }, + num_spawn_by = 1, + }) + end + + -- Dead bushes + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.035, + spread = {x = 100, y = 100, z = 100}, + seed = 1972, + octaves = 3, + persist = 0.6 + }, + y_min = 4, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:deadbush", + }) + + local function register_mgv6_flower(name, seed, offset, y_max) + if offset == nil then + offset = 0 + end + if y_max == nil then + y_max = mcl_vars.mg_overworld_max + end + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 16, + noise_params = { + offset = offset, + scale = 0.006, + spread = {x = 100, y = 100, z = 100}, + seed = seed, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = y_max, + decoration = "mcl_flowers:"..name, + }) + end + + register_mgv6_flower("tulip_red", 436) + register_mgv6_flower("tulip_orange", 536) + register_mgv6_flower("tulip_pink", 636) + register_mgv6_flower("tulip_white", 736) + register_mgv6_flower("azure_bluet", 800) + register_mgv6_flower("dandelion", 8) + -- Allium is supposed to only appear in flower forest in MC. There are no flower forests in v6. + -- We compensate by making it slightly rarer in v6. + register_mgv6_flower("allium", 0, -0.001) + --[[ Blue orchid is supposed to appear in swamplands. There are no swamplands in v6. + We emulate swamplands by limiting the height to 5 levels above sea level, + which should be close to the water. ]] + register_mgv6_flower("blue_orchid", 64500, nil, mcl_worlds.layer_to_y(67)) + register_mgv6_flower("oxeye_daisy", 3490) + register_mgv6_flower("poppy", 9439) + + -- Put top snow on snowy grass blocks. The v6 mapgen does not generate the top snow on its own. + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_snow"}, + sidelen = 16, + fill_ratio = 11.0, -- complete coverage + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:snow", + }) + +end +register_mgv6_decorations() + +local function generate_mgv6_structures() + local chunk_has_igloo = false + local struct_min, struct_max = -3, 111 --64 + --except end exit portall all v6 + if maxp.y >= struct_min and minp.y <= struct_max then + -- Generate structures + local pr = PcgRandom(blockseed) + perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100) + -- Assume X and Z lengths are equal + local divlen = 5 + for x0 = minp.x, maxp.x, divlen do for z0 = minp.z, maxp.z, divlen do + -- Determine amount from perlin noise + local amount = math.floor(perlin_structures:get_2d({x=x0, y=z0}) * 9) + -- Find random positions based on this random + local p, ground_y + for i=0, amount do + p = {x = pr:next(x0, x0+divlen-1), y = 0, z = pr:next(z0, z0+divlen-1)} + -- Find ground level + ground_y = nil + local nn + for y = struct_max, struct_min, -1 do + p.y = y + local checknode = minetest.get_node(p) + if checknode then + nn = checknode.name + local def = minetest.registered_nodes[nn] + if def and def.walkable then + ground_y = y + break + end + end + end + + if ground_y then + p.y = ground_y+1 + local nn0 = minetest.get_node(p).name + -- Check if the node can be replaced + if minetest.registered_nodes[nn0] and minetest.registered_nodes[nn0].buildable_to then + -- Igloos + if not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or (minetest.get_item_group(nn, "grass_block_snow") == 1)) then + if pr:next(1, 4400) == 1 then + -- Check surface + local floor = {x=p.x+9, y=p.y-1, z=p.z+9} + local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:snowblock") + local surface2 = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:dirt_with_grass_snow") + if #surface + #surface2 >= 63 then + mcl_structures.call_struct(p, "igloo", nil, pr) + chunk_has_igloo = true + end + end + end + + -- Fossil + if nn == "mcl_core:sandstone" or nn == "mcl_core:sand" and not chunk_has_desert_temple and ground_y > 3 then + local fossil_prob = minecraft_chunk_probability(64, minp, maxp) + + if pr:next(1, fossil_prob) == 1 then + -- Spawn fossil below desert surface between layers 40 and 49 + local p1 = {x=p.x, y=pr:next(mcl_worlds.layer_to_y(40), mcl_worlds.layer_to_y(49)), z=p.z} + -- Very rough check of the environment (we expect to have enough stonelike nodes). + -- Fossils may still appear partially exposed in caves, but this is O.K. + local p2 = vector.add(p1, 4) + local nodes = minetest.find_nodes_in_area(p1, p2, {"mcl_core:sandstone", "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:dirt", "mcl_core:gravel"}) + + if #nodes >= 100 then -- >= 80% + mcl_structures.call_struct(p1, "fossil", nil, pr) + end + end + end + + -- Witch hut (v6) + if ground_y <= 0 and nn == "mcl_core:dirt" then + local prob = minecraft_chunk_probability(48, minp, maxp) + if pr:next(1, prob) == 1 then + + local swampland = minetest.get_biome_id("Swampland") + local swampland_shore = minetest.get_biome_id("Swampland_shore") + + -- Where do witches live? + -- v6: In Normal biome + if biomeinfo.get_v6_biome(p) == "Normal" then + here_be_witches = true + end + local here_be_witches = false + if here_be_witches then + + local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270" + local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1} + local size + if r == "0" or r == "180" then + size = {x=10, y=4, z=8} + else + size = {x=8, y=4, z=10} + end + local p2 = vector.add(p1, size) + + -- This checks free space at the “body” of the hut and a bit around. + -- ALL nodes must be free for the placement to succeed. + local free_nodes = minetest.find_nodes_in_area(p1, p2, {"air", "mcl_core:water_source", "mcl_flowers:waterlily"}) + if #free_nodes >= ((size.x+1)*(size.y+1)*(size.z+1)) then + local place = {x=p.x, y=WITCH_HUT_HEIGHT-1, z=p.z} + + -- FIXME: For some mysterious reason (black magic?) this + -- function does sometimes NOT spawn the witch hut. One can only see the + -- oak wood nodes in the water, but no hut. :-/ + mcl_structures.place_structure(place,mcl_structures.registered_structures["witch_hut"],pr) + + local function place_tree_if_free(pos, prev_result) + local nn = minetest.get_node(pos).name + if nn == "mcl_flowers:waterlily" or nn == "mcl_core:water_source" or nn == "mcl_core:water_flowing" or nn == "air" then + minetest.set_node(pos, {name="mcl_core:tree", param2=0}) + return prev_result + else + return false + end + end + local offsets + if r == "0" then + offsets = { + {x=1, y=0, z=1}, + {x=1, y=0, z=5}, + {x=6, y=0, z=1}, + {x=6, y=0, z=5}, + } + elseif r == "180" then + offsets = { + {x=2, y=0, z=1}, + {x=2, y=0, z=5}, + {x=7, y=0, z=1}, + {x=7, y=0, z=5}, + } + elseif r == "270" then + offsets = { + {x=1, y=0, z=1}, + {x=5, y=0, z=1}, + {x=1, y=0, z=6}, + {x=5, y=0, z=6}, + } + elseif r == "90" then + offsets = { + {x=1, y=0, z=2}, + {x=5, y=0, z=2}, + {x=1, y=0, z=7}, + {x=5, y=0, z=7}, + } + end + for o=1, #offsets do + local ok = true + for y=place.y-1, place.y-64, -1 do + local tpos = vector.add(place, offsets[o]) + tpos.y = y + ok = place_tree_if_free(tpos, ok) + if not ok then + break + end + end + end + end + end + end + end + + -- Ice spikes in v6 + -- In other mapgens, ice spikes are generated as decorations. + if nn == "mcl_core:snowblock" then + local spike = pr:next(1,58000) + if spike < 3 then + -- Check surface + local floor = {x=p.x+4, y=p.y-1, z=p.z+4} + local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock"}) + -- Check for collision with spruce + local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) + + if #surface >= 9 and #spruce_collisions == 0 then + mcl_structures.place_structure(p,mcl_structures.registered_structures["ice_spike_large"],pr) + end + elseif spike < 100 then + -- Check surface + local floor = {x=p.x+6, y=p.y-1, z=p.z+6} + local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock", "mcl_core:dirt_with_grass_snow"}) + + -- Check for collision with spruce + local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) + + if #surface >= 25 and #spruce_collisions == 0 then + mcl_structures.place_structure(p,mcl_structures.registered_structures["ice_spike_small"],pr) + end + end + end + end + end + end + end end + end +end + +-- Generate mushrooms in caves manually. +-- only v6. minetest supports cave decos via "all_floors" flag now +local function generate_underground_mushrooms(minp, maxp, seed) + local pr_shroom = PseudoRandom(seed-24359) + -- Generate rare underground mushrooms + -- TODO: Make them appear in groups, use Perlin noise + local min, max = mcl_vars.mg_lava_overworld_max + 4, 0 + if minp.y > max or maxp.y < min then + return + end + + local bpos + local stone = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_core:stone", "mcl_core:dirt", "mcl_core:mycelium", "mcl_core:podzol", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:stone_with_iron", "mcl_core:stone_with_gold"}) + + for n = 1, #stone do + bpos = {x = stone[n].x, y = stone[n].y + 1, z = stone[n].z } + + local l = minetest.get_node_light(bpos, 0.5) + if bpos.y >= min and bpos.y <= max and l and l <= 12 and pr_shroom:next(1,1000) < 4 then + if pr_shroom:next(1,2) == 1 then + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) + else + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) + end + end + end +end + +-- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart +-- (only v6) +local nether_wart_chance = 85 +local function generate_nether_decorations(minp, maxp, seed) + local pr_nether = PseudoRandom(seed+667) + + if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then + return + end + + minetest.log("action", "[mcl_mapgen_core] Nether decorations " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp)) + + -- TODO: Generate everything based on Perlin noise instead of PseudoRandom + + local bpos + local rack = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:netherrack"}) + local magma = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:magma"}) + local ssand = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:soul_sand"}) + + -- Helper function to spawn “fake” decoration + local function special_deco(nodes, spawn_func) + for n = 1, #nodes do + bpos = {x = nodes[n].x, y = nodes[n].y + 1, z = nodes[n].z } + + spawn_func(bpos) + end + end + -- Eternal fire on netherrack + special_deco(rack, function(bpos) + -- Eternal fire on netherrack + if pr_nether:next(1,100) <= 3 then + minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"}) + end + end) + + -- Eternal fire on magma cubes + special_deco(magma, function(bpos) + if pr_nether:next(1,150) == 1 then + minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"}) + end + end) + + -- Mushrooms on netherrack + -- Note: Spawned *after* the fire because of light level checks + special_deco(rack, function(bpos) + local l = minetest.get_node_light(bpos, 0.5) + if bpos.y > mcl_vars.mg_lava_nether_max + 6 and l and l <= 12 and pr_nether:next(1,1000) <= 4 then + -- TODO: Make mushrooms appear in groups, use Perlin noise + if pr_nether:next(1,2) == 1 then + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) + else + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) + end + end + end) + + -- Nether wart on soul sand + -- TODO: Spawn in Nether fortresses + special_deco(ssand, function(bpos) + if pr_nether:next(1, nether_wart_chance) == 1 then + minetest.set_node(bpos, {name = "mcl_nether:nether_wart"}) + end + end) +end + +local function remove_mgv6_broken_plants(minp,maxp) + --[[ Remove broken double plants caused by v6 weirdness. + v6 might break the bottom part of double plants because of how it works. + There are 3 possibilities: + 1) Jungle: Top part is placed on top of a jungle tree or fern (=v6 jungle grass). + This is because the schematic might be placed even if some nodes of it + could not be placed because the destination was already occupied. + TODO: A better fix for this would be if schematics could abort placement + altogether if ANY of their nodes could not be placed. + 2) Cavegen: Removes the bottom part, the upper part floats + 3) Mudflow: Same as 2) ]] + + local plants = minetest.find_nodes_in_area(minp, maxp, "group:double_plant") + for n = 1, #plants do + local node = vm:get_node_at(plants[n]) + local is_top = minetest.get_item_group(node.name, "double_plant") == 2 + if is_top then + local p_pos = area:index(plants[n].x, plants[n].y-1, plants[n].z) + if p_pos then + node = vm:get_node_at({x=plants[n].x, y=plants[n].y-1, z=plants[n].z}) + local is_bottom = minetest.get_item_group(node.name, "double_plant") == 1 + if not is_bottom then + p_pos = area:index(plants[n].x, plants[n].y, plants[n].z) + data[p_pos] = c_air + lvm_used = true + end + end + end + end +end + +local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + if not (minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min) then + return + end + -- Nether block fixes: + -- * Replace water with Nether lava. + -- * Replace stone, sand dirt in v6 so the Nether works in v6. + local nodes = minetest.find_nodes_in_area(emin, emax, {"group:water"}) + for _, n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_nether_lava + lvm_used = true + end + nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) + for n=1, #nodes do + local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) + if data[p_pos] == c_water then + data[p_pos] = c_nether_lava + lvm_used = true + elseif data[p_pos] == c_stone then + data[p_pos] = c_netherrack + lvm_used = true + elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then + data[p_pos] = c_soul_sand + lvm_used = true + end + end +end + +local function end_fixes(minp,maxp) + if not ( minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min ) then + return + end + local nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) + if #nodes > 0 then + lvm_used = true + for _,n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_air + end + end +end + +local function basic_node(minp, maxp, blockseed) + if mg_name ~= "singlenode" then + -- Generate special decorations + if mg_name == "v6" then + generate_underground_mushrooms(minp, maxp, blockseed) + generate_nether_decorations(minp, maxp, blockseed) + end_fixes(minp,maxp) + remove_mgv6_broken_plants(minp,maxp,blockseed) + generate_mgv6_structures(minp, maxp, blockseed, minetest.get_mapgen_object("biomemap")) + end + end +end + +mcl_mapgen_core.register_generator("mgv6-fixes", basic, basic_node, 10, true) diff --git a/mods/MAPGEN/mcl_nether_fortresses/init.lua b/mods/MAPGEN/mcl_nether_fortresses/init.lua new file mode 100644 index 000000000..bf8f9c599 --- /dev/null +++ b/mods/MAPGEN/mcl_nether_fortresses/init.lua @@ -0,0 +1,212 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +mcl_structures.register_structure("nether_outpost",{ + place_on = {"mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand"}, + fill_ratio = 0.01, + chunk_probability = 900, + flags = "all_floors", + biomes = {"Nether","SoulsandValley","WarpedForest","CrimsonForest","BasaltDelta"}, + sidelen = 24, + solid_ground = true, + make_foundation = true, + y_min = mcl_vars.mg_lava_nether_max - 1, + y_max = mcl_vars.mg_nether_max - 30, + filenames = { modpath.."/schematics/mcl_nether_fortresses_nether_outpost.mts" }, + y_offset = 0, + after_place = function(pos) + local sp = minetest.find_nodes_in_area(pos,vector.offset(pos,0,20,0),{"mcl_mobspawners:spawner"}) + if not sp[1] then return end + mcl_mobspawners.setup_spawner(sp[1], "mobs_mc:blaze", 0, minetest.LIGHT_MAX+1, 10, 8, 0) + end +}) +local nbridges = { + modpath.."/schematics/mcl_nether_fortresses_nether_bridge_1.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bridge_2.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bridge_3.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bridge_4.mts", +} +mcl_structures.register_structure("nether_bridge",{ + place_on = {"mcl_nether:nether_lava_source","mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand","mcl_core:bedrock"}, + fill_ratio = 0.01, + chunk_probability = 500, + flags = "all_floors", + sidelen = 38, + solid_ground = false, + make_foundation = false, + y_min = mcl_vars.mg_nether_min - 4, + y_max = mcl_vars.mg_lava_nether_max - 20, + filenames = nbridges, + y_offset = function(pr) return pr:next(15,20) end, + after_place = function(pos,def,pr) + local p1 = vector.offset(pos,-14,0,-14) + local p2 = vector.offset(pos,14,24,14) + mcl_structures.spawn_mobs("mobs_mc:witherskeleton",{"mcl_blackstone:blackstone_chiseled_polished"},p1,p2,pr,5) + end +}) + +mcl_structures.register_structure("nether_outpost_with_bridges",{ + place_on = {"mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand","mcl_nether:nether_lava_source"}, + fill_ratio = 0.01, + chunk_probability = 1300, + flags = "all_floors", + biomes = {"Nether","SoulsandValley","WarpedForest","CrimsonForest","BasaltDelta"}, + sidelen = 24, + solid_ground = true, + make_foundation = true, + y_min = mcl_vars.mg_lava_nether_max - 1, + y_max = mcl_vars.mg_nether_max - 30, + filenames = { modpath.."/schematics/mcl_nether_fortresses_nether_outpost.mts" }, + daughters = {{ + files = { nbridges[1] }, + pos = vector.new(0,-2,-24), + rot = 180, + }, + { + files = { nbridges[1] }, + pos = vector.new(0,-2,24), + rot = 0, + }, + { + files = { nbridges[1] }, + pos = vector.new(-24,-2,0), + rot = 270, + }, + { + files = { nbridges[1] }, + pos = vector.new(24,-2,0), + rot = 90, + }, + }, + after_place = function(pos,def,pr) + local sp = minetest.find_nodes_in_area(pos,vector.offset(pos,0,20,0),{"mcl_mobspawners:spawner"}) + if not sp[1] then return end + mcl_mobspawners.setup_spawner(sp[1], "mobs_mc:blaze", 0, minetest.LIGHT_MAX+1, 10, 8, 0) + + local legs = minetest.find_nodes_in_area(vector.offset(pos,-45,-2,-45),vector.offset(pos,45,0,45), "mcl_nether:nether_brick") + local bricks = {} + for _,leg in pairs(legs) do + while minetest.get_item_group(mcl_vars.get_node(vector.offset(leg,0,-1,0), true, 333333).name, "solid") == 0 do + leg = vector.offset(leg,0,-1,0) + table.insert(bricks,leg) + end + end + minetest.bulk_set_node(bricks, {name = "mcl_nether:nether_brick", param2 = 2}) + + local p1 = vector.offset(pos,-45,13,-45) + local p2 = vector.offset(pos,45,13,45) + mcl_structures.spawn_mobs("mobs_mc:witherskeleton",{"mcl_blackstone:blackstone_chiseled_polished"},p1,p2,pr,5) + end +},true) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:witherskeleton", + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_max, + chance = 15, + interval = 60, + limit = 4, + spawnon = { "mcl_blackstone:blackstone_chiseled_polished" }, +}) + +mcl_structures.register_structure("nether_bulwark",{ + place_on = {"mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand"}, + fill_ratio = 0.01, + chunk_probability = 900, + flags = "all_floors", + biomes = {"Nether","SoulsandValley","WarpedForest","CrimsonForest"}, + sidelen = 36, + solid_ground = true, + make_foundation = true, + y_min = mcl_vars.mg_lava_nether_max - 1, + y_max = mcl_vars.mg_nether_max - 30, + filenames = { + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_1.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_2.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_3.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_4.mts", + }, + daughters = {{ + files = { + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_interior_1.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_interior_2.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_interior_3.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_interior_4.mts", + }, + pos = vector.new(0,0,0), + }, + }, + y_offset = 0, + construct_nodes = {"group:wall"}, + after_place = function(pos,def,pr) + local p1 = vector.offset(pos,-14,0,-14) + local p2 = vector.offset(pos,14,24,14) + mcl_structures.spawn_mobs("mobs_mc:piglin",{"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"},p1,p2,pr,5) + mcl_structures.spawn_mobs("mobs_mc:piglin_brute",{"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"},p1,p2,pr) + mcl_structures.spawn_mobs("mobs_mc:hoglin",{"mcl_blackstone:nether_gold"},p1,p2,pr,4) + end, + loot = { + ["mcl_chests:chest_small" ] ={ + { + stacks_min = 1, + stacks_max = 2, + items = { + --{ itemstring = "FIXME:spectral_arrow", weight = 1, amount_min = 10, amount_max=28 }, + { itemstring = "mcl_blackstone:blackstone_gilded", weight = 1, amount_min = 8, amount_max=12 }, + { itemstring = "mcl_core:iron_ingot", weight = 1, amount_min = 4, amount_max=9 }, + { itemstring = "mcl_core:gold_ingot", weight = 1, amount_min = 4, amount_max=9 }, + { itemstring = "mcl_core:crying_obsidian", weight = 1, amount_min = 3, amount_max=8 }, + { itemstring = "mcl_bows:crossbow", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_core:goldblock", weight = 1, }, + { itemstring = "mcl_tools:sword_gold", weight = 1, }, + { itemstring = "mcl_tools:axe_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + } + }, + { + stacks_min = 2, + stacks_max = 4, + items = { + { itemstring = "mcl_bows:arrow", weight = 4, amount_min = 5, amount_max=17 }, + { itemstring = "mcl_mobitems:string", weight = 4, amount_min = 1, amount_max=6 }, + { itemstring = "mcl_core:iron_nugget", weight = 1, amount_min = 2, amount_max = 6 }, + { itemstring = "mcl_core:gold_nugget", weight = 1, amount_min = 2, amount_max = 6 }, + { itemstring = "mcl_mobitems:leather", weight = 1, amount_min = 1, amount_max = 3 }, + } + }, + { + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_compass:lodestone" }, + } + }} + }, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:piglin", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + chance = 10, + interval = 60, + limit = 9, + spawnon = {"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"}, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:piglin_brute", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + chance = 20, + interval = 60, + limit = 4, + spawnon = {"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"}, +}) diff --git a/mods/MAPGEN/mcl_nether_fortresses/mod.conf b/mods/MAPGEN/mcl_nether_fortresses/mod.conf new file mode 100644 index 000000000..7d1565ff3 --- /dev/null +++ b/mods/MAPGEN/mcl_nether_fortresses/mod.conf @@ -0,0 +1,3 @@ +name = mcl_nether_fortresses +author = cora +depends = mcl_init, mcl_structures, mcl_mobspawners diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_1.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_1.mts new file mode 100644 index 000000000..6923f6edb Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_1.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_2.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_2.mts new file mode 100644 index 000000000..ba04dfd2d Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_2.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_3.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_3.mts new file mode 100644 index 000000000..e62e298fd Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_3.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_4.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_4.mts new file mode 100644 index 000000000..6b66ac6a0 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_4.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_1.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_1.mts new file mode 100644 index 000000000..a9522cce0 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_1.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_2.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_2.mts new file mode 100644 index 000000000..7cf4c0722 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_2.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_3.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_3.mts new file mode 100644 index 000000000..01f893dd7 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_3.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_4.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_4.mts new file mode 100644 index 000000000..1fc74c18b Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_4.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_1.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_1.mts new file mode 100644 index 000000000..9c09c3edb Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_1.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_2.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_2.mts new file mode 100644 index 000000000..b73a5a590 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_2.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_3.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_3.mts new file mode 100644 index 000000000..0a4c05425 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_3.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_4.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_4.mts new file mode 100644 index 000000000..d7e23f027 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_4.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_outpost.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_outpost.mts new file mode 100644 index 000000000..4fa3f1935 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_outpost.mts differ diff --git a/mods/MAPGEN/mcl_strongholds/init.lua b/mods/MAPGEN/mcl_strongholds/init.lua index 083172a3c..d5bc87963 100644 --- a/mods/MAPGEN/mcl_strongholds/init.lua +++ b/mods/MAPGEN/mcl_strongholds/init.lua @@ -16,25 +16,17 @@ local stronghold_rings = { } local strongholds = {} -local strongholds_inited = false local mg_name = minetest.get_mapgen_setting("mg_name") local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true" +local seed = tonumber(minetest.get_mapgen_setting("seed")) --- Determine the stronghold positions and store them into the strongholds table. --- The stronghold positions are based on the world seed. --- The actual position might be offset by a few blocks because it might be shifted --- to make sure the end portal room is completely within the boundaries of a mapchunk. local function init_strongholds() - if strongholds_inited then - return - end + local stronghold_positions = {} -- Don't generate strongholds in singlenode if mg_name == "singlenode" then - strongholds_inited = true - return + return {} end - local seed = tonumber(minetest.get_mapgen_setting("seed")) local pr = PseudoRandom(seed) for s=1, #stronghold_rings do local ring = stronghold_rings[s] @@ -53,17 +45,14 @@ local function init_strongholds() end local pos = { x = math.cos(angle) * dist, y = y, z = math.sin(angle) * dist } pos = vector.round(pos) - table.insert(strongholds, { pos = pos, generated = false }) + table.insert(stronghold_positions, pos) -- Rotate angle by (360 / amount) degrees. -- This will cause the angles to be evenly distributed in the stronghold ring angle = math.fmod(angle + ((math.pi*2) / ring.amount), math.pi*2) end end - - mcl_structures.register_structures("stronghold", table.copy(strongholds)) - - strongholds_inited = true + return stronghold_positions end -- Stronghold generation for register_on_generated. @@ -94,13 +83,94 @@ local function generate_strongholds(minp, maxp, blockseed) pos.z = maxp.z - 7 end - mcl_structures.call_struct(pos, "end_portal_shrine", nil, pr) + --mcl_structures.call_struct(pos, "end_portal_shrine", nil, pr) strongholds[s].generated = true end end end end -init_strongholds() +mcl_structures.register_structure("end_shrine",{ + static_pos = init_strongholds(), + filenames = { + minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" + }, + after_place = function(pos,def,pr,blockseed,p1,p2,size,rotation) + local p1 = vector.subtract(pos,size) + local p2 = vector.add(pos,size) + local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") + for s=1, #spawners do + --local meta = minetest.get_meta(spawners[s]) + mcl_mobspawners.setup_spawner(spawners[s], "mobs_mc:silverfish") + end -mcl_mapgen_core.register_generator("strongholds", nil, generate_strongholds, 999999) + -- Shuffle stone brick types + local bricks = minetest.find_nodes_in_area(p1, p2, "mcl_core:stonebrick") + for b=1, #bricks do + local r_bricktype = pr:next(1, 100) + local r_infested = pr:next(1, 100) + local bricktype + if r_infested <= 5 then + if r_bricktype <= 30 then -- 30% + bricktype = "mcl_monster_eggs:monster_egg_stonebrickmossy" + elseif r_bricktype <= 50 then -- 20% + bricktype = "mcl_monster_eggs:monster_egg_stonebrickcracked" + else -- 50% + bricktype = "mcl_monster_eggs:monster_egg_stonebrick" + end + else + if r_bricktype <= 30 then -- 30% + bricktype = "mcl_core:stonebrickmossy" + elseif r_bricktype <= 50 then -- 20% + bricktype = "mcl_core:stonebrickcracked" + end + -- 50% stonebrick (no change necessary) + end + if bricktype then + minetest.set_node(bricks[b], { name = bricktype }) + end + end + + -- Also replace stairs + local stairs = minetest.find_nodes_in_area(p1, p2, {"mcl_stairs:stair_stonebrick", "mcl_stairs:stair_stonebrick_outer", "mcl_stairs:stair_stonebrick_inner"}) + for s=1, #stairs do + local stair = minetest.get_node(stairs[s]) + local r_type = pr:next(1, 100) + if r_type <= 30 then -- 30% mossy + if stair.name == "mcl_stairs:stair_stonebrick" then + stair.name = "mcl_stairs:stair_stonebrickmossy" + elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then + stair.name = "mcl_stairs:stair_stonebrickmossy_outer" + elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then + stair.name = "mcl_stairs:stair_stonebrickmossy_inner" + end + minetest.set_node(stairs[s], stair) + elseif r_type <= 50 then -- 20% cracky + if stair.name == "mcl_stairs:stair_stonebrick" then + stair.name = "mcl_stairs:stair_stonebrickcracked" + elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then + stair.name = "mcl_stairs:stair_stonebrickcracked_outer" + elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then + stair.name = "mcl_stairs:stair_stonebrickcracked_inner" + end + minetest.set_node(stairs[s], stair) + end + -- 50% no change + end + + -- Randomly add ender eyes into end portal frames, but never fill the entire frame + local frames = minetest.find_nodes_in_area(p1, p2, "mcl_portals:end_portal_frame") + local eyes = 0 + for f=1, #frames do + local r_eye = pr:next(1, 10) + if r_eye == 1 then + eyes = eyes + 1 + if eyes < #frames then + local frame_node = minetest.get_node(frames[f]) + frame_node.name = "mcl_portals:end_portal_frame_eye" + minetest.set_node(frames[f], frame_node) + end + end + end + end, +}) diff --git a/mods/MAPGEN/mcl_structures/API.md b/mods/MAPGEN/mcl_structures/API.md new file mode 100644 index 000000000..074810186 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/API.md @@ -0,0 +1,38 @@ +# mcl_structures +Structure placement API for MCL2. + +## mcl_structures.register_structure(name,structure definition,nospawn) +If nospawn is truthy the structure will not be placed by mapgen and the decoration parameters can be omitted. This is intended for secondary structures the placement of which gets triggered by the placement of other structures. It can also be used to register testing structures so they can be used with /spawnstruct. + +### structure definition +{ + fill_ratio = OR noise = {}, + biomes = {}, + y_min =, + y_max =, + place_on = {}, + spawn_by = {}, + num_spawn_by =, + flags = (default: "place_center_x, place_center_z, force_placement") + (same as decoration def) + y_offset =, --can be a number or a function returning a number + filenames = {} OR place_func = function(pos,def,pr) + -- filenames can be a list of any schematics accepted by mcl_structures.place_schematic / minetest.place_schematic + on_place = function(pos,def,pr) end, + -- called before placement. denies placement when returning falsy. + after_place = function(pos,def,pr) + -- executed after successful placement + sidelen = int, --length of one side of the structure. used for foundations. + solid_ground = bool, -- structure requires solid ground + make_foundation = bool, -- a foundation is automatically built for the structure. needs the sidelen param + loot = , + --a table of loot tables for mcl_loot indexed by node names + -- e.g. { ["mcl_chests:chest_small"] = {loot},... } +} +## mcl_structures.registered_structures +Table of the registered structure defintions indexed by name. + +## mcl_structures.place_structure(pos, def, pr) +Places a structure using the mapgen placement function + +## mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) diff --git a/mods/MAPGEN/mcl_structures/api.lua b/mods/MAPGEN/mcl_structures/api.lua new file mode 100644 index 000000000..cf47b4e30 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/api.lua @@ -0,0 +1,422 @@ +mcl_structures.registered_structures = {} + +local place_queue = {} +local disabled_structures = minetest.settings:get("mcl_disabled_structures") +if disabled_structures then disabled_structures = disabled_structures:split(",") +else disabled_structures = {} end + +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) +local mob_cap_player = tonumber(minetest.settings:get("mcl_mob_cap_player")) or 75 +local mob_cap_animal = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 10 + +local logging = minetest.settings:get_bool("mcl_logging_structures",true) + +local mg_name = minetest.get_mapgen_setting("mg_name") + +local rotations = { + "0", + "90", + "180", + "270" +} + +function mcl_structures.is_disabled(structname) + return table.indexof(disabled_structures,structname) ~= -1 +end + +local function ecb_place(blockpos, action, calls_remaining, param) + if calls_remaining >= 1 then return end + minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) + if param.after_placement_callback and param.p1 and param.p2 then + param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param) + end +end + +function mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) + if type(schematic) ~= "table" and not mcl_util.file_exists(schematic) then + minetest.log("warning","[mcl_structures] schematic file "..tostring(schematic).." does not exist.") + return end + local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic")() + if s and s.size then + local x, z = s.size.x, s.size.z + if rotation then + if rotation == "random" and pr then + rotation = rotations[pr:next(1,#rotations)] + end + if rotation == "random" then + x = math.max(x, z) + z = x + elseif rotation == "90" or rotation == "270" then + x, z = z, x + end + end + local p1 = {x=pos.x , y=pos.y , z=pos.z } + local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} + minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) + local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} + minetest.emerge_area(p1, p2, ecb_place, param) + return true + end +end + +function mcl_structures.get_struct(file) + local localfile = modpath.."/schematics/"..file + local file, errorload = io.open(localfile, "rb") + if errorload then + minetest.log("error", "[mcl_structures] Could not open this struct: "..localfile) + return nil + end + + local allnode = file:read("*a") + file:close() + + return allnode +end + +-- Call on_construct on pos. +-- Useful to init chests from formspec. +local function init_node_construct(pos) + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + if def and def.on_construct then + def.on_construct(pos) + return true + end + return false +end +mcl_structures.init_node_construct = init_node_construct + +function mcl_structures.fill_chests(p1,p2,loot,pr) + for it,lt in pairs(loot) do + local nodes = minetest.find_nodes_in_area(p1, p2, it) + for _,p in pairs(nodes) do + local lootitems = mcl_loot.get_multi_loot(lt, pr) + mcl_structures.init_node_construct(p) + local meta = minetest.get_meta(p) + local inv = meta:get_inventory() + mcl_loot.fill_inventory(inv, "main", lootitems, pr) + end + end +end + +local function generate_loot(pos, def, pr) + local hl = def.sidelen + local p1 = vector.offset(pos,-hl,-hl,-hl) + local p2 = vector.offset(pos,hl,hl,hl) + if def.loot then mcl_structures.fill_chests(p1,p2,def.loot,pr) end +end + +function mcl_structures.construct_nodes(p1,p2,nodes) + local nn=minetest.find_nodes_in_area(p1,p2,nodes) + for _,p in pairs(nn) do + mcl_structures.init_node_construct(p) + end +end + +local function construct_nodes(pos,def,pr) + return mcl_structures.construct_nodes(vector.offset(pos,-def.sidelen/2,0,-def.sidelen/2),vector.offset(pos,def.sidelen/2,def.sidelen,def.sidelen/2),def.construct_nodes) +end + + +function mcl_structures.find_lowest_y(pp) + local y = 31000 + for _,p in pairs(pp) do + if p.y < y then y = p.y end + end + return y +end + +function mcl_structures.find_highest_y(pp) + local y = -31000 + for _,p in pairs(pp) do + if p.y > y then y = p.y end + end + return y +end + +local function smooth_cube(nn,pos,plane,amnt) + local r = {} + local amnt = amnt or 9 + table.sort(nn,function(a, b) + if false or plane then + return vector.distance(vector.new(pos.x,0,pos.z), vector.new(a.x,0,a.z)) < vector.distance(vector.new(pos.x,0,pos.z), vector.new(b.x,0,b.z)) + else + return vector.distance(pos, a) < vector.distance(pos, b) + end + end) + for i=1,math.max(1,#nn-amnt) do table.insert(r,nn[i]) end + return r +end + +local function find_ground(pos,nn,gn) + local r = 0 + for _,v in pairs(nn) do + local p=vector.new(v) + repeat + local n = minetest.get_node(p).name + p = vector.offset(p,0,-1,0) + until not n or n == "mcl_core:bedrock" or n == "ignore" or n == gn + --minetest.log(tostring(pos.y - p.y)) + if pos.y - p.y > r then r = pos.y - p.y end + end + return r +end + +local function get_foundation_nodes(ground_p1,ground_p2,pos,sidelen,node_stone) + local replace = {"air","group:liquid","mcl_core:snow","group:tree","group:leaves","group:plant","grass_block","group:dirt"} + local depth = find_ground(pos,minetest.find_nodes_in_area(ground_p1,ground_p2,replace),node_stone) + local nn = smooth_cube(minetest.find_nodes_in_area(vector.offset(ground_p1,0,-1,0),vector.offset(ground_p2,0,-depth,0),replace),vector.offset(pos,0,-depth,0),true,sidelen * 64) + local stone = {} + local filler = {} + local top = {} + local dust = {} + for l,v in pairs(nn) do + if v.y == ground_p1.y - 1 then + table.insert(filler,v) + table.insert(top,vector.offset(v,0,1,0)) + table.insert(dust,vector.offset(v,0,2,0)) + elseif v.y < ground_p1.y -1 and v.y > ground_p2.y -4 then table.insert(filler,v) + elseif v.y < ground_p2.y - 3 and v.y > ground_p2.y -5 then + if math.random(3) == 1 then + table.insert(filler,v) + else + table.insert(stone,v) + end + else + table.insert(stone,v) + end + end + return stone,filler,top,dust +end + +local function foundation(ground_p1,ground_p2,pos,sidelen) + local node_stone = "mcl_core:stone" + local node_filler = "mcl_core:dirt" + local node_top = "mcl_core:dirt_with_grass" or minetest.get_node(ground_p1).name + local node_dust = nil + + if mg_name ~= "v6" then + local b = minetest.registered_biomes[minetest.get_biome_name(minetest.get_biome_data(pos).biome)] + --minetest.log(dump(b.node_top)) + if b then + if b.node_top then node_top = b.node_top end + if b.node_filler then node_filler = b.node_filler end + if b.node_stone then node_stone = b.node_stone end + if b.node_dust then node_dust = b.node_dust end + end + end + + local stone,filler,top,dust = get_foundation_nodes(ground_p1,ground_p2,pos,sidelen,node_stone) + minetest.bulk_set_node(top,{name=node_top},node_stone) + + if node_dust then + minetest.bulk_set_node(dust,{name=node_dust}) + end + minetest.bulk_set_node(filler,{name=node_filler}) + minetest.bulk_set_node(stone,{name=node_stone}) +end + +local function process_queue() + if #place_queue < 1 then return end + local s = table.remove(place_queue) + mcl_structures.place_schematic(s.pos, s.file, s.rot, nil, true, "place_center_x,place_center_z",function(s) + if s.after_place then + s.after_place(s.pos,s.def,s.pr) + end + end,s.pr) + minetest.after(0.5,process_queue) +end + +function mcl_structures.spawn_mobs(mob,spawnon,p1,p2,pr,n,water) + n = n or 1 + local sp = {} + if water then + local nn = minetest.find_nodes_in_area(p1,p2,spawnon) + for k,v in pairs(nn) do + if minetest.get_item_group(minetest.get_node(vector.offset(v,0,1,0)).name,"water") > 0 then + table.insert(sp,v) + end + end + else + sp = minetest.find_nodes_in_area_under_air(p1,p2,spawnon) + end + table.shuffle(sp) + for i,node in pairs(sp) do + if not peaceful and i <= n then + local pos = vector.offset(node,0,1,0) + if pos then + minetest.add_entity(pos,mob) + end + end + minetest.get_meta(node):set_string("spawnblock","yes") + end +end + +function mcl_structures.place_structure(pos, def, pr, blockseed, rot) + if not def then return end + if not rot then rot = "random" end + local log_enabled = logging and not def.terrain_feature + local y_offset = 0 + if type(def.y_offset) == "function" then + y_offset = def.y_offset(pr) + elseif def.y_offset then + y_offset = def.y_offset + end + local pp = vector.offset(pos,0,y_offset,0) + if def.solid_ground and def.sidelen then + local ground_p1 = vector.offset(pos,-def.sidelen/2,-1,-def.sidelen/2) + local ground_p2 = vector.offset(pos,def.sidelen/2,-1,def.sidelen/2) + + local solid = minetest.find_nodes_in_area(ground_p1,ground_p2,{"group:solid"}) + if #solid < ( def.sidelen * def.sidelen ) then + if def.make_foundation then + foundation(vector.offset(pos,-def.sidelen/2 - 3,-1,-def.sidelen/2 - 3),vector.offset(pos,def.sidelen/2 + 3,-1,def.sidelen/2 + 3),pos,def.sidelen) + else + if log_enabled then + minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. No solid ground.") + end + return false + end + end + end + if def.on_place and not def.on_place(pos,def,pr,blockseed) then + if log_enabled then + minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. Conditions not satisfied.") + end + return false + end + if def.filenames then + if #def.filenames <= 0 then return false end + local r = pr:next(1,#def.filenames) + local file = def.filenames[r] + if file then + local rot = rotations[pr:next(1,#rotations)] + local ap = function(pos,def,pr,blockseed) end + + if def.daughters then + ap = function(pos,def,pr,blockseed) + for _,d in pairs(def.daughters) do + local p = vector.add(pos,d.pos) + local rot = d.rot or 0 + mcl_structures.place_schematic(p, d.files[pr:next(1,#d.files)], rot, nil, true, "place_center_x,place_center_z",function() + if def.loot then generate_loot(pp,def,pr,blockseed) end + if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end + if def.after_place then + def.after_place(pos,def,pr) + end + end,pr) + end + end + elseif def.after_place then + ap = def.after_place + end + mcl_structures.place_schematic(pp, file, rot, def.replacements, true, "place_center_x,place_center_z",function(p1, p2, size, rotation) + if not def.daughters then + if def.loot then generate_loot(pp,def,pr,blockseed) end + if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end + end + return ap(pp,def,pr,blockseed,p1,p2,size,rotation) + end,pr) + if log_enabled then + minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) + end + return true + end + elseif def.place_func and def.place_func(pp,def,pr,blockseed) then + if not def.after_place or ( def.after_place and def.after_place(pp,def,pr,blockseed) ) then + if def.loot then generate_loot(pp,def,pr,blockseed) end + if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end + if log_enabled then + minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) + end + return true + end + end + if log_enabled then + minetest.log("warning","[mcl_structures] placing "..def.name.." failed at "..minetest.pos_to_string(pos)) + end +end + +function mcl_structures.register_structure(name,def,nospawn) --nospawn means it will be placed by another (non-nospawn) structure that contains it's structblock i.e. it will not be placed by mapgen directly + if mcl_structures.is_disabled(name) then return end + local structblock = "mcl_structures:structblock_"..name + local flags = "place_center_x, place_center_z, force_placement" + local y_offset = 0 + local sbgroups = { structblock = 1, not_in_creative_inventory=1 } + if def.flags then flags = def.flags end + def.name = name + if nospawn then + sbgroups.structblock = nil + sbgroups.structblock_lbm = 1 + else + if def.place_on then + minetest.register_on_mods_loaded(function() --make sure all previous decorations and biomes have been registered + def.deco = minetest.register_decoration({ + name = "mcl_structures:deco_"..name, + decoration = structblock, + deco_type = "simple", + place_on = def.place_on, + spawn_by = def.spawn_by, + num_spawn_by = def.num_spawn_by, + sidelen = 80, + fill_ratio = def.fill_ratio, + noise_params = def.noise_params, + flags = flags, + biomes = def.biomes, + y_max = def.y_max, + y_min = def.y_min + }) + minetest.register_node(":"..structblock, {drawtype="airlike", walkable = false, pointable = false,groups = sbgroups,sunlight_propagates = true,}) + def.structblock = structblock + def.deco_id = minetest.get_decoration_id("mcl_structures:deco_"..name) + minetest.set_gen_notify({decoration=true}, { def.deco_id }) + --catching of gennotify happens in mcl_mapgen_core + + end) + end + end + mcl_structures.registered_structures[name] = def +end + +local structure_spawns = {} +function mcl_structures.register_structure_spawn(def) + --name,y_min,y_max,spawnon,biomes,chance,interval,limit + minetest.register_abm({ + label = "Spawn "..def.name, + nodenames = def.spawnon, + min_y = def.y_min or -31000, + max_y = def.y_max or 31000, + interval = def.interval or 60, + chance = def.chance or 5, + action = function(pos, node, active_object_count, active_object_count_wider) + local limit = def.limit or 7 + if active_object_count_wider > limit + mob_cap_animal then return end + if active_object_count_wider > mob_cap_player then return end + local p = vector.offset(pos,0,1,0) + if minetest.get_node(p).name ~= "air" then return end + if minetest.get_meta(pos):get_string("spawnblock") == "" then return end + if mg_name ~= "v6" and mg_name ~= "singlenode" and def.biomes then + if table.indexof(def.biomes,minetest.get_biome_name(minetest.get_biome_data(p).biome)) == -1 then + return + end + end + local mobdef = minetest.registered_entities[def.name] + if mobdef.can_spawn and not mobdef.can_spawn(p) then return end + minetest.add_entity(p,def.name) + end, + }) +end + +--lbm for secondary structures (structblock included in base structure) +minetest.register_lbm({ + name = "mcl_structures:struct_lbm", + run_at_every_load = true, + nodenames = {"group:structblock_lbm"}, + action = function(pos, node) + minetest.remove_node(pos) + local name = node.name:gsub("mcl_structures:structblock_","") + local def = mcl_structures.registered_structures[name] + if not def then return end + mcl_structures.place_structure(pos) + end +}) diff --git a/mods/MAPGEN/mcl_structures/desert_temple.lua b/mods/MAPGEN/mcl_structures/desert_temple.lua new file mode 100644 index 000000000..75c170ab1 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/desert_temple.lua @@ -0,0 +1,86 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +local function temple_placement_callback(pos,def, pr) + local hl = def.sidelen / 2 + local p1 = vector.offset(pos,-hl,-hl,-hl) + local p2 = vector.offset(pos,hl,hl,hl) + -- Delete cacti leftovers: + local cactus_nodes = minetest.find_nodes_in_area_under_air(p1, p2, "mcl_core:cactus") + if cactus_nodes and #cactus_nodes > 0 then + for _, pos in pairs(cactus_nodes) do + local node_below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) + if node_below and node_below.name == "mcl_core:sandstone" then + minetest.swap_node(pos, {name="air"}) + end + end + end + + -- Initialize pressure plates and randomly remove up to 5 plates + local pplates = minetest.find_nodes_in_area(p1, p2, "mesecons_pressureplates:pressure_plate_stone_off") + local pplates_remove = 5 + for p=1, #pplates do + if pplates_remove > 0 and pr:next(1, 100) >= 50 then + -- Remove plate + minetest.remove_node(pplates[p]) + pplates_remove = pplates_remove - 1 + else + -- Initialize plate + minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p]) + end + end +end + +mcl_structures.register_structure("desert_temple",{ + place_on = {"group:sand"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + make_foundation = true, + sidelen = 18, + y_offset = -12, + chunk_probability = 300, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + biomes = { "Desert" }, + filenames = { modpath.."/schematics/mcl_structures_desert_temple.mts" }, + after_place = temple_placement_callback, + loot = { + ["mcl_chests:chest" ] ={ + { + stacks_min = 2, + stacks_max = 4, + items = { + { itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 }, + { itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 }, + { itemstring = "mcl_books:book", weight = 20, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_mobitems:saddle", weight = 20, }, + { itemstring = "mcl_core:apple_gold", weight = 20, }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 3 }, + { itemstring = "", weight = 15, }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 15, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 10, }, + { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 5, }, + { itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }, + { + stacks_min = 4, + stacks_max = 4, + items = { + { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_core:sand", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, + } + }} + } +}) diff --git a/mods/MAPGEN/mcl_structures/end_city.lua b/mods/MAPGEN/mcl_structures/end_city.lua new file mode 100644 index 000000000..5f432a0eb --- /dev/null +++ b/mods/MAPGEN/mcl_structures/end_city.lua @@ -0,0 +1,144 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +local spawnon = {"mcl_end:purpur_block"} + +local function spawn_shulkers(pos,def,pr) + local p1 = vector.offset(pos,-def.sidelen/2,-1,-def.sidelen/2) + local p2 = vector.offset(pos,def.sidelen/2,def.sidelen,def.sidelen/2) + mcl_structures.spawn_mobs("mobs_mc:shulker",spawnon,p1,p2,pr,1) + + local guard = minetest.find_node_near(pos,def.sidelen,{"mcl_itemframes:item_frame"}) + if guard then + minetest.add_entity(vector.offset(guard,0,-1.5,0),"mobs_mc:shulker") + end +end + +mcl_structures.register_structure("end_shipwreck",{ + place_on = {"mcl_end:end_stone"}, + fill_ratio = 0.001, + flags = "place_center_x, place_center_z, all_floors", + y_offset = function(pr) return pr:next(-50,-20) end, + chunk_probability = 800, + --y_max = mcl_vars.mg_end_max, + --y_min = mcl_vars.mg_end_min -100, + biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" }, + sidelen = 32, + filenames = { + modpath.."/schematics/mcl_structures_end_shipwreck_1.mts", + }, + construct_nodes = {"mcl_chests:ender_chest_small","mcl_chests:ender_chest","mcl_brewing:stand_000","mcl_chests:violet_shulker_box_small"}, + after_place = function(pos,def,pr) + local fr = minetest.find_node_near(pos,def.sidelen,{"mcl_itemframes:item_frame"}) + if fr then + if mcl_itemframes then + mcl_itemframes.update_item_entity(fr,minetest.get_node(fr)) + end + end + return spawn_shulkers(pos,def,pr) + end, + loot = { + [ "mcl_itemframes:item_frame" ] ={{ + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_armor:elytra", weight = 100 }, + }, + }}, + [ "mcl_chests:chest_small" ] ={{ + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 }, + { itemstring = "mcl_farming:beetroot_seeds", weight = 16, amount_min = 1, amount_max=10 }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + --{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 }, + { itemstring = "mcl_core:diamond", weight = 3, amount_min = 2, amount_max = 7 }, + { itemstring = "mcl_mobitems:saddle", weight = 3, }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_tools:pick_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:shovel_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:sword_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:pick_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:shovel_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:sword_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }} + } +}) + +mcl_structures.register_structure("end_boat",{ + place_on = {"mcl_end:end_stone"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z, all_floors", + y_offset = function(pr) return pr:next(15,30) end, + chunk_probability = 900, + --y_max = mcl_vars.mg_end_max, + --y_min = mcl_vars.mg_end_min -100, + biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" }, + sidelen = 20, + filenames = { + modpath.."/schematics/mcl_structures_end_boat.mts", + }, + after_place = spawn_shulkers, + construct_nodes = {"mcl_chests:ender_chest_small","mcl_chests:ender_chest","mcl_brewing:stand_000","mcl_chests:violet_shulker_box_small"}, + loot = { + [ "mcl_chests:chest_small" ] ={{ + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 }, + { itemstring = "mcl_farming:beetroot_seeds", weight = 16, amount_min = 1, amount_max=10 }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 }, + { itemstring = "mcl_core:diamond", weight = 3, amount_min = 2, amount_max = 7 }, + { itemstring = "mcl_mobitems:saddle", weight = 3, }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_tools:pick_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:shovel_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:sword_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:pick_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:shovel_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }} + } +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:shulker", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max, + chance = 10, + interval = 60, + limit = 6, + spawnon = spawnon, +}) diff --git a/mods/MAPGEN/mcl_structures/end_spawn.lua b/mods/MAPGEN/mcl_structures/end_spawn.lua new file mode 100644 index 000000000..5769ac487 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/end_spawn.lua @@ -0,0 +1,123 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + + +mcl_structures.register_structure("end_spawn_obsidian_platform",{ + static_pos ={mcl_vars.mg_end_platform_pos}, + place_func = function(pos,def,pr) + local obby = minetest.find_nodes_in_area(vector.offset(pos,-2,0,-2),vector.offset(pos,2,0,2),{"air","mcl_end:end_stone"}) + local air = minetest.find_nodes_in_area(vector.offset(pos,-2,1,-2),vector.offset(pos,2,3,2),{"air","mcl_end:end_stone"}) + minetest.bulk_set_node(obby,{name="mcl_core:obsidian"}) + minetest.bulk_set_node(air,{name="air"}) + return true + end, +}) + +mcl_structures.register_structure("end_exit_portal",{ + static_pos = { mcl_vars.mg_end_exit_portal_pos }, + filenames = { + modpath.."/schematics/mcl_structures_end_exit_portal.mts" + }, + after_place = function(pos,def,pr,blockseed) + if minetest.settings:get_bool("only_peaceful_mobs", false) then + return + end + local p1 = vector.offset(pos,-16,-16,-16) + local p2 = vector.offset(pos,16,21,16) + minetest.emerge_area(p1,p2,function(blockpos, action, calls_remaining, param) + if calls_remaining > 0 then return end + minetest.bulk_set_node(minetest.find_nodes_in_area(p1,p2,{"mcl_portals:portal_end"}),{name="air"}) + local obj = minetest.add_entity(vector.offset(pos,3, 11, 3), "mobs_mc:enderdragon") + if obj then + local dragon_entity = obj:get_luaentity() + dragon_entity._portal_pos = pos + if blockseed ~= -1 then + dragon_entity._initial = true + end + else + minetest.log("error", "[mcl_mapgen_core] ERROR! Ender dragon doesn't want to spawn") + end + minetest.fix_light(p1,p2) + end) + end +}) +mcl_structures.register_structure("end_exit_portal_open",{ + filenames = { + modpath.."/schematics/mcl_structures_end_exit_portal.mts" + }, + after_place = function(pos,def,pr) + local p1 = vector.offset(pos,-16,-16,-16) + local p2 = vector.offset(pos,16,16,16) + minetest.fix_light(p1,p2) + end +}) +mcl_structures.register_structure("end_gateway_portal",{ + filenames = { + modpath.."/schematics/mcl_structures_end_gateway_portal.mts" + }, +}) + +local function get_tower(p,h,tbl) + for i = 1,h do + table.insert(tbl,vector.offset(p,0,i,0)) + end +end + +local function make_endspike(pos,width,height) + local nn = minetest.find_nodes_in_area(vector.offset(pos,-width/2,0,-width/2),vector.offset(pos,width/2,0,width/2),{"air","group:solid"}) + table.sort(nn,function(a, b) + return vector.distance(pos, a) < vector.distance(pos, b) + end) + local nodes = {} + for i = 1,math.ceil(#nn*0.55) do + get_tower(nn[i],height,nodes) + end + minetest.bulk_set_node(nodes,{ name="mcl_core:obsidian"} ) + return vector.offset(pos,0,height,0) +end + +function make_cage(pos,width) + local nodes = {} + local nodes2 = {} + local r = math.max(1,math.floor(width/2) - 2) + for x=-r,r do for y = 0,width do for z = -r,r do + if x == r or x == -r or z==r or z == -r then + table.insert(nodes,vector.add(pos,vector.new(x,y,z))) + end + end end end + if xpanes then + minetest.bulk_set_node(nodes,{ name="xpanes:bar_flat"} ) + for _,p in pairs(nodes) do + xpanes.update_pane(p) + end + end +end + +local function get_points_on_circle(pos,r,n) + local rt = {} + for i=1, n do + table.insert(rt,vector.offset(pos,r * math.cos(((i-1)/n) * (2*math.pi)),0, r* math.sin(((i-1)/n) * (2*math.pi)) )) + end + return rt +end + +mcl_structures.register_structure("end_spike",{ + static_pos =get_points_on_circle(vector.offset(mcl_vars.mg_end_exit_portal_pos,0,-20,0),43,10), + place_func = function(pos,def,pr) + local d = pr:next(6,12) + local h = d * pr:next(4,6) + local p1 = vector.offset(pos, -d / 2, 0, -d / 2) + local p2 = vector.offset(pos, d / 2, h + d, d / 2) + minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param) + if calls_remaining ~= 0 then return end + local s = make_endspike(pos,d,h) + minetest.set_node(vector.offset(s,0,1,0),{name="mcl_core:bedrock"}) + minetest.add_entity(vector.offset(s,0,2,0),"mcl_end:crystal") + if pr:next(1,3) == 1 then + make_cage(vector.offset(s,0,1,0),d) + end + end) + return true + end, +}) diff --git a/mods/MAPGEN/mcl_structures/geode.lua b/mods/MAPGEN/mcl_structures/geode.lua new file mode 100644 index 000000000..95f9b0e81 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/geode.lua @@ -0,0 +1,88 @@ +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), + vector.new(0,1,0), + vector.new(0,-1,0) +} + +local function set_node_no_bedrock(pos,node) + local n = minetest.get_node(pos) + if n.name == "mcl_core:bedrock" then return end + return minetest.set_node(pos,node) +end + +local function makegeode(pos,def,pr) + local size = pr:next(5,7) + local p1 = vector.offset(pos,-size,-size,-size) + local p2 = vector.offset(pos,size,size,size) + minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param) + if calls_remaining ~= 0 then return end + local calcite = {} + local nn = minetest.find_nodes_in_area(p1,p2,{"group:material_stone","group:dirt","mcl_core:gravel"}) + table.sort(nn,function(a, b) + return vector.distance(pos, a) < vector.distance(pos, b) + end) + if not nn[1] then return end + + for i=1,pr:next(1,math.max(2,#nn - math.ceil(#nn/5) )) do + set_node_no_bedrock(nn[i],{name="mcl_amethyst:amethyst_block"}) + end + + for k,v in pairs(minetest.find_nodes_in_area(p1,p2,{"mcl_amethyst:amethyst_block"})) do + local all_amethyst = true + for kk,vv in pairs(adjacents) do + local pp = vector.add(v,vv) + local an = minetest.get_node(pp) + if an.name ~= "mcl_amethyst:amethyst_block" then + if minetest.get_item_group(an.name,"material_stone") > 0 then + set_node_no_bedrock(pp,{name="mcl_amethyst:calcite"}) + table.insert(calcite,pp) + if pr:next(1,5) == 1 then + set_node_no_bedrock(v,{name="mcl_amethyst:budding_amethyst_block"}) + end + all_amethyst = false + elseif an.name ~= "mcl_amethyst:amethyst_block" and an.name ~= "air" and an.name ~= "mcl_amethyst:budding_amethyst_block" then + all_amethyst = false + end + end + end + if all_amethyst then set_node_no_bedrock(v,{name="air"}) end + end + + for _,v in pairs(calcite) do + for _,vv in pairs(minetest.find_nodes_in_area(vector.offset(v,-1,-1,-1),vector.offset(v,1,1,1),{"group:material_stone"})) do + set_node_no_bedrock(vv,{name="mcl_blackstone:basalt_smooth"}) + end + end + + for k,v in pairs(minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_amethyst:amethyst_block","mcl_amethyst:budding_amethyst_block"})) do + local r = pr:next(1,50) + if r < 10 then + set_node_no_bedrock(vector.offset(v,0,1,0),{name="mcl_amethyst:amethyst_cluster",param2=1}) + end + end + return true + end) + return true +end + +mcl_structures.register_structure("geode",{ + place_on = {"group:material_stone"}, + noise_params = { + offset = 0, + scale = 0.00022, + spread = {x = 250, y = 250, z = 250}, + seed = 7894353, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "force_placement", + terrain_feature = true, + y_max = -24, + y_min = mcl_vars.mg_overworld_min, + y_offset = function(pr) return pr:next(-4,-2) end, + place_func = makegeode, +}) diff --git a/mods/MAPGEN/mcl_structures/igloo.lua b/mods/MAPGEN/mcl_structures/igloo.lua new file mode 100644 index 000000000..0fd8c6217 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/igloo.lua @@ -0,0 +1,180 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +function mcl_structures.generate_igloo_top(pos, pr) + -- Furnace does ot work atm because apparently meta is not set. Need a bit of help with fixing this for furnaces, bookshelves, and brewing stands. + local newpos = {x=pos.x,y=pos.y-2,z=pos.z} + local path = modpath.."/schematics/mcl_structures_igloo_top.mts" + local rotation = tostring(pr:next(0,3)*90) + return mcl_structures.place_schematic(newpos, path, rotation, nil, true, nil, function() + local p1 = vector.offset(pos,-5,-5,-5) + local p2 = vector.offset(pos,5,5,5) + mcl_structures.construct_nodes(p1,p2,{"mcl_furnaces:furnace","mcl_books:bookshelf"}) + end), rotation +end + +local function spawn_mobs(p1,p2,vi,zv) + local mc = minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_core:stonebrickmossy"}) + if #mc == 2 then + local vp = mc[1] + local zp = mc[2] + if not vi and zv and zv:get_pos() and vector.distance(mc[1],zv:get_pos()) < 2 then + vp = mc[2] + elseif not zv and vi and vi:get_pos() and vector.distance(mc[2],vi:get_pos()) < 2 then + zp = mc[1] + elseif zv and vi then + return + end + vi = minetest.add_entity(vector.offset(mc[1],0,1,0),"mobs_mc:villager") + zv = minetest.add_entity(vector.offset(mc[2],0,1,0),"mobs_mc:villager_zombie") + minetest.after(1,spawn_mobs,p1,p2,vi,zv) + end +end + +function mcl_structures.generate_igloo_basement(pos, orientation, loot, pr) + -- TODO: Add monster eggs + local path = modpath.."/schematics/mcl_structures_igloo_basement.mts" + mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, function() + local p1 = vector.offset(pos,-5,-5,-5) + local p2 = vector.offset(pos,5,5,5) + mcl_structures.fill_chests(p1,p2,loot,pr) + mcl_structures.construct_nodes(p1,p2,{"mcl_brewing:stand_000","mcl_books:bookshelf"}) + spawn_mobs(p1,p2) + end, pr) +end + +function mcl_structures.generate_igloo(pos, def, pr) + -- Place igloo + local success, rotation = mcl_structures.generate_igloo_top(pos, pr) + -- Place igloo basement with 50% chance + local r = pr:next(1,2) + if r == 1 then + -- Select basement depth + local dim = mcl_worlds.pos_to_dimension(pos) + --local buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) + local buffer + if dim == "nether" then + buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10) + elseif dim == "end" then + buffer = pos.y - (mcl_vars.mg_end_min + 1) + elseif dim == "overworld" then + buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) + else + return success + end + if buffer <= 19 then + return success + end + local depth = pr:next(19, buffer) + local bpos = {x=pos.x, y=pos.y-depth, z=pos.z} + -- trapdoor position + local tpos + local dir, tdir + if rotation == "0" then + dir = {x=-1, y=0, z=0} + tdir = {x=1, y=0, z=0} + tpos = {x=pos.x+7, y=pos.y-2, z=pos.z+3} + elseif rotation == "90" then + dir = {x=0, y=0, z=-1} + tdir = {x=0, y=0, z=-1} + tpos = {x=pos.x+3, y=pos.y-2, z=pos.z+1} + elseif rotation == "180" then + dir = {x=1, y=0, z=0} + tdir = {x=-1, y=0, z=0} + tpos = {x=pos.x+1, y=pos.y-2, z=pos.z+3} + elseif rotation == "270" then + dir = {x=0, y=0, z=1} + tdir = {x=0, y=0, z=1} + tpos = {x=pos.x+3, y=pos.y-2, z=pos.z+7} + else + return success + end + local function set_brick(pos) + local c = pr:next(1, 3) -- cracked chance + local m = pr:next(1, 10) -- chance for monster egg + local brick + if m == 1 then + if c == 1 then + brick = "mcl_monster_eggs:monster_egg_stonebrickcracked" + else + brick = "mcl_monster_eggs:monster_egg_stonebrick" + end + else + if c == 1 then + brick = "mcl_core:stonebrickcracked" + else + brick = "mcl_core:stonebrick" + end + end + minetest.set_node(pos, {name=brick}) + end + local ladder_param2 = minetest.dir_to_wallmounted(tdir) + local real_depth = 0 + -- Check how deep we can actuall dig + for y=1, depth-5 do + real_depth = real_depth + 1 + local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z}) + local def = minetest.registered_nodes[node.name] + if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then + bpos.y = tpos.y-y+1 + break + end + end + if real_depth <= 6 then + return success + end + -- Generate ladder to basement + for y=1, real_depth-1 do + set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z }) + set_brick({x=tpos.x+1,y=tpos.y-y,z=tpos.z }) + set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z-1}) + set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z+1}) + minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2}) + end + -- Place basement + mcl_structures.generate_igloo_basement(bpos, rotation, def.loot, pr) + -- Place hidden trapdoor + minetest.after(5, function(tpos, dir) + minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2 + end, tpos, dir) + end + return success +end + +mcl_structures.register_structure("igloo",{ + place_on = {"mcl_core:snowblock","mcl_core:snow","group:grass_block_snow"}, + fill_ratio = 0.01, + sidelen = 16, + chunk_probability = 250, + solid_ground = true, + make_foundation = true, + y_max = mcl_vars.mg_overworld_max, + y_min = 0, + y_offset = 0, + biomes = { "ColdTaiga", "IcePlainsSpikes", "IcePlains" }, + place_func = mcl_structures.generate_igloo, + loot = { + ["mcl_chests:chest_small"] = {{ + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_core:apple_gold", weight = 1 }, + } + }, + { + stacks_min = 2, + stacks_max = 8, + items = { + { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 }, + { itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, + { itemstring = "mcl_tools:axe_stone", weight = 2 }, + { itemstring = "mcl_core:emerald", weight = 1 }, + { itemstring = "mcl_core:apple_gold", weight = 1 }, + } + }}, + } +}) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 5d3ecac6c..cd5691fca 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -4,559 +4,78 @@ local modpath = minetest.get_modpath(modname) mcl_structures = {} -local rotations = { - "0", - "90", - "180", - "270" -} +dofile(modpath.."/api.lua") +dofile(modpath.."/shipwrecks.lua") +dofile(modpath.."/desert_temple.lua") +dofile(modpath.."/jungle_temple.lua") +dofile(modpath.."/ocean_ruins.lua") +dofile(modpath.."/witch_hut.lua") +dofile(modpath.."/igloo.lua") +dofile(modpath.."/woodland_mansion.lua") +dofile(modpath.."/ruined_portal.lua") +dofile(modpath.."/geode.lua") +dofile(modpath.."/pillager_outpost.lua") +dofile(modpath.."/end_spawn.lua") +dofile(modpath.."/end_city.lua") -local function ecb_place(blockpos, action, calls_remaining, param) - if calls_remaining >= 1 then return end - minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) - if param.after_placement_callback and param.p1 and param.p2 then - param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param) - end -end -function mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) - local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic")() - if s and s.size then - local x, z = s.size.x, s.size.z - if rotation then - if rotation == "random" and pr then - rotation = rotations[pr:next(1,#rotations)] - end - if rotation == "random" then - x = math.max(x, z) - z = x - elseif rotation == "90" or rotation == "270" then - x, z = z, x - end - end - local p1 = {x=pos.x , y=pos.y , z=pos.z } - local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} - minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) - local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} - minetest.emerge_area(p1, p2, ecb_place, param) - end -end +mcl_structures.register_structure("desert_well",{ + place_on = {"group:sand"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + not_near = { "desert_temple_new" }, + solid_ground = true, + sidelen = 4, + chunk_probability = 600, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + y_offset = -2, + biomes = { "Desert" }, + filenames = { modpath.."/schematics/mcl_structures_desert_well.mts" }, +}) -function mcl_structures.get_struct(file) - local localfile = modpath.."/schematics/"..file - local file, errorload = io.open(localfile, "rb") - if errorload then - minetest.log("error", "[mcl_structures] Could not open this struct: "..localfile) - return nil - end - - local allnode = file:read("*a") - file:close() - - return allnode -end - --- Call on_construct on pos. --- Useful to init chests from formspec. -local function init_node_construct(pos) - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - if def and def.on_construct then - def.on_construct(pos) - return true - end - return false -end - --- The call of Struct -function mcl_structures.call_struct(pos, struct_style, rotation, pr) - minetest.log("action","[mcl_structures] call_struct " .. struct_style.." at "..minetest.pos_to_string(pos)) - if not rotation then - rotation = "random" - end - if struct_style == "desert_temple" then - return mcl_structures.generate_desert_temple(pos, rotation, pr) - elseif struct_style == "desert_well" then - return mcl_structures.generate_desert_well(pos, rotation) - elseif struct_style == "igloo" then - return mcl_structures.generate_igloo(pos, rotation, pr) - elseif struct_style == "witch_hut" then - return mcl_structures.generate_witch_hut(pos, rotation) - elseif struct_style == "ice_spike_small" then - return mcl_structures.generate_ice_spike_small(pos, rotation) - elseif struct_style == "ice_spike_large" then - return mcl_structures.generate_ice_spike_large(pos, rotation) - elseif struct_style == "boulder" then - return mcl_structures.generate_boulder(pos, rotation, pr) - elseif struct_style == "fossil" then - return mcl_structures.generate_fossil(pos, rotation, pr) - elseif struct_style == "end_exit_portal" then - return mcl_structures.generate_end_exit_portal(pos, rotation) - elseif struct_style == "end_exit_portal_open" then - return mcl_structures.generate_end_exit_portal_open(pos, rotation) - elseif struct_style == "end_gateway_portal" then - return mcl_structures.generate_end_gateway_portal(pos, rotation) - elseif struct_style == "end_portal_shrine" then - return mcl_structures.generate_end_portal_shrine(pos, rotation, pr) - end -end - -function mcl_structures.generate_desert_well(pos, rot) - local newpos = {x=pos.x,y=pos.y-2,z=pos.z} - local path = modpath.."/schematics/mcl_structures_desert_well.mts" - return mcl_structures.place_schematic(newpos, path, rot or "0", nil, true) -end - -function mcl_structures.generate_igloo(pos, rotation, pr) - -- Place igloo - local success, rotation = mcl_structures.generate_igloo_top(pos, pr) - -- Place igloo basement with 50% chance - local r = pr:next(1,2) - if r == 1 then - -- Select basement depth - local dim = mcl_worlds.pos_to_dimension(pos) - --local buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) - local buffer - if dim == "nether" then - buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10) - elseif dim == "end" then - buffer = pos.y - (mcl_vars.mg_end_min + 1) - elseif dim == "overworld" then - buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) - else - return success - end - if buffer <= 19 then - return success - end - local depth = pr:next(19, buffer) - local bpos = {x=pos.x, y=pos.y-depth, z=pos.z} - -- trapdoor position - local tpos - local dir, tdir - if rotation == "0" then - dir = {x=-1, y=0, z=0} - tdir = {x=1, y=0, z=0} - tpos = {x=pos.x+7, y=pos.y-1, z=pos.z+3} - elseif rotation == "90" then - dir = {x=0, y=0, z=-1} - tdir = {x=0, y=0, z=-1} - tpos = {x=pos.x+3, y=pos.y-1, z=pos.z+1} - elseif rotation == "180" then - dir = {x=1, y=0, z=0} - tdir = {x=-1, y=0, z=0} - tpos = {x=pos.x+1, y=pos.y-1, z=pos.z+3} - elseif rotation == "270" then - dir = {x=0, y=0, z=1} - tdir = {x=0, y=0, z=1} - tpos = {x=pos.x+3, y=pos.y-1, z=pos.z+7} - else - return success - end - local function set_brick(pos) - local c = pr:next(1, 3) -- cracked chance - local m = pr:next(1, 10) -- chance for monster egg - local brick - if m == 1 then - if c == 1 then - brick = "mcl_monster_eggs:monster_egg_stonebrickcracked" - else - brick = "mcl_monster_eggs:monster_egg_stonebrick" - end - else - if c == 1 then - brick = "mcl_core:stonebrickcracked" - else - brick = "mcl_core:stonebrick" - end - end - minetest.set_node(pos, {name=brick}) - end - local ladder_param2 = minetest.dir_to_wallmounted(tdir) - local real_depth = 0 - -- Check how deep we can actuall dig - for y=1, depth-5 do - real_depth = real_depth + 1 - local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z}) - local def = minetest.registered_nodes[node.name] - if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then - bpos.y = tpos.y-y+1 - break - end - end - if real_depth <= 6 then - return success - end - -- Generate ladder to basement - for y=1, real_depth-1 do - set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z }) - set_brick({x=tpos.x+1,y=tpos.y-y,z=tpos.z }) - set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z-1}) - set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z+1}) - minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2}) - end - -- Place basement - mcl_structures.generate_igloo_basement(bpos, rotation, 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 - -function mcl_structures.generate_igloo_top(pos, pr) - -- FIXME: This spawns bookshelf instead of furnace. Fix this! - -- Furnace does ot work atm because apparently meta is not set. :-( - local newpos = {x=pos.x,y=pos.y-1,z=pos.z} - local path = modpath.."/schematics/mcl_structures_igloo_top.mts" - local rotation = tostring(pr:next(0,3)*90) - return mcl_structures.place_schematic(newpos, path, rotation, nil, true), rotation -end - -local function igloo_placement_callback(p1, p2, size, orientation, pr) - local chest_offset - if orientation == "0" then - chest_offset = {x=5, y=1, z=5} - elseif orientation == "90" then - chest_offset = {x=5, y=1, z=3} - elseif orientation == "180" then - chest_offset = {x=3, y=1, z=1} - elseif orientation == "270" then - chest_offset = {x=1, y=1, z=5} - else - return - end - --local size = {x=9,y=5,z=7} - local lootitems = mcl_loot.get_multi_loot({ - { - stacks_min = 1, - stacks_max = 1, - items = { - { itemstring = "mcl_core:apple_gold", weight = 1 }, - } +mcl_structures.register_structure("fossil",{ + place_on = {"group:material_stone","group:sand"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + sidelen = 13, + chunk_probability = 1000, + y_offset = function(pr) return ( pr:next(1,16) * -1 ) -16 end, + y_max = 15, + y_min = mcl_vars.mg_overworld_min + 35, + biomes = { "Desert" }, + filenames = { + modpath.."/schematics/mcl_structures_fossil_skull_1.mts", -- 4×5×5 + modpath.."/schematics/mcl_structures_fossil_skull_2.mts", -- 5×5×5 + modpath.."/schematics/mcl_structures_fossil_skull_3.mts", -- 5×5×7 + modpath.."/schematics/mcl_structures_fossil_skull_4.mts", -- 7×5×5 + modpath.."/schematics/mcl_structures_fossil_spine_1.mts", -- 3×3×13 + modpath.."/schematics/mcl_structures_fossil_spine_2.mts", -- 5×4×13 + modpath.."/schematics/mcl_structures_fossil_spine_3.mts", -- 7×4×13 + modpath.."/schematics/mcl_structures_fossil_spine_4.mts", -- 8×5×13 }, - { - stacks_min = 2, - stacks_max = 8, - items = { - { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 }, - { itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 }, - { itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, - { itemstring = "mcl_tools:axe_stone", weight = 2 }, - { itemstring = "mcl_core:emerald", weight = 1 }, - } - }}, pr) +}) - local chest_pos = vector.add(p1, chest_offset) - init_node_construct(chest_pos) - local meta = minetest.get_meta(chest_pos) - local inv = meta:get_inventory() - mcl_loot.fill_inventory(inv, "main", lootitems, pr) -end +mcl_structures.register_structure("boulder",{ + filenames = { + modpath.."/schematics/mcl_structures_boulder_small.mts", + modpath.."/schematics/mcl_structures_boulder_small.mts", + modpath.."/schematics/mcl_structures_boulder_small.mts", + modpath.."/schematics/mcl_structures_boulder.mts", + -- small boulder 3x as likely + }, +},true) --is spawned as a normal decoration. this is just for /spawnstruct -function mcl_structures.generate_igloo_basement(pos, orientation, pr) - -- TODO: Add brewing stand - -- TODO: Add monster eggs - -- TODO: Spawn villager and zombie villager - local path = modpath.."/schematics/mcl_structures_igloo_basement.mts" - mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, igloo_placement_callback, pr) -end - -function mcl_structures.generate_boulder(pos, rotation, pr) - -- Choose between 2 boulder sizes (2×2×2 or 3×3×3) - local r = pr:next(1, 10) - local path - if r <= 3 then - path = modpath.."/schematics/mcl_structures_boulder_small.mts" - else - path = modpath.."/schematics/mcl_structures_boulder.mts" - end - - local newpos = {x=pos.x,y=pos.y-1,z=pos.z} - - return minetest.place_schematic(newpos, path, rotation) -- don't serialize schematics for registered biome decorations, for MT 5.4.0, https://github.com/minetest/minetest/issues/10995 -end - -local function spawn_witch(p1,p2) - local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"}) - if c then - local nn = minetest.find_nodes_in_area_under_air(vector.new(p1.x,c.y-1,p1.z),vector.new(p2.x,c.y-1,p2.z),{"mcl_core:sprucewood"}) - local witch = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:witch"):get_luaentity() - local cat = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:cat"):get_luaentity() - witch._home = c - witch.can_despawn = false - cat.object:set_properties({textures = {"mobs_mc_cat_black.png"}}) - cat.owner = "!witch!" --so it's not claimable by player - cat._home = c - cat.can_despawn = false - return - end -end - -local function hut_placement_callback(p1, p2, size, orientation, pr) - if not p1 or not p2 then return end - local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree") - for i = 1, #legs do - while minetest.get_item_group(mcl_vars.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do - legs[i].y = legs[i].y - 1 - minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2}) - end - end - spawn_witch(p1,p2) -end - -function mcl_structures.generate_witch_hut(pos, rotation, pr) - 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 = 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 = 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 - -function mcl_structures.generate_fossil(pos, rotation, pr) - -- Generates one out of 8 possible fossil pieces - local newpos = {x=pos.x,y=pos.y-1,z=pos.z} - local fossils = { - "mcl_structures_fossil_skull_1.mts", -- 4×5×5 - "mcl_structures_fossil_skull_2.mts", -- 5×5×5 - "mcl_structures_fossil_skull_3.mts", -- 5×5×7 - "mcl_structures_fossil_skull_4.mts", -- 7×5×5 - "mcl_structures_fossil_spine_1.mts", -- 3×3×13 - "mcl_structures_fossil_spine_2.mts", -- 5×4×13 - "mcl_structures_fossil_spine_3.mts", -- 7×4×13 - "mcl_structures_fossil_spine_4.mts", -- 8×5×13 - } - local r = pr:next(1, #fossils) - 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 = 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 = 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 = modpath.."/schematics/mcl_structures_end_gateway_portal.mts" - return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) -end - -local function shrine_placement_callback(p1, p2, size, rotation, pr) - -- Find and setup spawner with silverfish - local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") - for s=1, #spawners do - --local meta = minetest.get_meta(spawners[s]) - mcl_mobspawners.setup_spawner(spawners[s], "mobs_mc:silverfish") - end - - -- Shuffle stone brick types - local bricks = minetest.find_nodes_in_area(p1, p2, "mcl_core:stonebrick") - for b=1, #bricks do - local r_bricktype = pr:next(1, 100) - local r_infested = pr:next(1, 100) - local bricktype - if r_infested <= 5 then - if r_bricktype <= 30 then -- 30% - bricktype = "mcl_monster_eggs:monster_egg_stonebrickmossy" - elseif r_bricktype <= 50 then -- 20% - bricktype = "mcl_monster_eggs:monster_egg_stonebrickcracked" - else -- 50% - bricktype = "mcl_monster_eggs:monster_egg_stonebrick" - end - else - if r_bricktype <= 30 then -- 30% - bricktype = "mcl_core:stonebrickmossy" - elseif r_bricktype <= 50 then -- 20% - bricktype = "mcl_core:stonebrickcracked" - end - -- 50% stonebrick (no change necessary) - end - if bricktype then - minetest.set_node(bricks[b], { name = bricktype }) - end - end - - -- Also replace stairs - local stairs = minetest.find_nodes_in_area(p1, p2, {"mcl_stairs:stair_stonebrick", "mcl_stairs:stair_stonebrick_outer", "mcl_stairs:stair_stonebrick_inner"}) - for s=1, #stairs do - local stair = minetest.get_node(stairs[s]) - local r_type = pr:next(1, 100) - if r_type <= 30 then -- 30% mossy - if stair.name == "mcl_stairs:stair_stonebrick" then - stair.name = "mcl_stairs:stair_stonebrickmossy" - elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then - stair.name = "mcl_stairs:stair_stonebrickmossy_outer" - elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then - stair.name = "mcl_stairs:stair_stonebrickmossy_inner" - end - minetest.set_node(stairs[s], stair) - elseif r_type <= 50 then -- 20% cracky - if stair.name == "mcl_stairs:stair_stonebrick" then - stair.name = "mcl_stairs:stair_stonebrickcracked" - elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then - stair.name = "mcl_stairs:stair_stonebrickcracked_outer" - elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then - stair.name = "mcl_stairs:stair_stonebrickcracked_inner" - end - minetest.set_node(stairs[s], stair) - end - -- 50% no change - end - - -- Randomly add ender eyes into end portal frames, but never fill the entire frame - local frames = minetest.find_nodes_in_area(p1, p2, "mcl_portals:end_portal_frame") - local eyes = 0 - for f=1, #frames do - local r_eye = pr:next(1, 10) - if r_eye == 1 then - eyes = eyes + 1 - if eyes < #frames then - local frame_node = minetest.get_node(frames[f]) - frame_node.name = "mcl_portals:end_portal_frame_eye" - minetest.set_node(frames[f], frame_node) - end - end - end -end - -function mcl_structures.generate_end_portal_shrine(pos, rotation, pr) - local offset = {x=6, y=4, z=6} - --local size = {x=13, y=8, z=13} - local newpos = { x = pos.x - offset.x, y = pos.y, z = pos.z - offset.z } - - 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 - -local function temple_placement_callback(p1, p2, size, rotation, pr) - - -- Delete cacti leftovers: - local cactus_nodes = minetest.find_nodes_in_area_under_air(p1, p2, "mcl_core:cactus") - if cactus_nodes and #cactus_nodes > 0 then - for _, pos in pairs(cactus_nodes) do - local node_below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) - if node_below and node_below.name == "mcl_core:sandstone" then - minetest.swap_node(pos, {name="air"}) - end - end - end - - -- Find chests. - -- FIXME: Searching this large area just for the chets is not efficient. Need a better way to find the chests; - -- probably let's just infer it from newpos because the schematic always the same. - local chests = minetest.find_nodes_in_area(p1, p2, "mcl_chests:chest") - - -- Add desert temple loot into chests - for c=1, #chests do - local lootitems = mcl_loot.get_multi_loot({ - { - stacks_min = 2, - stacks_max = 4, - items = { - { itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 }, - { itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 }, - { itemstring = "mcl_books:book", weight = 20, func = function(stack, pr) - mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) - end }, - { itemstring = "mcl_mobitems:saddle", weight = 20, }, - { itemstring = "mcl_core:apple_gold", weight = 20, }, - { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, - { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 }, - { itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 3 }, - { itemstring = "", weight = 15, }, - { itemstring = "mcl_mobitems:iron_horse_armor", weight = 15, }, - { itemstring = "mcl_mobitems:gold_horse_armor", weight = 10, }, - { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 5, }, - { itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 3 }, - { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, - } - }, - { - stacks_min = 4, - stacks_max = 4, - items = { - { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_core:sand", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, - } - }}, pr) - init_node_construct(chests[c]) - local meta = minetest.get_meta(chests[c]) - local inv = meta:get_inventory() - mcl_loot.fill_inventory(inv, "main", lootitems, pr) - end - - -- Initialize pressure plates and randomly remove up to 5 plates - local pplates = minetest.find_nodes_in_area(p1, p2, "mesecons_pressureplates:pressure_plate_stone_off") - local pplates_remove = 5 - for p=1, #pplates do - if pplates_remove > 0 and pr:next(1, 100) >= 50 then - -- Remove plate - minetest.remove_node(pplates[p]) - pplates_remove = pplates_remove - 1 - else - -- Initialize plate - minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p]) - end - end -end - -function mcl_structures.generate_desert_temple(pos, rotation, pr) - -- No Generating for the temple ... Why using it ? No Change - 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 - return - end - mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true, nil, temple_placement_callback, pr) -end - -local registered_structures = {} - ---[[ Returns a table of structure of the specified type. -Currently the only valid parameter is "stronghold". -Format of return value: -{ - { pos = , generated= }, -- first structure - { pos = , generated= }, -- second structure - -- and so on -} - -TODO: Implement this function for all other structure types as well. -]] -function mcl_structures.get_registered_structures(structure_type) - if registered_structures[structure_type] then - return table.copy(registered_structures[structure_type]) - else - return {} - end -end - --- Register a structures table for the given type. The table format is the same as for --- mcl_structures.get_registered_structures. -function mcl_structures.register_structures(structure_type, structures) - registered_structures[structure_type] = structures -end +mcl_structures.register_structure("ice_spike_small",{ + filenames = { modpath.."/schematics/mcl_structures_ice_spike_small.mts" }, +},true) --is spawned as a normal decoration. this is just for /spawnstruct +mcl_structures.register_structure("ice_spike_large",{ + sidelen = 6, + filenames = { modpath.."/schematics/mcl_structures_ice_spike_large.mts" }, +},true) --is spawned as a normal decoration. this is just for /spawnstruct +-- Debug command local function dir_to_rotation(dir) local ax, az = math.abs(dir.x), math.abs(dir.z) if ax > az then @@ -571,9 +90,8 @@ local function dir_to_rotation(dir) return "0" end --- Debug command minetest.register_chatcommand("spawnstruct", { - params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | nether_portal | dungeon", + params = "dungeon", description = S("Generate a pre-defined structure near your position."), privs = {debug = true}, func = function(name, param) @@ -587,38 +105,18 @@ minetest.register_chatcommand("spawnstruct", { local pr = PseudoRandom(pos.x+pos.y+pos.z) local errord = false local message = S("Structure placed.") - if param == "desert_temple" then - mcl_structures.generate_desert_temple(pos, rot, pr) - elseif param == "desert_well" then - mcl_structures.generate_desert_well(pos, rot) - elseif param == "igloo" then - mcl_structures.generate_igloo(pos, rot, pr) - elseif param == "witch_hut" then - mcl_structures.generate_witch_hut(pos, rot, pr) - elseif param == "boulder" then - mcl_structures.generate_boulder(pos, rot, pr) - elseif param == "fossil" then - mcl_structures.generate_fossil(pos, rot, pr) - elseif param == "ice_spike_small" then - mcl_structures.generate_ice_spike_small(pos, rot, pr) - elseif param == "ice_spike_large" then - mcl_structures.generate_ice_spike_large(pos, rot, pr) - elseif param == "end_exit_portal" then - mcl_structures.generate_end_exit_portal(pos, rot, pr) - elseif param == "end_exit_portal_open" then - mcl_structures.generate_end_exit_portal_open(pos, rot, pr) - elseif param == "end_gateway_portal" then - mcl_structures.generate_end_gateway_portal(pos, rot, pr) - elseif param == "end_portal_shrine" then - mcl_structures.generate_end_portal_shrine(pos, rot, pr) - elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then + if param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then mcl_dungeons.spawn_dungeon(pos, rot, pr) - elseif param == "nether_portal" and mcl_portals and mcl_portals.spawn_nether_portal then - mcl_portals.spawn_nether_portal(pos, rot, pr, name) elseif param == "" then message = S("Error: No structure type given. Please use “/spawnstruct ”.") errord = true else + for n,d in pairs(mcl_structures.registered_structures) do + if n == param then + mcl_structures.place_structure(pos,d,pr,math.random(),rot) + return true,message + end + end message = S("Error: Unknown structure type. Please use “/spawnstruct ”.") errord = true end @@ -628,3 +126,10 @@ minetest.register_chatcommand("spawnstruct", { end end }) +minetest.register_on_mods_loaded(function() + local p = "" + for n,_ in pairs(mcl_structures.registered_structures) do + p = p .. " | "..n + end + minetest.registered_chatcommands["spawnstruct"].params = minetest.registered_chatcommands["spawnstruct"].params .. p +end) diff --git a/mods/MAPGEN/mcl_structures/jungle_temple.lua b/mods/MAPGEN/mcl_structures/jungle_temple.lua new file mode 100644 index 000000000..843dec04d --- /dev/null +++ b/mods/MAPGEN/mcl_structures/jungle_temple.lua @@ -0,0 +1,44 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +mcl_structures.register_structure("jungle_temple",{ + place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + make_foundation = true, + y_offset = function(pr) return pr:next(-3,0) -5 end, + chunk_probability = 200, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + biomes = { "Jungle" }, + sidelen = 18, + filenames = { + modpath.."/schematics/mcl_structures_jungle_temple.mts", + modpath.."/schematics/mcl_structures_jungle_temple_nice.mts", + }, + loot = { + ["mcl_chests:trapped_chest_small" ] ={{ + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 16, amount_min = 3, amount_max=7 }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + --{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:diamond", weight = 3, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:saddle", weight = 3, }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }} + } +}) diff --git a/mods/MAPGEN/mcl_structures/locale/mcl_structures.ja.tr b/mods/MAPGEN/mcl_structures/locale/mcl_structures.ja.tr new file mode 100644 index 000000000..12ad5c643 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/locale/mcl_structures.ja.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_structures +Generate a pre-defined structure near your position.=自分の位置の近くに、既成の構造体を生成します。 +Structure placed.=構造体を配置しました。 +Village built. WARNING: Villages are experimental and might have bugs.=村を構築しました。 注:村は実験的なものであり、バグがあるかもしれません。 +Error: No structure type given. Please use “/spawnstruct ”.=エラー:構造体タイプが指定されていません。 "/spawnstruct " を使用してください。 +Error: Unknown structure type. Please use “/spawnstruct ”.=エラー:構造体タイプが不明です。 "/spawnstruct " を使用してください。 +Use /help spawnstruct to see a list of avaiable types.=使用可能なタイプのリストを見るには、 /help spawnstruct を使用してください。 diff --git a/mods/MAPGEN/mcl_structures/mod.conf b/mods/MAPGEN/mcl_structures/mod.conf index 3150c7cec..823714aad 100644 --- a/mods/MAPGEN/mcl_structures/mod.conf +++ b/mods/MAPGEN/mcl_structures/mod.conf @@ -1,4 +1,4 @@ name = mcl_structures -author = Wuzzy -description = Structures for MCL2 -depends = mcl_loot +author = Wuzzy, cora +description = Structure placement for MCL2 +depends = mcl_init, mcl_loot diff --git a/mods/MAPGEN/mcl_structures/ocean_ruins.lua b/mods/MAPGEN/mcl_structures/ocean_ruins.lua new file mode 100644 index 000000000..0b609aee7 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/ocean_ruins.lua @@ -0,0 +1,132 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +local cold_oceans = { + "RoofedForest_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "ExtremeHillsM_deep_ocean", + "SunflowerPlains_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "StoneBeach_ocean", + "ColdTaiga_deep_ocean", + "Forest_deep_ocean", + "FlowerForest_deep_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", +} + +local warm_oceans = { + "JungleEdgeM_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "Swampland_ocean", + "Mesa_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "MushroomIsland_ocean", + "SavannaM_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "Jungle_ocean", + "Desert_ocean", + "JungleM_ocean", + "JungleEdgeM_deep_ocean", + "Jungle_deep_ocean", + "Savanna_deep_ocean", + "MesaPlateauF_deep_ocean", + "Swampland_deep_ocean", + "Mesa_deep_ocean", + "Plains_deep_ocean", + "MesaPlateauFM_deep_ocean", + "MushroomIsland_deep_ocean", + "SavannaM_deep_ocean", + "JungleEdge_deep_ocean", + "MesaBryce_deep_ocean", + "Jungle_deep_ocean", + "Desert_deep_ocean", + "JungleM_deep_ocean", +} + +local cold = { + place_on = {"group:sand","mcl_core:gravel","mcl_core:dirt","mcl_core:clay","group:material_stone"}, + spawn_by = {"mcl_core:water_source"}, + num_spawn_by = 2, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z, force_placement", + solid_ground = true, + make_foundation = true, + y_offset = -1, + y_min = mcl_vars.mg_overworld_min, + y_max = -2, + biomes = cold_oceans, + chunk_probability = 400, + sidelen = 20, + filenames = { + modpath.."/schematics/mcl_structures_ocean_ruins_cold_1.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_cold_2.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_cold_3.mts", + }, + loot = { + ["mcl_chests:chest_small" ] = { + { + stacks_min = 2, + stacks_max = 4, + items = { + { itemstring = "mcl_core:coal_lump", weight = 25, amount_min = 1, amount_max=4 }, + { itemstring = "mcl_farming:wheat_item", weight = 25, amount_min = 2, amount_max=3 }, + { itemstring = "mcl_core:gold_nugget", weight = 25, amount_min = 1, amount_max=3 }, + --{ itemstring = "mcl_maps:treasure_map", weight = 20, }, --FIXME Treasure map + + { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_fishing:fishing_rod_enchanted", weight = 20, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_armor:chestplate_leather", weight = 15, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:apple_gold", weight = 20, }, + { itemstring = "mcl_armor:helmet_gold", weight = 15, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + } + } + }, +} + +local warm = table.copy(cold) +warm.biomes = warm_oceans +warm.filenames = { + modpath.."/schematics/mcl_structures_ocean_ruins_warm_1.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_warm_2.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_warm_3.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_warm_4.mts", +} + +mcl_structures.register_structure("cold_ocean_ruins",cold) +mcl_structures.register_structure("warm_ocean_ruins",warm) diff --git a/mods/MAPGEN/mcl_structures/pillager_outpost.lua b/mods/MAPGEN/mcl_structures/pillager_outpost.lua new file mode 100644 index 000000000..9b72071f0 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/pillager_outpost.lua @@ -0,0 +1,98 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +local spawnon = {"mcl_core:stripped_oak","mcl_stairs:slab_birchwood_top"} + +mcl_structures.register_structure("pillager_outpost",{ + place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass","group:sand"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + make_foundation = true, + sidelen = 32, + y_offset = 0, + chunk_probability = 600, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + biomes = { "Desert", "Plains", "Savanna", "IcePlains", "Taiga" }, + construct_nodes = {"mcl_anvils:anvil_damage_2"}, + filenames = { + modpath.."/schematics/mcl_structures_pillager_outpost.mts", + modpath.."/schematics/mcl_structures_pillager_outpost_2.mts" + }, + loot = { + ["mcl_chests:chest_small" ] ={ + { + stacks_min = 2, + stacks_max = 3, + items = { + { itemstring = "mcl_farming:wheat_item", weight = 7, amount_min = 3, amount_max=5 }, + { itemstring = "mcl_farming:carrot_item", weight = 5, amount_min = 3, amount_max=5 }, + { itemstring = "mcl_farming:potato_item", weight = 5, amount_min = 2, amount_max=5 }, + } + }, + { + stacks_min = 1, + stacks_max = 2, + items = { + { itemstring = "mcl_experience:bottle", weight = 6, amount_min = 0, amount_max=1 }, + { itemstring = "mcl_bows:arrow", weight = 4, amount_min = 2, amount_max=7 }, + { itemstring = "mcl_mobitems:string", weight = 4, amount_min = 1, amount_max=6 }, + { itemstring = "mcl_core:iron_ingot", weight = 3, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + } + }, + { + stacks_min = 1, + stacks_max = 3, + items = { + { itemstring = "mcl_core:darktree", amount_min = 2, amount_max=3 }, + } + }, + { + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_bows:crossbow" }, + } + }} + }, + after_place = function(p,def,pr) + local p1 = vector.offset(p,-9,0,-9) + local p2 = vector.offset(p,9,32,9) + mcl_structures.spawn_mobs("mobs_mc:evoker",spawnon,p1,p2,pr,1) + mcl_structures.spawn_mobs("mobs_mc:pillager",spawnon,p1,p2,pr,5) + mcl_structures.spawn_mobs("mobs_mc:parrot",{"mesecons_pressureplates:pressure_plate_stone_off"},p1,p2,pr,3) + mcl_structures.spawn_mobs("mobs_mc:iron_golem",{"mesecons_button:button_stone_off"},p1,p2,pr,1) + for _,n in pairs(minetest.find_nodes_in_area(p1,p2,{"group:wall"})) do + local def = minetest.registered_nodes[minetest.get_node(n).name:gsub("_%d+$","")] + if def and def.on_construct then + def.on_construct(n) + end + end + end +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:pillager", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 10, + interval = 60, + limit = 9, + spawnon = spawnon, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:evoker", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 100, + interval = 60, + limit = 4, + spawnon = spawnon, +}) diff --git a/mods/MAPGEN/mcl_structures/ruined_portal.lua b/mods/MAPGEN/mcl_structures/ruined_portal.lua new file mode 100644 index 000000000..00d2d682c --- /dev/null +++ b/mods/MAPGEN/mcl_structures/ruined_portal.lua @@ -0,0 +1,85 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local function get_replacements(b,c,pr) + local r = {} + if not b then return r end + for k,v in pairs(b) do + if pr:next(1,100) < c then table.insert(r,v) end + end + return r +end + +local def = { + place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass","group:grass_block","group:sand","group:grass_block_snow","mcl_core:snow"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z, all_floors", + solid_ground = true, + make_foundation = true, + chunk_probability = 800, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + sidelen = 10, + y_offset = -5, + filenames = { + modpath.."/schematics/mcl_structures_ruined_portal_1.mts", + modpath.."/schematics/mcl_structures_ruined_portal_2.mts", + modpath.."/schematics/mcl_structures_ruined_portal_3.mts", + modpath.."/schematics/mcl_structures_ruined_portal_4.mts", + modpath.."/schematics/mcl_structures_ruined_portal_5.mts", + modpath.."/schematics/mcl_structures_ruined_portal_99.mts", + }, + after_place = function(pos,def,pr) + local hl = def.sidelen / 2 + local p1 = vector.offset(pos,-hl,-hl,-hl) + local p2 = vector.offset(pos,hl,hl,hl) + local gold = minetest.find_nodes_in_area(p1,p2,{"mcl_core:goldblock"}) + local lava = minetest.find_nodes_in_area(p1,p2,{"mcl_core:lava_source"}) + local rack = minetest.find_nodes_in_area(p1,p2,{"mcl_nether:netherrack"}) + local brick = minetest.find_nodes_in_area(p1,p2,{"mcl_core:stonebrick"}) + local obby = minetest.find_nodes_in_area(p1,p2,{"mcl_core:obsidian"}) + minetest.bulk_set_node(get_replacements(gold,30,pr),{name="air"}) + minetest.bulk_set_node(get_replacements(lava,20,pr),{name="mcl_nether:magma"}) + minetest.bulk_set_node(get_replacements(rack,7,pr),{name="mcl_nether:magma"}) + minetest.bulk_set_node(get_replacements(obby,30,pr),{name="mcl_core:crying_obsidian"}) + minetest.bulk_set_node(get_replacements(obby,10,pr),{name="air"}) + minetest.bulk_set_node(get_replacements(brick,50,pr),{name="mcl_core:stonebrickcracked"}) + brick = minetest.find_nodes_in_area(p1,p2,{"mcl_core:stonebrick"}) + minetest.bulk_set_node(get_replacements(brick,50,pr),{name="mcl_core:stonebrickmossy"}) + end, + loot = { + ["mcl_chests:chest_small" ] ={{ + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_core:iron_nugget", weight = 40, amount_min = 9, amount_max = 18 }, + { itemstring = "mcl_core:flint", weight = 40, amount_min = 1, amount_max=4 }, + { itemstring = "mcl_core:obsidian", weight = 40, amount_min = 1, amount_max=2 }, + { itemstring = "mcl_fire:fire_charge", weight = 40, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_fire:flint_and_steel", weight = 40, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:gold_nugget", weight = 15, amount_min = 4, amount_max = 24 }, + { itemstring = "mcl_core:apple_gold", weight = 15, }, + + { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + --{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO + + { itemstring = "mcl_core:diamond", weight = 3, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:saddle", weight = 3, }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, }, + { itemstring = "mcl_core:apple_gold", weight = 15, }, + } + }} + } +} +mcl_structures.register_structure("ruined_portal_overworld",def) +local ndef = table.copy(def) +ndef.y_min=mcl_vars.mg_lava_nether_max +10 +ndef.y_max=mcl_vars.mg_nether_max - 15 +ndef.place_on = {"mcl_nether:netherrack","group:soul_block","mcl_blackstone:basalt,mcl_blackstone:blackstone","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium"}, +mcl_structures.register_structure("ruined_portal_nether",ndef) diff --git a/mods/MAPGEN/mcl_structures/schematics/coral_cora.mts b/mods/MAPGEN/mcl_structures/schematics/coral_cora.mts new file mode 100644 index 000000000..8ee971820 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/coral_cora.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_1.mts new file mode 100644 index 000000000..03e1ddfb6 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_2.mts new file mode 100644 index 000000000..f40af2ec3 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_1.mts new file mode 100644 index 000000000..1111368e8 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_2.mts new file mode 100644 index 000000000..c3cf1012e Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_1.mts new file mode 100644 index 000000000..fffbfb26f Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_2.mts new file mode 100644 index 000000000..a55b3995f Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_1.mts new file mode 100644 index 000000000..03c8f0e85 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_2.mts new file mode 100644 index 000000000..8d2ec7f2b Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_1.mts new file mode 100644 index 000000000..89d08e9ea Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_2.mts new file mode 100644 index 000000000..cd4372f95 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_boat.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_boat.mts new file mode 100644 index 000000000..a334a4bdc Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_boat.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_shipwreck_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_shipwreck_1.mts new file mode 100644 index 000000000..5daad2f3d Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_shipwreck_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_basement.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_basement.mts index c2a774e78..2bc92ae5d 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_basement.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_basement.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_top.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_top.mts index e3705236e..5a2a96dea 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_top.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_top.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple.mts new file mode 100644 index 000000000..ec98a83ea Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple_nice.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple_nice.mts new file mode 100644 index 000000000..8a9babb9b Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple_nice.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_1.mts new file mode 100644 index 000000000..1b2c8d1f3 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_2.mts new file mode 100644 index 000000000..d7437d7ce Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_3.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_3.mts new file mode 100644 index 000000000..67cb5c9ac Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_3.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_1.mts new file mode 100644 index 000000000..072931b13 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_2.mts new file mode 100644 index 000000000..9834226fa Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_3.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_3.mts new file mode 100644 index 000000000..eb43cdf1c Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_3.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_4.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_4.mts new file mode 100644 index 000000000..0eb5bacf0 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_4.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple.mts new file mode 100644 index 000000000..0a16fa9b2 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple_2.mts new file mode 100644 index 000000000..8a5a6a313 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost.mts new file mode 100644 index 000000000..35424ad76 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost_2.mts new file mode 100644 index 000000000..4a7727acf Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts new file mode 100644 index 000000000..55a6f2ae3 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts new file mode 100644 index 000000000..9da16e2ed Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_3.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_3.mts new file mode 100644 index 000000000..88c0acb28 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_3.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_4.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_4.mts new file mode 100644 index 000000000..404256ed9 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_4.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_5.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_5.mts new file mode 100644 index 000000000..f14105154 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_5.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts new file mode 100644 index 000000000..463bf19df Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_back_damaged.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_back_damaged.mts new file mode 100644 index 000000000..12f3c9b13 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_back_damaged.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_damaged.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_damaged.mts new file mode 100644 index 000000000..5c8a3e105 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_damaged.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_normal.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_normal.mts new file mode 100644 index 000000000..3d997c83b Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_normal.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_back.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_back.mts new file mode 100644 index 000000000..f58376f30 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_back.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_front.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_front.mts new file mode 100644 index 000000000..41efb386b Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_front.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_cabin.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_cabin.mts new file mode 100644 index 000000000..f654da926 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_cabin.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_outpost.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_outpost.mts new file mode 100644 index 000000000..8ee1daffa Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_outpost.mts differ diff --git a/mods/MAPGEN/mcl_structures/shipwrecks.lua b/mods/MAPGEN/mcl_structures/shipwrecks.lua new file mode 100644 index 000000000..a9c48e0b5 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/shipwrecks.lua @@ -0,0 +1,263 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +--local S = minetest.get_translator(modname) + +local seed = minetest.get_mapgen_setting("seed") +local water_level = minetest.get_mapgen_setting("water_level") +local pr = PseudoRandom(seed) + +--schematics by chmodsayshello +local schems = { + modpath.."/schematics/mcl_structures_shipwreck_full_damaged.mts", + modpath.."/schematics/mcl_structures_shipwreck_full_normal.mts", + modpath.."/schematics/mcl_structures_shipwreck_full_back_damaged.mts", + modpath.."/schematics/mcl_structures_shipwreck_half_front.mts", + modpath.."/schematics/mcl_structures_shipwreck_half_back.mts", +} + +local ocean_biomes = { + "RoofedForest_ocean", + "JungleEdgeM_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "ExtremeHillsM_deep_ocean", + "Savanna_deep_ocean", + "SunflowerPlains_ocean", + "Swampland_deep_ocean", + "Swampland_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "JungleEdgeM_deep_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "Mesa_ocean", + "StoneBeach_ocean", + "Plains_deep_ocean", + "JungleEdge_deep_ocean", + "SavannaM_deep_ocean", + "Desert_deep_ocean", + "Mesa_deep_ocean", + "ColdTaiga_deep_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "Forest_deep_ocean", + "JungleM_deep_ocean", + "FlowerForest_deep_ocean", + "MushroomIsland_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "SavannaM_ocean", + "MesaPlateauF_deep_ocean", + "MesaBryce_deep_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "MushroomIsland_deep_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "Jungle_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "MesaPlateauFM_deep_ocean", + "Desert_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", + "JungleM_ocean" +} + +local beach_biomes = { + "FlowerForest_beach", + "Forest_beach", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "Savanna_beach", + "Plains_beach", + "ExtremeHills_beach", + "ColdTaiga_beach", + "Swampland_shore", + "MushroomIslandShore", + "JungleM_shore", + "Jungle_shore" +} + +mcl_structures.register_structure("shipwreck",{ + place_on = {"group:sand","mcl_core:gravel"}, + spawn_by = {"group:water"}, + num_spawn_by = 4, + noise_params = { + offset = 0, + scale = 0.000022, + spread = {x = 250, y = 250, z = 250}, + seed = 3, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + sidelen = 16, + flags = "force_placement", + biomes = ocean_biomes, + y_max = water_level-4, + y_min = mcl_vars.mg_overworld_min, + filenames = schems, + y_offset = function(pr) return pr:next(-4,-2) end, + loot = { + ["mcl_chests:chest_small"] = { + stacks_min = 3, + stacks_max = 10, + items = { + { itemstring = "mcl_sus_stew:stew", weight = 10, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:paper", weight = 8, amount_min = 1, amount_max = 12 }, + { itemstring = "mcl_farming:wheat_item", weight = 7, amount_min = 8, amount_max = 21 }, + { itemstring = "mcl_farming:carrot_item", weight = 7, amount_min = 4, amount_max = 8 }, + { itemstring = "mcl_farming:potato_item_poison", weight = 7, amount_min = 2, amount_max = 6 }, + { itemstring = "mcl_farming:potato_item", weight = 7, amount_min = 2, amount_max = 6 }, + --{ itemstring = "TODO:moss_block", weight = 7, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_core:coal_lump", weight = 6, amount_min = 2, amount_max = 8 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 5, amount_min = 5, amount_max = 24 }, + { itemstring = "mcl_farming:potato_item", weight = 3, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_armor:helmet_leather_enchanted", weight = 3, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, + { itemstring = "mcl_armor:chestplate_leather_enchanted", weight = 3, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, + { itemstring = "mcl_armor:leggings_leather_enchanted", weight = 3, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, + { itemstring = "mcl_armor:boots_leather_enchanted", weight = 3, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, + --{ itemstring = "TODO:bamboo", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_farming:pumpkin", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 }, + + }, + { + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_core:iron_ingot", weight = 90, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:iron_nugget", weight = 50, amount_min = 1, amount_max = 10 }, + { itemstring = "mcl_core:emerald", weight = 40, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:lapis", weight = 20, amount_min = 1, amount_max = 10 }, + { itemstring = "mcl_core:gold_ingot", weight = 10, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 10 }, + { itemstring = "mcl_experience:bottle", weight = 5, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 1 }, + } + },{ + stacks_min = 3, + stacks_max = 3, + items = { + --{ itemstring = "FIXME TREASURE MAP", weight = 8, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:paper", weight = 20, amount_min = 1, amount_max = 10 }, + { itemstring = "mcl_mobitems:feather", weight = 10, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_books:book", weight = 5, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_clock:clock", weight = 1, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_compass:compass", weight = 1, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_maps:empty_map", weight = 1, amount_min = 1, amount_max = 1 }, + + } + }, + } + } +}) + +local spawnon = { "mcl_stairs:slab_prismarine_dark"} + +mcl_structures.register_structure("ocean_temple",{ + place_on = {"group:sand","mcl_core:gravel"}, + spawn_by = {"group:water"}, + num_spawn_by = 4, + noise_params = { + offset = 0, + scale = 0.0000122, + spread = {x = 250, y = 250, z = 250}, + seed = 32345, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + sidelen = 32, + flags = "force_placement", + biomes = ocean_biomes, + y_max = water_level-4, + y_min = mcl_vars.mg_overworld_min, + filenames = { + modpath .. "/schematics/mcl_structures_ocean_temple.mts", + modpath .. "/schematics/mcl_structures_ocean_temple_2.mts", + }, + y_offset = function(pr) return pr:next(-2,0) end, + after_place = function(p,def,pr) + local p1 = vector.offset(p,-9,0,-9) + local p2 = vector.offset(p,9,32,9) + mcl_structures.spawn_mobs("mobs_mc:guardian",spawnon,p1,p2,pr,5,true) + mcl_structures.spawn_mobs("mobs_mc:guardian_elder",spawnon,p1,p2,pr,1,true) + mcl_structures.construct_nodes(p1,p2,{"group:wall"}) + end, + loot = { + ["mcl_chests:chest_small"] = { + stacks_min = 3, + stacks_max = 10, + items = { + { itemstring = "mcl_sus_stew:stew", weight = 10, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:paper", weight = 8, amount_min = 1, amount_max = 12 }, + { itemstring = "mcl_fishing:fish_raw", weight = 5, amount_min = 8, amount_max = 21 }, + { itemstring = "mcl_fishing:salmon_raw", weight = 7, amount_min = 4, amount_max = 8 }, + { itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 }, + }, + { + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:goldblock", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "mcl_experience:bottle", weight = 5, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_fishing:fishing_rod", weight = 1, amount_min = 1, amount_max = 1 }, + } + }, + { + stacks_min = 4, + stacks_max = 4, + items = { + --{ itemstring = "FIXME TREASURE MAP", weight = 8, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_books:book", weight = 1, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_clock:clock", weight = 1, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_compass:compass", weight = 1, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_maps:empty_map", weight = 1, amount_min = 1, amount_max = 1 }, + } + }, + } + } +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:guardian", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 10, + interval = 60, + limit = 9, + spawnon = spawnon, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:guardian_elder", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 100, + interval = 60, + limit = 4, + spawnon = spawnon, +}) diff --git a/mods/MAPGEN/mcl_structures/witch_hut.lua b/mods/MAPGEN/mcl_structures/witch_hut.lua new file mode 100644 index 000000000..5ac23b144 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/witch_hut.lua @@ -0,0 +1,54 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +local function spawn_witch(p1,p2) + local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"}) + if c then + local nn = minetest.find_nodes_in_area_under_air(vector.new(p1.x,c.y-1,p1.z),vector.new(p2.x,c.y-1,p2.z),{"mcl_core:sprucewood"}) + local witch + if not peaceful then + witch = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:witch"):get_luaentity() + witch._home = c + witch.can_despawn = false + end + local cat = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:cat"):get_luaentity() + cat.object:set_properties({textures = {"mobs_mc_cat_black.png"}}) + cat.owner = "!witch!" --so it's not claimable by player + cat._home = c + cat.can_despawn = false + return + end +end + +local function hut_placement_callback(pos,def,pr) + local hl = def.sidelen / 2 + local p1 = vector.offset(pos,-hl,-hl,-hl) + local p2 = vector.offset(pos,hl,hl,hl) + local legs = minetest.find_nodes_in_area(vector.offset(pos,-hl,0,-hl),vector.offset(pos,hl,0,hl), "mcl_core:tree") + local tree = {} + for _,leg in pairs(legs) do + while minetest.get_item_group(mcl_vars.get_node(vector.offset(leg,0,-1,0), true, 333333).name, "water") ~= 0 do + leg = vector.offset(leg,0,-1,0) + table.insert(tree,leg) + end + end + minetest.bulk_set_node(tree, {name = "mcl_core:tree", param2 = 2}) + spawn_witch(p1,p2) +end + +mcl_structures.register_structure("witch_hut",{ + place_on = {"group:sand","group:grass_block","mcl_core:water_source","group:dirt"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z, liquid_surface, force_placement", + sidelen = 8, + chunk_probability = 300, + y_max = mcl_vars.mg_overworld_max, + y_min = -4, + y_offset = 0, + biomes = { "Swampland", "Swampland_ocean", "Swampland_shore" }, + filenames = { modpath.."/schematics/mcl_structures_witch_hut.mts" }, + after_place = hut_placement_callback, +}) diff --git a/mods/MAPGEN/mcl_structures/woodland_mansion.lua b/mods/MAPGEN/mcl_structures/woodland_mansion.lua new file mode 100644 index 000000000..5429e4892 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/woodland_mansion.lua @@ -0,0 +1,89 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +local spawnon = {"mcl_deepslate:deepslate","mcl_core:birchwood","mcl_wool:red_carpet","mcl_wool:brown_carpet"} + +mcl_structures.register_structure("woodland_cabin",{ + place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + make_foundation = true, + chunk_probability = 800, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + biomes = { "RoofedForest" }, + sidelen = 32, + filenames = { + modpath.."/schematics/mcl_structures_woodland_cabin.mts", + modpath.."/schematics/mcl_structures_woodland_outpost.mts", + }, + construct_nodes = {"mcl_barrels:barrel_closed","mcl_books:bookshelf"}, + after_place = function(p,def,pr) + local p1=vector.offset(p,-def.sidelen,-1,-def.sidelen) + local p2=vector.offset(p,def.sidelen,def.sidelen,def.sidelen) + mcl_structures.spawn_mobs("mobs_mc:vindicator",spawnon,p1,p2,pr,5) + mcl_structures.spawn_mobs("mobs_mc:evoker",spawnon,p1,p2,pr,1) + mcl_structures.spawn_mobs("mobs_mc:parrot",{"mcl_heads:wither_skeleton"},p1,p2,pr,1) + end, + loot = { + ["mcl_chests:chest_small" ] ={{ + stacks_min = 3, + stacks_max = 3, + items = { + { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max=8 }, + { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max=8 }, + { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max=8 }, + + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + }},{ + stacks_min = 1, + stacks_max = 4, + items = { + { itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_farming:bread", weight = 20, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mesecons:mesecon", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_buckets:bucket_empty", weight = 10, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, + }},{ + stacks_min = 1, + stacks_max = 4, + items = { + --{ itemstring = "FIXME:lead", weight = 20, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_mobs:nametag", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_chain", weight = 1, }, + { itemstring = "mcl_armor:chestplate_diamond", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }} + } +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:vindicator", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 10, + interval = 60, + limit = 6, + spawnon = spawnon, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:evoker", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 50, + interval = 60, + limit = 6, + spawnon = spawnon, +}) diff --git a/mods/MAPGEN/mcl_terrain_features/init.lua b/mods/MAPGEN/mcl_terrain_features/init.lua new file mode 100644 index 000000000..eab33e78e --- /dev/null +++ b/mods/MAPGEN/mcl_terrain_features/init.lua @@ -0,0 +1,374 @@ +local adjacents = { + vector.new(1,0,0), + vector.new(1,0,1), + vector.new(1,0,-1), + vector.new(-1,0,0), + vector.new(-1,0,1), + vector.new(-1,0,-1), + vector.new(0,0,1), + vector.new(0,0,-1), + vector.new(0,-1,0) +} + +local plane_adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +local function set_node_no_bedrock(pos,node) + local n = minetest.get_node(pos) + if n.name == "mcl_core:bedrock" then return end + return minetest.set_node(pos,node) +end + +local function airtower(pos,tbl,h) + for i=1,h do + table.insert(tbl,vector.offset(pos,0,i,0)) + end +end + +local function makelake(pos,size,liquid,placein,border,pr,noair) + local node_under = minetest.get_node(vector.offset(pos,0,-1,0)) + local p1 = vector.offset(pos,-size,-1,-size) + local p2 = vector.offset(pos,size,-1,size) + minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param) + if calls_remaining ~= 0 then return end + local nn = minetest.find_nodes_in_area(p1,p2,placein) + table.sort(nn,function(a, b) + return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) + end) + if not nn[1] then return end + local y = pos.y - pr:next(1,2) + local lq = {} + local air = {} + local r = pr:next(1,#nn) + if r > #nn then return end + for i=1,r do + if nn[i].y == y then + airtower(nn[i],air,55) + table.insert(lq,nn[i]) + end + end + minetest.bulk_set_node(lq,{name=liquid}) + minetest.bulk_set_node(air,{name="air"}) + air = {} + local br = {} + for k,v in pairs(lq) do + for kk,vv in pairs(adjacents) do + local pp = vector.add(v,vv) + local an = minetest.get_node(pp) + local un = minetest.get_node(vector.offset(pp,0,1,0)) + if not border then + if minetest.get_item_group(an.name,"solid") > 0 then + border = an.name + elseif minetest.get_item_group(minetest.get_node(nn[1]).name,"solid") > 0 then + border = minetest.get_node_or_nil(nn[1]).name + else + border = "mcl_core:stone" + end + if border == nil or border == "mcl_core:dirt" then border = "mcl_core:dirt_with_grass" end + end + if not noair and an.name ~= liquid then + table.insert(br,pp) + if un.name ~= liquid then + airtower(pp,air,55) + end + end + end + end + minetest.bulk_set_node(br,{name=border}) + minetest.bulk_set_node(air,{name="air"}) + return true + end) + return true +end + +local mushrooms = {"mcl_mushrooms:mushroom_brown","mcl_mushrooms:mushroom_red"} + +local function get_fallen_tree_schematic(pos,pr) + local tree = minetest.find_node_near(pos,15,{"group:tree"}) + if not tree then return end + tree = minetest.get_node(tree).name + local maxlen = 8 + local minlen = 2 + local vprob = 120 + local mprob = 160 + local len = pr:next(minlen,maxlen) + local schem = { + size = {x = len + 2, y = 2, z = 3}, + data = { + {name = "air", prob=0}, + {name = "air", prob=0}, + } + } + for i = 1,len do + table.insert(schem.data,{name = "mcl_core:vine",param2=4, prob=vprob}) + end + table.insert(schem.data,{name = "air", prob=0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = "air", prob=0}) + end + + table.insert(schem.data,{name = tree, param2 = 0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = tree, param2 = 12}) + end + table.insert(schem.data,{name = "air", prob=0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = mushrooms[pr:next(1,#mushrooms)], param2 = 12, prob=mprob}) + end + + table.insert(schem.data,{name = "air", prob=0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = "mcl_core:vine",param2=5, prob=vprob}) + end + table.insert(schem.data,{name = "air", prob=0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = "air", prob=0}) + end + + return schem +end + +mcl_structures.register_structure("fallen_tree",{ + place_on = {"group:grass_block"}, + terrain_feature = true, + noise_params = { + offset = 0.00018, + scale = 0.01011, + spread = {x = 250, y = 250, z = 250}, + seed = 24533, + octaves = 3, + persist = 0.66 + }, + flags = "place_center_x, place_center_z", + sidelen = 18, + solid_ground = true, + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + on_place = function(pos,def,pr) + local air_p1 = vector.offset(pos,-def.sidelen/2,1,-def.sidelen/2) + local air_p2 = vector.offset(pos,def.sidelen/2,1,def.sidelen/2) + local air = minetest.find_nodes_in_area(air_p1,air_p2,{"air"}) + if #air < ( def.sidelen * def.sidelen ) / 2 then + return false + end + return true + end, + place_func = function(pos,def,pr) + local schem=get_fallen_tree_schematic(pos,pr) + if not schem then return end + return minetest.place_schematic(pos,schem,"random") + end +}) + +mcl_structures.register_structure("lavapool",{ + place_on = {"group:sand", "group:dirt", "group:stone"}, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.0000022, + spread = {x = 250, y = 250, z = 250}, + seed = 78375213, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + place_func = function(pos,def,pr) + return makelake(pos,5,"mcl_core:lava_source",{"group:material_stone", "group:sand", "group:dirt"},"mcl_core:stone",pr) + end +}) + +mcl_structures.register_structure("water_lake",{ + place_on = {"group:dirt","group:stone"}, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.000032, + spread = {x = 250, y = 250, z = 250}, + seed = 756641353, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + place_func = function(pos,def,pr) + return makelake(pos,5,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt","group:grass_block"},"mcl_core:dirt_with_grass",pr) + end +}) + +mcl_structures.register_structure("water_lake_mangrove_swamp",{ + place_on = {"mcl_mud:mud"}, + biomes = { "MangroveSwamp" }, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.0032, + spread = {x = 250, y = 250, z = 250}, + seed = 6343241353, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + place_func = function(pos,def,pr) + return makelake(pos,3,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt","group:grass_block","mcl_mud:mud"},"mcl_mud:mud",pr,true) + end +}) + +local pool_adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,-1,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +mcl_structures.register_structure("basalt_column",{ + place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, + terrain_feature = true, + spawn_by = {"air"}, + num_spawn_by = 2, + noise_params = { + offset = 0, + scale = 0.003, + spread = {x = 250, y = 250, z = 250}, + seed = 72235213, + octaves = 5, + persist = 0.3, + flags = "absvalue", + }, + flags = "all_floors", + y_max = mcl_vars.mg_nether_max - 20, + y_min = mcl_vars.mg_lava_nether_max + 1, + biomes = { "BasaltDelta" }, + place_func = function(pos,def,pr) + local nn = minetest.find_nodes_in_area(vector.offset(pos,-5,-1,-5),vector.offset(pos,5,-1,5),{"air","mcl_blackstone:basalt","mcl_blackstone:blackstone"}) + table.sort(nn,function(a, b) + return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) + end) + if #nn < 1 then return false end + local basalt = {} + local magma = {} + for i=1,pr:next(1,#nn) do + if minetest.get_node(vector.offset(nn[i],0,-1,0)).name ~= "air" then + local dst=vector.distance(pos,nn[i]) + local r = pr:next(1,14)-dst + for ii=0,r do + if pr:next(1,25) == 1 then + table.insert(magma,vector.new(nn[i].x,nn[i].y + ii,nn[i].z)) + else + table.insert(basalt,vector.new(nn[i].x,nn[i].y + ii,nn[i].z)) + end + end + end + end + minetest.bulk_set_node(magma,{name="mcl_nether:magma"}) + minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"}) + return true + end +}) +mcl_structures.register_structure("basalt_pillar",{ + place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.001, + spread = {x = 250, y = 250, z = 250}, + seed = 7113, + octaves = 5, + persist = 0.1, + flags = "absvalue", + }, + flags = "all_floors", + y_max = mcl_vars.mg_nether_max-40, + y_min = mcl_vars.mg_lava_nether_max + 1, + biomes = { "BasaltDelta" }, + place_func = function(pos,def,pr) + local nn = minetest.find_nodes_in_area(vector.offset(pos,-2,-1,-2),vector.offset(pos,2,-1,2),{"air","mcl_blackstone:basalt","mcl_blackstone:blackstone"}) + table.sort(nn,function(a, b) + return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) + end) + if #nn < 1 then return false end + local basalt = {} + local magma = {} + for i=1,pr:next(1,#nn) do + if minetest.get_node(vector.offset(nn[i],0,-1,0)).name ~= "air" then + local dst=vector.distance(pos,nn[i]) + for ii=0,pr:next(19,35)-dst do + if pr:next(1,20) == 1 then + table.insert(magma,vector.new(nn[i].x,nn[i].y + ii,nn[i].z)) + else + table.insert(basalt,vector.new(nn[i].x,nn[i].y + ii,nn[i].z)) + end + end + end + end + minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"}) + minetest.bulk_set_node(magma,{name="mcl_nether:magma"}) + return true + end +}) + +mcl_structures.register_structure("lavadelta",{ + place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, + spawn_by = {"mcl_blackstone:basalt","mcl_blackstone:blackstone"}, + num_spawn_by = 2, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.005, + spread = {x = 250, y = 250, z = 250}, + seed = 78375213, + octaves = 5, + persist = 0.1, + flags = "absvalue", + }, + flags = "all_floors", + y_max = mcl_vars.mg_nether_max, + y_min = mcl_vars.mg_lava_nether_max + 1, + biomes = { "BasaltDelta" }, + place_func = function(pos,def,pr) + local nn = minetest.find_nodes_in_area_under_air(vector.offset(pos,-10,-1,-10),vector.offset(pos,10,-2,10),{"mcl_blackstone:basalt","mcl_blackstone:blackstone","mcl_nether:netherrack"}) + table.sort(nn,function(a, b) + return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) + end) + if #nn < 1 then return false end + local lava = {} + for i=1,pr:next(1,#nn) do + table.insert(lava,nn[i]) + end + minetest.bulk_set_node(lava,{name="mcl_nether:nether_lava_source"}) + local basalt = {} + local magma = {} + for _,v in pairs(lava) do + for _,vv in pairs(adjacents) do + local p = vector.add(v,vv) + if minetest.get_node(p).name ~= "mcl_nether:nether_lava_source" then + table.insert(basalt,p) + + end + end + if math.random(3) == 1 then + table.insert(magma,v) + end + end + minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"}) + minetest.bulk_set_node(magma,{name="mcl_nether:magma"}) + return true + end +}) diff --git a/mods/MAPGEN/mcl_terrain_features/mod.conf b/mods/MAPGEN/mcl_terrain_features/mod.conf new file mode 100644 index 000000000..008e370cc --- /dev/null +++ b/mods/MAPGEN/mcl_terrain_features/mod.conf @@ -0,0 +1,3 @@ +name = mcl_terrain_features +author = cora +depends = mcl_init, mcl_structures diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 67a0785ce..92a53ddaf 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -79,19 +79,27 @@ function settlements.create_site_plan(maxp, minp, pr) local settlement_info = {} local building_all_info local possible_rotations = {"0", "90", "180", "270"} + -- find center of chunk local center = { x=math.floor((minp.x+maxp.x)/2), y=maxp.y, z=math.floor((minp.z+maxp.z)/2) } + -- find center_surface of chunk local center_surface , surface_material = settlements.find_surface(center, true) local chunks = {} chunks[mcl_vars.get_chunk_number(center)] = true -- go build settlement around center - if not center_surface then return false end + if not center_surface then + minetest.log("action", "Cannot build village at: " .. minetest.pos_to_string(center)) + return false + else + minetest.log("action", "Village built.") + --minetest.log("action", "Build village at: " .. minetest.pos_to_string(center) .. " with surface material: " .. surface_material) + end -- initialize all settlement_info table local count_buildings, number_of_buildings, number_built = settlements.initialize_settlement_info(pr) @@ -190,6 +198,7 @@ local function construct_node(p1, p2, name) end local function spawn_iron_golem(pos) + --minetest.log("action", "Attempt to spawn iron golem.") local p = minetest.find_node_near(pos,50,"mcl_core:grass_path") if p then local l=minetest.add_entity(p,"mobs_mc:iron_golem"):get_luaentity() @@ -200,6 +209,7 @@ local function spawn_iron_golem(pos) end local function spawn_villagers(minp,maxp) + --minetest.log("action", "Attempt to spawn villagers.") local beds=minetest.find_nodes_in_area(vector.offset(minp,-20,-20,-20),vector.offset(maxp,20,20,20),{"mcl_beds:bed_red_bottom"}) for _,bed in pairs(beds) do local m = minetest.get_meta(bed) @@ -235,23 +245,6 @@ end function settlements.place_schematics(settlement_info, pr) local building_all_info - --attempt to place one belltower in the center of the village - this doesn't always work out great but it's a lot better than doing it first or last. - local belltower = table.remove(settlement_info,math.floor(#settlement_info/2)) - if belltower then - mcl_structures.place_schematic( - vector.offset(belltower["pos"],0,0,0), - settlements.modpath.."/schematics/belltower.mts", - belltower["rotation"], - nil, - true, - nil, - function(p1, p2, size, rotation, pr) - spawn_iron_golem(p1) - end, - pr - ) - end - for i, built_house in ipairs(settlement_info) do local is_last = i == #settlement_info @@ -262,6 +255,9 @@ function settlements.place_schematics(settlement_info, pr) end end + + + local pos = settlement_info[i]["pos"] local rotation = settlement_info[i]["rotat"] -- get building node material for better integration to surrounding @@ -313,8 +309,11 @@ function settlements.place_schematics(settlement_info, pr) -- format schematic string local schematic = loadstring(schem_lua)() + + local is_belltower = building_all_info["name"] == "belltower" + -- build foundation for the building an make room above - -- place schematic + mcl_structures.place_schematic( pos, schematic, @@ -323,8 +322,12 @@ function settlements.place_schematics(settlement_info, pr) true, nil, function(p1, p2, size, rotation, pr) - init_nodes(p1, p2, size, rotation, pr) - spawn_villagers(p1,p2) + if is_belltower then + spawn_iron_golem(p1) + else + init_nodes(p1, p2, size, rotation, pr) + spawn_villagers(p1,p2) + end end, pr ) diff --git a/mods/MAPGEN/mcl_villages/const.lua b/mods/MAPGEN/mcl_villages/const.lua index 65f43f344..feff6a1d2 100644 --- a/mods/MAPGEN/mcl_villages/const.lua +++ b/mods/MAPGEN/mcl_villages/const.lua @@ -52,16 +52,17 @@ schem_path = settlements.modpath.."/schematics/" local basic_pseudobiome_villages = minetest.settings:get_bool("basic_pseudobiome_villages", true) settlements.schematic_table = { - {name = "large_house", mts = schem_path.."large_house.mts", hwidth = 11, hdepth = 12, hheight = 9, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, - {name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.055, rplc = basic_pseudobiome_villages }, - {name = "butcher", mts = schem_path.."butcher.mts", hwidth = 11, hdepth = 8, hheight = 10, hsize = 14, max_num = 0.03 , rplc = basic_pseudobiome_villages }, + {name = "belltower", mts = schem_path.."belltower.mts", hwidth = 5, hdepth = 5, hheight = 9, hsize = 14, max_num = 0 , rplc = basic_pseudobiome_villages }, + {name = "large_house", mts = schem_path.."large_house.mts", hwidth = 12, hdepth = 12, hheight = 9, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, + {name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 8, hdepth = 11, hheight = 13, hsize = 13, max_num = 0.055, rplc = basic_pseudobiome_villages }, + {name = "butcher", mts = schem_path.."butcher.mts", hwidth = 12, hdepth = 8, hheight = 10, hsize = 14, max_num = 0.03 , rplc = basic_pseudobiome_villages }, {name = "church", mts = schem_path.."church.mts", hwidth = 13, hdepth = 13, hheight = 14, hsize = 15, max_num = 0.04 , rplc = basic_pseudobiome_villages }, - {name = "farm", mts = schem_path.."farm.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1 , rplc = basic_pseudobiome_villages }, - {name = "lamp", mts = schem_path.."lamp.mts", hwidth = 3, hdepth = 3, hheight = 13, hsize = 10, max_num = 0.1 , rplc = false }, + {name = "farm", mts = schem_path.."farm.mts", hwidth = 9, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1 , rplc = basic_pseudobiome_villages }, + {name = "lamp", mts = schem_path.."lamp.mts", hwidth = 3, hdepth = 4, hheight = 13, hsize = 10, max_num = 0.1 , rplc = false }, {name = "library", mts = schem_path.."library.mts", hwidth = 12, hdepth = 12, hheight = 8, hsize = 13, max_num = 0.04 , rplc = basic_pseudobiome_villages }, - {name = "medium_house", mts = schem_path.."medium_house.mts", hwidth = 8, hdepth = 12, hheight = 8, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, - {name = "small_house", mts = schem_path.."small_house.mts", hwidth = 9, hdepth = 7, hheight = 8, hsize = 13, max_num = 0.7 , rplc = basic_pseudobiome_villages }, - {name = "tavern", mts = schem_path.."tavern.mts", hwidth = 11, hdepth = 10, hheight = 10, hsize = 13, max_num = 0.050, rplc = basic_pseudobiome_villages }, + {name = "medium_house", mts = schem_path.."medium_house.mts", hwidth = 9, hdepth = 12, hheight = 8, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, + {name = "small_house", mts = schem_path.."small_house.mts", hwidth = 9, hdepth = 8, hheight = 8, hsize = 13, max_num = 0.7 , rplc = basic_pseudobiome_villages }, + {name = "tavern", mts = schem_path.."tavern.mts", hwidth = 12, hdepth = 10, hheight = 10, hsize = 13, max_num = 0.050, rplc = basic_pseudobiome_villages }, {name = "well", mts = schem_path.."well.mts", hwidth = 6, hdepth = 8, hheight = 6, hsize = 10, max_num = 0.045, rplc = basic_pseudobiome_villages }, } diff --git a/mods/MAPGEN/mcl_villages/foundation.lua b/mods/MAPGEN/mcl_villages/foundation.lua index 71c5cfdda..e53a4a3ce 100644 --- a/mods/MAPGEN/mcl_villages/foundation.lua +++ b/mods/MAPGEN/mcl_villages/foundation.lua @@ -1,16 +1,34 @@ +local function mcl_log (message) + mcl_util.mcl_log (message, "[Village - Foundation]") +end + +local foundation_materials = {} + +foundation_materials["mcl_core:sand"] = "mcl_core:sandstone" +--"mcl_core:sandstonecarved" + ------------------------------------------------------------------------------- -- function to fill empty space below baseplate when building on a hill ------------------------------------------------------------------------------- -function settlements.ground(pos, pr) -- role model: Wendelsteinkircherl, Brannenburg +function settlements.ground(pos, pr, platform_material) -- role model: Wendelsteinkircherl, Brannenburg local p2 = vector.new(pos) local cnt = 0 + local mat = "mcl_core:dirt" + if not platform_material then + mat = "mcl_core:dirt" + else + mat = platform_material + end + p2.y = p2.y-1 while true do cnt = cnt+1 if cnt > 20 then break end if cnt>pr:next(2,4) then - mat = "mcl_core:stone" + if not platform_material then + mat = "mcl_core:stone" + end end minetest.swap_node(p2, {name=mat}) p2.y = p2.y-1 @@ -40,6 +58,12 @@ function settlements.terraform(settlement_info, pr) end --fheight = schematic_data["hheight"] * 3 -- remove trees and leaves above fheight = schematic_data["hheight"] -- remove trees and leaves above + + local surface_mat = settlement_info[i]["surface_mat"] + mcl_log("Surface material: " .. tostring(surface_mat)) + local platform_mat = foundation_materials[surface_mat] + mcl_log("Foundation material: " .. tostring(platform_mat)) + -- -- now that every info is available -> create platform and clear space above -- @@ -48,7 +72,8 @@ function settlements.terraform(settlement_info, pr) for yi = 0,fheight *3 do if yi == 0 then local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi} - settlements.ground(p, pr) + -- Pass in biome info and make foundations of same material (seed: apple for desert) + settlements.ground(p, pr, platform_mat) else -- write ground -- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 79a6e37cf..7ada9bbcb 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -12,13 +12,14 @@ dofile(settlements.modpath.."/paths.lua") -- settlements.grundstellungen() +local S = minetest.get_translator(minetest.get_current_modname()) local villagegen={} -- -- register block for npc spawn -- minetest.register_node("mcl_villages:stonebrickcarved", { - description = ("Chiseled Stone Village Bricks"), + description = S("Chiseled Stone Village Bricks"), _doc_items_longdesc = doc.sub.items.temp.build, tiles = {"mcl_core_stonebrick_carved.png"}, drop = "mcl_core:stonebrickcarved", @@ -113,7 +114,7 @@ minetest.register_lbm({ -- manually place villages if minetest.is_creative_enabled("") then minetest.register_craftitem("mcl_villages:tool", { - description = "mcl_villages build tool", + description = S("mcl_villages build tool"), inventory_image = "default_tool_woodshovel.png", -- build ssettlement on_place = function(itemstack, placer, pointed_thing) diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr new file mode 100644 index 000000000..b648cd36c --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks=Pierre sculptée du village +mcl_villages build tool=outil de construction de mcl_villages \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr new file mode 100644 index 000000000..4d0e4794f --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks=模様入り石村レンガ +mcl_villages build tool=mcl_villages 構築ツール \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr new file mode 100644 index 000000000..467f31121 --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks=Точёный каменный блок из деревни diff --git a/mods/MAPGEN/mcl_villages/locale/template.txt b/mods/MAPGEN/mcl_villages/locale/template.txt new file mode 100644 index 000000000..464daea9b --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks= +mcl_villages build tool= \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts b/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts index dab65afa4..d4e26fb26 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts and b/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/butcher.mts b/mods/MAPGEN/mcl_villages/schematics/butcher.mts index 1786599dc..06dd25112 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/butcher.mts and b/mods/MAPGEN/mcl_villages/schematics/butcher.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/large_house.mts b/mods/MAPGEN/mcl_villages/schematics/large_house.mts index 3939a2c43..6cc19543e 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/large_house.mts and b/mods/MAPGEN/mcl_villages/schematics/large_house.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/medium_house.mts b/mods/MAPGEN/mcl_villages/schematics/medium_house.mts index fa859ac48..6a90a0cfa 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/medium_house.mts and b/mods/MAPGEN/mcl_villages/schematics/medium_house.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/small_house.mts b/mods/MAPGEN/mcl_villages/schematics/small_house.mts index a3789504e..92c0c150d 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/small_house.mts and b/mods/MAPGEN/mcl_villages/schematics/small_house.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/tavern.mts b/mods/MAPGEN/mcl_villages/schematics/tavern.mts index c26c14dbc..32b905261 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/tavern.mts and b/mods/MAPGEN/mcl_villages/schematics/tavern.mts differ diff --git a/mods/MAPGEN/mcl_villages/utils.lua b/mods/MAPGEN/mcl_villages/utils.lua index 4ee2ccfbf..3b882af0c 100644 --- a/mods/MAPGEN/mcl_villages/utils.lua +++ b/mods/MAPGEN/mcl_villages/utils.lua @@ -40,22 +40,32 @@ function settlements.find_surface(pos, wait) -- go through nodes an find surface while cnt < cnt_max do -- Check Surface_node and Node above - -- - if settlements.surface_mat[surface_node.name] then + if surface_node and settlements.surface_mat[surface_node.name] then local surface_node_plus_1 = get_node({ x=p6.x, y=p6.y+1, z=p6.z}) - if surface_node_plus_1 and surface_node and - (string.find(surface_node_plus_1.name,"air") or - string.find(surface_node_plus_1.name,"snow") or - string.find(surface_node_plus_1.name,"fern") or - string.find(surface_node_plus_1.name,"flower") or - string.find(surface_node_plus_1.name,"bush") or - string.find(surface_node_plus_1.name,"tree") or - string.find(surface_node_plus_1.name,"grass")) + + if surface_node_plus_1 then + + local surface_node_minus_1 = get_node({ x=p6.x, y=p6.y-1, z=p6.z}) + local is_leaf_below = minetest.get_item_group(surface_node_minus_1, "leaves") ~= 0 or + string.find(surface_node_minus_1.name,"leaves") + + if not is_leaf_below and ((string.find(surface_node_plus_1.name,"air") or + string.find(surface_node_plus_1.name,"fern") or + string.find(surface_node_plus_1.name,"flower") or + string.find(surface_node_plus_1.name,"bush") or + string.find(surface_node_plus_1.name,"tree") or + string.find(surface_node_plus_1.name,"grass")) or + string.find(surface_node_plus_1.name,"snow")) then - settlements.debug("find_surface7: " ..surface_node.name.. " " .. surface_node_plus_1.name) + settlements.debug("find_surface success: " ..surface_node.name.. " " .. surface_node_plus_1.name) + settlements.debug("node below: " .. tostring(surface_node_minus_1.name)) + settlements.debug("node below leaves group: " .. tostring(minetest.get_item_group(surface_node_minus_1, "leaves"))) return p6, surface_node.name + else + settlements.debug("find_surface2: wrong surface+1") + end else - settlements.debug("find_surface2: wrong surface+1") + settlements.debug("find_surface8: missing node or plus_1") end else settlements.debug("find_surface3: wrong surface "..surface_node.name.." at pos "..minetest.pos_to_string(p6)) diff --git a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua index de4b18119..4a27586a2 100644 --- a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua +++ b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua @@ -42,6 +42,14 @@ tsm_railcorridors.carts = { "mcl_minecarts:minecart" } function tsm_railcorridors.on_construct_cart(pos, cart) -- TODO: Fill cart with treasures + + -- This is it? There's this giant hack announced in + -- the other file and I grep for the function and it's + -- a stub? :) + + -- The path here using some minetest.after hackery was + -- deactivated in init.lua - reactivate when this does + -- something the function is called RecheckCartHack. end -- Fallback function. Returns a random treasure. This function is called for chests @@ -84,7 +92,7 @@ function tsm_railcorridors.get_treasures(pr) { itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 }, { itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 }, { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 5 }, - { itemstring = "mcl_dye:blue", weight = 5, amount_min = 4, amount_max = 9 }, + { itemstring = "mcl_core:lapis", weight = 5, amount_min = 4, amount_max = 9 }, { itemstring = "mesecons:redstone", weight = 5, amount_min = 4, amount_max = 9 }, { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_core:diamond", weight = 3, amount_min = 1, amount_max = 2 }, diff --git a/mods/MAPGEN/tsm_railcorridors/init.lua b/mods/MAPGEN/tsm_railcorridors/init.lua index 451406167..d68c58aa3 100644 --- a/mods/MAPGEN/tsm_railcorridors/init.lua +++ b/mods/MAPGEN/tsm_railcorridors/init.lua @@ -364,18 +364,24 @@ local function Platform(p, radius, node, node2) if not node2 then node2 = { name = tsm_railcorridors.nodes.dirt } end + local n1 = {} + local n2 = {} for zi = p.z-radius, p.z+radius do for xi = p.x-radius, p.x+radius do local np, np2 = NeedsPlatform({x=xi,y=p.y,z=zi}) if np then if np2 then - minetest.set_node({x=xi,y=p.y-1,z=zi}, node2) + --minetest.set_node({x=xi,y=p.y-1,z=zi}, node2) + table.insert(n1,{x=xi,y=p.y-1,z=zi}) else - minetest.set_node({x=xi,y=p.y-1,z=zi}, node) + --minetest.set_node({x=xi,y=p.y-1,z=zi}, node) + table.insert(n2,{x=xi,y=p.y-1,z=zi}) end end end end + minetest.bulk_set_node(n1,node) + minetest.bulk_set_node(n2,node2) end -- Chests @@ -388,11 +394,16 @@ local function PlaceChest(pos, param2) end end + -- This function checks if a cart has ACTUALLY been spawned. -- To be calld by minetest.after. -- This is a workaround thanks to the fact that minetest.add_entity is unreliable as fuck -- See: https://github.com/minetest/minetest/issues/4759 -- FIXME: Kill this horrible hack with fire as soon you can. + +-- Why did anyone activate it in the first place? It doesn't +-- have a function seeing as there are no chest minecarts yet. +--[[ local function RecheckCartHack(params) local pos = params[1] local cart_id = params[2] @@ -408,6 +419,8 @@ local function RecheckCartHack(params) end minetest.log("info", "[tsm_railcorridors] Cart spawn FAILED: "..minetest.pos_to_string(pos)) end +--]] + -- Try to place a cobweb. -- pos: Position of cobweb @@ -937,7 +950,10 @@ local function spawn_carts() -- Note that the callback function is also called there. -- TODO: Move callback function to this position when the -- minetest.add_entity bug has been fixed. - minetest.after(3, RecheckCartHack, {cpos, cart_id}) + + -- minetest.after(3, RecheckCartHack, {cpos, cart_id}) + -- This whole recheck logic leads to a stub right now + -- it can be reenabled when chest carts are a thing. end end carts_table = {} @@ -1092,6 +1108,28 @@ local function create_corridor_system(main_cave_coords) return true end +mcl_structures.register_structure("mineshaft",{ + place_on = {"group:sand","group:grass_block","mcl_core:water_source","group:dirt","mcl_core:dirt_with_grass","mcl_core:gravel","group:material_stone","mcl_core:snow"}, + fill_ratio = 0.0001, + flags = "place_center_x, place_center_z, force_placement, all_floors", + sidelen = 32, + y_max = 40, + y_min = mcl_vars.mg_overworld_min, + place_func = function(pos,def,pr,blockseed) + local r = pr:next(-50,-10) + local p = vector.offset(pos,0,r,0) + if p.y < mcl_vars.mg_overworld_min + 5 then + p.y = mcl_vars.mg_overworld_min + 5 + end + if p.y > -10 then return true end + InitRandomizer(blockseed) + create_corridor_system(p, pr) + return true + end, + +}) + +--[[ Old Generation code this is VERY slow -- The rail corridor algorithm starts here mcl_mapgen_core.register_generator("railcorridors", nil, function(minp, maxp, blockseed, _pr) -- We re-init the randomizer for every mapchunk as we start generating in the middle of each mapchunk. @@ -1120,3 +1158,4 @@ mcl_mapgen_core.register_generator("railcorridors", nil, function(minp, maxp, bl end end end, 10) +--]] diff --git a/mods/MAPGEN/tsm_railcorridors/mod.conf b/mods/MAPGEN/tsm_railcorridors/mod.conf index c846cff19..d1a9ada4a 100644 --- a/mods/MAPGEN/tsm_railcorridors/mod.conf +++ b/mods/MAPGEN/tsm_railcorridors/mod.conf @@ -1,4 +1,4 @@ name = tsm_railcorridors author = UgnilJoZ description = Adds simple underground mines with railways and occasional treasure chests. -depends = mcl_init, mcl_worlds, mcl_core, mcl_mapgen_core, mcl_loot, mcl_tnt, mcl_farming, mcl_mobspawners, mcl_minecarts +depends = mcl_init, mcl_worlds, mcl_core, mcl_mapgen_core, mcl_loot, mcl_tnt, mcl_farming, mcl_mobspawners, mcl_minecarts, mcl_structures diff --git a/mods/MISC/findbiome/locale/findbiome.ja.tr b/mods/MISC/findbiome/locale/findbiome.ja.tr new file mode 100644 index 000000000..60eb7e3c8 --- /dev/null +++ b/mods/MISC/findbiome/locale/findbiome.ja.tr @@ -0,0 +1,10 @@ +# textdomain: findbiome +Find and teleport to biome=バイオームを探し、テレポート +=<バイオーム> +No player.=プレイヤーがいません。 +Biome does not exist!=バイオームが存在しません! +Biome found at @1.=@1 で発見したバイオームです。 +No biome found!=バイオームが見つかりません! +List all biomes=バイオームの全リスト +No biomes.=バイオームがありません。 +Not supported. The “biomeinfo” mod is required for v6 mapgen support!=サポートされていません。v6 mapgen のサポートには "biomeinfo" モッドが必要です! diff --git a/mods/MISC/mcl_commands/locale/mcl_commands.ja.tr b/mods/MISC/mcl_commands/locale/mcl_commands.ja.tr new file mode 100644 index 000000000..16f7d357c --- /dev/null +++ b/mods/MISC/mcl_commands/locale/mcl_commands.ja.tr @@ -0,0 +1,23 @@ +# textdomain: mcl_commands +Players can't be killed right now, damage has been disabled.=今、プレイヤーを殺ることはできません。ダメージは無効になっています。 +Player @1 does not exist.=プレイヤー @1 は存在しません。 +You are already dead=あなたはもう死んでいる +@1 is already dead=@1 はもう死んでいる +@1 committed suicide.=@1 は自害しました。 +@1 was killed by @2.=@1 は @2 に殺られました。 +[]=[<名前>] +Kill player or yourself=プレイヤーまたは自分自身を殺害 +Can use /say= /say を使用可能 +=<メッセージ> +Send a message to every player=全プレイヤーにメッセージを送信 +Invalid usage, see /help say.=無効な使用方法です、 /help say を参照してください。 +,, =,, <ノード文字列> +Set node at given position=指定された位置にノードを設定 +Invalid node=無効なノード +@1 spawned.=@1 がスポーンしました。 +Invalid parameters (see /help setblock)=無効なパラメータ ( /help setblock を参照の事) +List bans=BANのリスト +Ban list: @1=BANリスト: @1 +Show who is logged on=誰がログオンしているかを表示 +Displays the world seed=ワールドのシードを表示 +Only peaceful mobs allowed!=平和的なモブのみ許されます! diff --git a/mods/MISC/mcl_privs/locale/mcl_privs.ja.tr b/mods/MISC/mcl_privs/locale/mcl_privs.ja.tr new file mode 100644 index 000000000..7b8a9fbc7 --- /dev/null +++ b/mods/MISC/mcl_privs/locale/mcl_privs.ja.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_privs +Can place and use advanced blocks like mob spawners, command blocks and barriers.=モブスポナー、コマンドブロック、バリアなどの高度なブロックを配置・使用できます。 diff --git a/mods/MISC/mcl_wip/locale/mcl_wip.ja.tr b/mods/MISC/mcl_wip/locale/mcl_wip.ja.tr new file mode 100644 index 000000000..7c3b3d14d --- /dev/null +++ b/mods/MISC/mcl_wip/locale/mcl_wip.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_wip +# WIP means “Work in Progress” +(WIP)=(制作途中) +(Temporary)=(仮) diff --git a/mods/PLAYER/mcl_death_drop/init.lua b/mods/PLAYER/mcl_death_drop/init.lua index 5ea548ecc..9b1bad75f 100644 --- a/mods/PLAYER/mcl_death_drop/init.lua +++ b/mods/PLAYER/mcl_death_drop/init.lua @@ -33,21 +33,20 @@ 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 + local dropspots = minetest.find_nodes_in_area(vector.offset(pos,-3,0,-3),vector.offset(pos,3,0,3),{"air"}) + if #dropspots == 0 then + table.insert(dropspots,pos) + end if inv then for i, stack in ipairs(inv:get_list(listname)) do - local x = random(0, 9)/3 - local z = random(0, 9)/3 - pos.x = pos.x + x - pos.z = pos.z + z + local p = vector.offset(dropspots[math.random(#dropspots)],math.random()-0.5,math.random()-0.5,math.random()-0.5) if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then local def = minetest.registered_items[stack:get_name()] if def and def.on_drop then - stack = def.on_drop(stack, player, pos) + stack = def.on_drop(stack, player, p) end - minetest.add_item(pos, stack) + minetest.add_item(p, stack) end - pos.x = pos.x - x - pos.z = pos.z - z end inv:set_list(listname, {}) end diff --git a/mods/PLAYER/mcl_hunger/api.lua b/mods/PLAYER/mcl_hunger/api.lua index 20937023a..3c9cd97e9 100644 --- a/mods/PLAYER/mcl_hunger/api.lua +++ b/mods/PLAYER/mcl_hunger/api.lua @@ -67,7 +67,7 @@ if mcl_hunger.active then local satuchanged = false local s = mcl_hunger.get_saturation(player) if s > 0 then - mcl_hunger.set_saturation(player, math.max(s - 1.0, 0)) + mcl_hunger.set_saturation(player, math.max(s - 1.5, 0)) satuchanged = true elseif s <= 0.0001 then h = mcl_hunger.get_hunger(player) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 21c1e0860..321139c5f 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -11,10 +11,9 @@ Hunger is enabled when damage is enabled. If the damage setting is changed within the game, this does NOT update the hunger mechanic, so the game must be restarted for this to take effect. ]] -if minetest.settings:get_bool("enable_damage") == true then +mcl_hunger.active = false +if minetest.settings:get_bool("enable_damage") == true and minetest.settings:get_bool("mcl_enable_hunger") ~= false then mcl_hunger.active = true -else - mcl_hunger.active = false end mcl_hunger.HUD_TICK = 0.1 @@ -28,6 +27,7 @@ mcl_hunger.EXHAUST_SWIM = 10 -- player movement in water mcl_hunger.EXHAUST_SPRINT = 100 -- sprint (per node) mcl_hunger.EXHAUST_DAMAGE = 100 -- taking damage (protected by armor) mcl_hunger.EXHAUST_REGEN = 6000 -- Regenerate 1 HP +mcl_hunger.EXHAUST_HUNGER = 5 -- Hunger status effect at base level. mcl_hunger.EXHAUST_LVL = 4000 -- at what exhaustion player saturation gets lowered mcl_hunger.SATURATION_INIT = 5 -- Initial saturation for new/respawning players @@ -84,6 +84,9 @@ function mcl_hunger.update_saturation_hud(player, saturation, hunger) end function mcl_hunger.update_exhaustion_hud(player, exhaustion) if mcl_hunger.debug then + if not exhaustion then + exhaustion = mcl_hunger.get_exhaustion(player) + end hb.change_hudbar(player, "exhaustion", exhaustion) end end @@ -147,11 +150,17 @@ minetest.register_globalstep(function(dtime) if food_tick_timer > 4.0 then food_tick_timer = 0 - if food_level >= 18 then -- slow regenration + -- let hunger work always + if player_health > 0 and player_health <= 20 then + --mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_HUNGER) -- later for hunger status effect + mcl_hunger.update_exhaustion_hud(player) + end + + if food_level >= 18 then -- slow regeneration if player_health > 0 and player_health < 20 then player:set_hp(player_health+1) mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + mcl_hunger.update_exhaustion_hud(player) end elseif food_level == 0 then -- starvation @@ -164,12 +173,12 @@ minetest.register_globalstep(function(dtime) end end - elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level >= 6 then -- fast regeneration + elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level > 0 then -- fast regeneration if player_health > 0 and player_health < 20 then food_tick_timer = 0 player:set_hp(player_health+1) mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) + mcl_hunger.update_exhaustion_hud(player) end end diff --git a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ja.tr b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ja.tr new file mode 100644 index 000000000..8e5fe234a --- /dev/null +++ b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_hunger +@1 succumbed to the poison.=@1 は毒にやられました。 +Food=食料 +Saturation=満腹状態 +%s: %.1f/%d= +Exhaust.=尽きた。 +%s: %d/%d= +@1 starved to death.=@1 は餓死しました。 diff --git a/mods/PLAYER/mcl_meshhand/init.lua b/mods/PLAYER/mcl_meshhand/init.lua index 93f22c325..1cc31f601 100644 --- a/mods/PLAYER/mcl_meshhand/init.lua +++ b/mods/PLAYER/mcl_meshhand/init.lua @@ -1,79 +1,57 @@ -local has_mcl_skins = minetest.get_modpath("mcl_skins") ~= nil +local mcl_skins_enabled = minetest.global_exists("mcl_skins") -local def = minetest.registered_items[""] +---This is a fake node that should never be placed in the world +---@type node_definition +local node_def = { + use_texture_alpha = "opaque", + paramtype = "light", + drawtype = "mesh", + node_placement_prediction = "", + on_construct = function(pos) + local name = minetest.get_node(pos).name + local message = "[mcl_meshhand] Trying to construct " .. name .. " at " .. minetest.pos_to_string(pos) + minetest.log("error", message) + minetest.remove_node(pos) + end, + drop = "", + on_drop = function(_, _, _) return ItemStack() end, + groups = { dig_immediate = 3, not_in_creative_inventory = 1 }, + range = minetest.registered_items[""].range +} -local list --- mcl_skins is enabled -if has_mcl_skins == true then - list = mcl_skins.list -else - list = { "hand" } -end - ---generate a node for every skin -for _,texture in pairs(list) do - -- This is a fake node that should never be placed in the world - minetest.register_node("mcl_meshhand:"..texture, { - description = "", - tiles = {texture..".png"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - visual_scale = 1, - wield_scale = {x=1,y=1,z=1}, - paramtype = "light", - drawtype = "mesh", - mesh = "mcl_meshhand.b3d", - -- Prevent construction - node_placement_prediction = "", - on_construct = function(pos) - minetest.log("error", "[mcl_meshhand] Trying to construct mcl_meshhand:"..texture.." at "..minetest.pos_to_string(pos)) - minetest.remove_node(pos) - end, - drop = "", - on_drop = function() - return "" - end, - groups = { dig_immediate = 3, not_in_creative_inventory = 1 }, - range = def.range, - _mcl_hand_id = texture, - }) - - minetest.register_node("mcl_meshhand:"..texture.. "_female", { - description = "", - tiles = {texture..".png"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - visual_scale = 1, - wield_scale = {x=1,y=1,z=1}, - paramtype = "light", - drawtype = "mesh", - mesh = "mcl_meshhand_female.b3d", - -- Prevent construction - node_placement_prediction = "", - on_construct = function(pos) - minetest.log("error", "[mcl_meshhand] Trying to construct mcl_meshhand:"..texture.." at "..minetest.pos_to_string(pos)) - minetest.remove_node(pos) - end, - drop = "", - on_drop = function() - return "" - end, - groups = { dig_immediate = 3, not_in_creative_inventory = 1 }, - range = def.range, - _mcl_hand_id = texture .. "_female", - }) -end - -if has_mcl_skins == true then - --change the player's hand to their skin - mcl_skins.register_on_set_skin(function(player, skin) - local meta = mcl_skins.meta[skin] - if meta.gender == "female" then - player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin.."_female") +if mcl_skins_enabled then + -- Generate a node for every skin + local list = mcl_skins.get_skin_list() + for _, skin in pairs(list) do + if skin.slim_arms then + local female = table.copy(node_def) + female._mcl_hand_id = skin.id + female.mesh = "mcl_meshhand_female.b3d" + female.tiles = { skin.texture } + minetest.register_node("mcl_meshhand:" .. skin.id, female) else - player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin) + local male = table.copy(node_def) + male._mcl_hand_id = skin.id + male.mesh = "mcl_meshhand.b3d" + male.tiles = { skin.texture } + minetest.register_node("mcl_meshhand:" .. skin.id, male) end + end +else + node_def._mcl_hand_id = "hand" + node_def.mesh = "mcl_meshhand.b3d" + node_def.tiles = { "character.png" } + minetest.register_node("mcl_meshhand:hand", node_def) +end + +if mcl_skins_enabled then + -- Change the player's hand to their skin + mcl_player.register_on_visual_change(function(player) + local node_id = mcl_skins.get_node_id_by_player(player) + player:get_inventory():set_stack("hand", 1, "mcl_meshhand:" .. node_id) end) else minetest.register_on_joinplayer(function(player) - player:get_inventory():set_stack("hand", 1, "mcl_meshhand:hand") + player:get_inventory():set_stack("hand", 1, ItemStack("mcl_meshhand:hand")) end) end diff --git a/mods/PLAYER/mcl_meshhand/mod.conf b/mods/PLAYER/mcl_meshhand/mod.conf index 6a988417f..a95edb858 100644 --- a/mods/PLAYER/mcl_meshhand/mod.conf +++ b/mods/PLAYER/mcl_meshhand/mod.conf @@ -1,6 +1,5 @@ name = mcl_meshhand author = jordan4ibanez description = Applies the player skin texture to the hand. -depends = mcl_tools +depends = mcl_tools, mcl_player optional_depends = mcl_skins - diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 4824bc9e3..6c521be72 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -1,3 +1,5 @@ +local sf = string.format + -- Minetest 0.4 mod: player -- See README.txt for licensing and other information. mcl_player = {} @@ -53,17 +55,55 @@ local player_model = {} local player_textures = {} local player_anim = {} local player_sneak = {} +local player_visible = {} mcl_player.player_attached = {} function mcl_player.player_get_animation(player) local name = player:get_player_name() + local textures = player_textures[name] + + if not player_visible[name] then + textures = table.copy(textures) + textures[1] = "blank.png" + end + return { model = player_model[name], - textures = player_textures[name], + textures = textures, animation = player_anim[name], + visibility = player_visibility[name] } end +local registered_on_visual_change = {} + +function mcl_player.register_on_visual_change(func) + table.insert(registered_on_visual_change, func) +end + +local function update_player_textures(player) + local name = player:get_player_name() + local textures = player_textures[name] + + if not player_visible[name] then + textures = table.copy(textures) + textures[1] = "blank.png" + end + + player:set_properties({ textures = textures }) + + -- Delay calling the callbacks because mods (including mcl_player) + -- need to fully initialize player data from minetest.register_on_joinplayer + -- before callbacks run + minetest.after(0.1, function() + if player:is_player() then + for i, func in ipairs(registered_on_visual_change) do + func(player) + end + end + end) +end + -- Called when a player's appearance needs to be updated function mcl_player.player_set_model(player, model_name) local name = player:get_player_name() @@ -74,11 +114,11 @@ function mcl_player.player_set_model(player, model_name) end player:set_properties({ mesh = model_name, - textures = player_textures[name] or model.textures, visual = "mesh", visual_size = model.visual_size or {x=1, y=1}, damage_texture_modifier = "^[colorize:red:130", }) + update_player_textures(player) mcl_player.player_set_animation(player, "stand") else player:set_properties({ @@ -89,29 +129,36 @@ function mcl_player.player_set_model(player, model_name) player_model[name] = model_name end -local function set_texture(player, index, texture) - local textures = player_textures[player:get_player_name()] - textures[index] = texture - player:set_properties({textures = textures}) +function mcl_player.player_set_visibility(player, visible) + local name = player:get_player_name() + if player_visible[name] == visible then return end + player_visible[name] = visible + update_player_textures(player) end function mcl_player.player_set_skin(player, texture) - set_texture(player, 1, texture) + local name = player:get_player_name() + player_textures[name][1] = texture + update_player_textures(player) end function mcl_player.player_set_armor(player, texture) - set_texture(player, 2, texture) -end - -function mcl_player.player_set_wielditem(player, texture) - set_texture(player, 3, texture) + local name = player:get_player_name() + player_textures[name][2] = texture + update_player_textures(player) end function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname) local name = player:get_player_name() local model = player_model[name] local anim = models[model].animations[player_anim[name]] - return "model["..x..","..y..";"..w..","..h..";"..fsname..";"..model..";"..table.concat(player_textures[name], ",")..";0,".. 180 ..";false;false;"..anim.x..","..anim.y.."]" + local textures = player_textures[name] + if not player_visible[name] then + textures = table.copy(textures) + textures[1] = "blank.png" + end + return sf("model[%s,%s;%s,%s;%s;%s;%s;0,180;false;false;%s,%s]", x, y, w, h, fsname, model, + table.concat(textures, ","), anim.x, anim.y) end function mcl_player.player_set_animation(player, anim_name, speed) @@ -132,8 +179,9 @@ end minetest.register_on_joinplayer(function(player) local name = player:get_player_name() mcl_player.player_attached[name] = false + player_visible[name] = true mcl_player.player_set_model(player, "character.b3d") - player_textures[name] = {"blank.png", "blank.png", "blank.png"} + player_textures[name] = {"character.png", "blank.png", "blank.png"} --player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30) player:set_fov(86.1) -- see >>> end) @@ -143,6 +191,8 @@ minetest.register_on_leaveplayer(function(player) player_model[name] = nil player_anim[name] = nil player_textures[name] = nil + player_sneak[name] = nil + player_visible[name] = nil end) -- Localize for better performance. @@ -184,6 +234,8 @@ minetest.register_globalstep(function(dtime) -- Apply animations based on what the player is doing if player:get_hp() == 0 then player_set_animation(player, "die") + elseif mcl_playerplus.elytra[player] and mcl_playerplus.elytra[player].active then + player_set_animation(player, "stand") elseif walking and velocity.x > 0.35 or walking and velocity.x < -0.35 or walking and velocity.z > 0.35 diff --git a/mods/PLAYER/mcl_playerinfo/init.lua b/mods/PLAYER/mcl_playerinfo/init.lua index 9c5d1433f..1f1b84749 100644 --- a/mods/PLAYER/mcl_playerinfo/init.lua +++ b/mods/PLAYER/mcl_playerinfo/init.lua @@ -33,11 +33,14 @@ local function get_player_nodes(player_pos) work_pos.y = work_pos.y + 1.5 -- head level local node_head = node_ok(work_pos) + work_pos.y = work_pos.y + 0.5 -- top of head level, at collision box height + local node_head_top = node_ok(work_pos) + work_pos.y = work_pos.y - 0.5 work_pos.y = work_pos.y - 1.2 -- feet level local node_feet = node_ok(work_pos) - return node_stand, node_stand_below, node_head, node_feet + return node_stand, node_stand_below, node_head, node_feet, node_head_top end minetest.register_globalstep(function(dtime) @@ -62,11 +65,12 @@ minetest.register_globalstep(function(dtime) local pos = player:get_pos() -- what is around me? - local node_stand, node_stand_below, node_head, node_feet = get_player_nodes(pos) + local node_stand, node_stand_below, node_head, node_feet, node_head_top = get_player_nodes(pos) mcl_playerinfo[name].node_stand = node_stand mcl_playerinfo[name].node_stand_below = node_stand_below mcl_playerinfo[name].node_head = node_head mcl_playerinfo[name].node_feet = node_feet + mcl_playerinfo[name].node_head_top = node_head_top end @@ -81,6 +85,7 @@ minetest.register_on_joinplayer(function(player) node_feet = "", node_stand = "", node_stand_below = "", + node_head_top = "", } end) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 924b60c97..0faa9c53f 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,8 +1,10 @@ mcl_playerplus = { elytra = {}, + is_pressing_jump = {}, } -local player_velocity_old = {x=0, y=0, z=0} +local hud_water = {} + local get_connected_players = minetest.get_connected_players local dir_to_yaw = minetest.dir_to_yaw local get_item_group = minetest.get_item_group @@ -25,6 +27,26 @@ local mcl_playerplus_internal = {} local time = 0 local look_pitch = 0 + +local function calculate_water_depth(pos) + for i=1, 50 do + if get_item_group(minetest.get_node(vector.new(pos.x,pos.y+i,pos.z)).name, "water") == 0 then + return i + end + end + return 50 +end + +local function remove_water_hud(player) + if hud_water[player] then + mcl_weather.skycolor.update_sky_color() + for i=1, #hud_water[player] do + player:hud_remove(hud_water[player][i]) + end + hud_water[player] = nil + end +end + local function player_collision(player) local pos = player:get_pos() @@ -118,102 +140,58 @@ function limit_vel_yaw(player_vel_yaw, yaw) return player_vel_yaw end -local node_stand, node_stand_below, node_head, node_feet +local node_stand, node_stand_below, node_head, node_feet, node_head_top +local is_swimming --- 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 set_bone_pos = mcl_util.set_bone_position +local set_properties = mcl_util.set_properties -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) +local function get_overall_velocity(vector) + local v = math.sqrt(vector.x^2 + vector.y^2 + vector.z^2) + return v +end +local function anglediff(a1, a2) + local a = a1 - a2 + return math.abs((a + math.pi) % (math.pi*2) - math.pi) +end +local function clamp(num, min, max) + return math.min(max, math.max(num, min)) end +local elytra_vars = { + slowdown_mult = 0.0, -- amount of vel to take per sec + fall_speed = 0.2, -- amount of vel to fall down per sec + speedup_mult = 2, -- amount of speed to add based on look dir + max_speed = 6, -- max amount to multiply against look direction when flying + pitch_penalty = 1.3, -- if pitching up, slow down at this rate as a multiplier + rocket_speed = 5.5, +} +local player_props_elytra = { + collisionbox = { -0.35, 0, -0.35, 0.35, 0.8, 0.35 }, + eye_height = 0.5, + nametag_color = { r = 225, b = 225, a = 225, g = 225 } +} +local player_props_riding = { + collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, + eye_height = 1.5, + nametag_color = { r = 225, b = 225, a = 225, g = 225 } +} +local player_props_sneaking = { + collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, + eye_height = 1.35, + nametag_color = { r = 225, b = 225, a = 0, g = 225 } +} +local player_props_swimming = { + collisionbox = { -0.312, 0, -0.312, 0.312, 0.8, 0.312 }, + eye_height = 0.5, + nametag_color = { r = 225, b = 225, a = 225, g = 225 } +} +local player_props_normal = { + collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, + eye_height = 1.5, + nametag_color = { r = 225, b = 225, a = 225, g = 225 } +} minetest.register_globalstep(function(dtime) @@ -258,34 +236,57 @@ minetest.register_globalstep(function(dtime) player_vel_yaws[name] = player_vel_yaw local fly_pos = player:get_pos() - local fly_node = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.5, z = fly_pos.z}).name + local fly_node = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.1, z = fly_pos.z}).name local elytra = mcl_playerplus.elytra[player] + if not elytra.active then + elytra.speed = 0 + end + + if not elytra.last_yaw then + elytra.last_yaw = player:get_look_horizontal() + end + + local is_just_jumped = control.jump and not mcl_playerplus.is_pressing_jump[name] and not elytra.active + mcl_playerplus.is_pressing_jump[name] = control.jump + if is_just_jumped and not elytra.active then + local direction = player:get_look_dir() + elytra.speed = 1 - (direction.y/2 + 0.5) + end + elytra.active = player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" - and not player:get_attach() - and (elytra.active or control.jump and player_velocity.y < -6) - and (fly_node == "air" or fly_node == "ignore") + and not parent + and (elytra.active or (is_just_jumped and player_velocity.y < -0)) + and ((not minetest.registered_nodes[fly_node].walkable) or fly_node == "ignore") if elytra.active then + if is_just_jumped then -- move the player up when they start flying to give some clearance + player:set_pos(vector.offset(player:get_pos(), 0, 0.8, 0)) + end mcl_player.player_set_animation(player, "fly") - if player_velocity.y < -1.5 then - player:add_velocity({x=0, y=0.17, z=0}) - end - if math.abs(player_velocity.x) + math.abs(player_velocity.z) < 20 then - local dir = minetest.yaw_to_dir(player:get_look_horizontal()) - if degrees(player:get_look_vertical()) * -.01 < .1 then - look_pitch = degrees(player:get_look_vertical()) * -.01 - else - look_pitch = .1 - end - player:add_velocity({x=dir.x, y=look_pitch, z=dir.z}) - end - playerphysics.add_physics_factor(player, "gravity", "mcl_playerplus:elytra", 0.1) + local direction = player:get_look_dir() + local player_vel = player:get_velocity() + local turn_amount = anglediff(minetest.dir_to_yaw(direction), minetest.dir_to_yaw(player_vel)) + local direction_mult = clamp(-(direction.y+0.1), -1, 1) + if direction_mult < 0 then direction_mult = direction_mult * elytra_vars.pitch_penalty end + local speed_mult = elytra.speed + local block_below = minetest.get_node(vector.offset(fly_pos, 0, -0.9, 0)).name + if (not minetest.registered_nodes[block_below].walkable) and (player_vel.y ~= 0) then + speed_mult = speed_mult + direction_mult * elytra_vars.speedup_mult * dtime + end + speed_mult = speed_mult - elytra_vars.slowdown_mult * clamp(dtime, 0.09, 0.2) -- slow down but don't overdo it + speed_mult = clamp(speed_mult, -elytra_vars.max_speed, elytra_vars.max_speed) + if turn_amount > 0.3 and math.abs(direction.y) < 0.98 then -- don't do this if looking straight up / down + speed_mult = speed_mult - (speed_mult * (turn_amount / (math.pi*8))) + end + + playerphysics.add_physics_factor(player, "gravity", "mcl_playerplus:elytra", elytra_vars.fall_speed) if elytra.rocketing > 0 then elytra.rocketing = elytra.rocketing - dtime if vector.length(player_velocity) < 40 then - player:add_velocity(vector.multiply(player:get_look_dir(), 4)) + -- player:add_velocity(vector.multiply(player:get_look_dir(), 4)) + speed_mult = elytra_vars.rocket_speed add_particle({ pos = fly_pos, velocity = {x = 0, y = 0, z = 0}, @@ -299,90 +300,143 @@ minetest.register_globalstep(function(dtime) }) end end - else + + elytra.speed = speed_mult -- set the speed so you can keep track of it and add to it + + local new_vel = vector.multiply(direction, speed_mult * dtime * 30) -- use the look dir and speed as a mult + -- new_vel.y = new_vel.y - elytra_vars.fall_speed * dtime -- make the player fall a set amount + + -- slow the player down so less spongy movement by applying some of the inverse velocity + -- NOTE: do not set this higher than about 0.2 or the game will get the wrong vel and it will be broken + -- this is far from ideal, but there's no good way to set_velocity or slow down the player + player_vel = vector.multiply(player_vel, -0.1) + -- if speed_mult < 1 then player_vel.y = player_vel.y * 0.1 end + new_vel = vector.add(new_vel, player_vel) + + player:add_velocity(new_vel) + else -- reset things when you stop flying with elytra elytra.rocketing = 0 playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra") end if wielded_def and wielded_def._mcl_toollike_wield then - set_bone_position_conditional(player,"Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) + set_bone_pos(player, "Wield_Item", vector.new(0, 4.7, 3.1), vector.new(-90, 225, 90)) elseif string.find(wielded:get_name(), "mcl_bows:bow") then - set_bone_position_conditional(player,"Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) + set_bone_pos(player, "Wield_Item", vector.new(1, 4, 0), vector.new(90, 130, 115)) elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then - set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(64,90,0)) + set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 180, 73)) elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then - set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(90,90,0)) + set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 180, 45)) + elseif wielded_def.inventory_image == "" then + set_bone_pos(player,"Wield_Item", vector.new(0, 6, 2), vector.new(180, -45, 0)) else - set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) + set_bone_pos(player, "Wield_Item", vector.new(0, 5.3, 2), vector.new(90, 0, 0)) end - player_velocity_old = player:get_velocity() or player:get_player_velocity() - - -- 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)) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, 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)) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(20, 20, 0)) elseif string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then - 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)) + local right_arm_rot = vector.new(pitch + 90, -30, pitch * -1 * .35) + local left_arm_rot = vector.new(pitch + 90, 43, pitch * .35) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot) -- controls right and left arms pitch when holing a loaded crossbow elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then - 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)) + local right_arm_rot = vector.new(pitch + 90, -30, pitch * -1 * .35) + local left_arm_rot = vector.new(pitch + 90, 43, pitch * .35) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot) -- controls right and left arms pitch when loading a crossbow elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then - set_bone_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)) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(45, -20, 25)) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(55, 20, -45)) -- when punching elseif control.LMB and not parent then - set_bone_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)) + set_bone_pos(player,"Arm_Right_Pitch_Control", nil, vector.new(pitch, 0, 0)) + set_bone_pos(player,"Arm_Left_Pitch_Control", nil, vector.zero()) -- when holding an item. elseif wielded:get_name() ~= "" then - set_bone_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)) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(20, 0, 0)) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.zero()) -- resets arms pitch else - set_bone_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)) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.zero()) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.zero()) end if elytra.active then -- set head pitch and yaw when flying - 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)) + local head_rot = vector.new(pitch - degrees(dir_to_pitch(player_velocity)) + 50, player_vel_yaw - yaw, 0) + set_bone_pos(player,"Head_Control", nil, head_rot) + -- sets eye height, and nametag color accordingly - set_properties_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 }}) + set_properties(player, player_props_elytra) + -- control body bone when flying - 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)) + local body_rot = vector.new((75 - degrees(dir_to_pitch(player_velocity))), -player_vel_yaw + yaw, 0) + set_bone_pos(player, "Body_Control", nil, body_rot) elseif parent then + set_properties(player, player_props_riding) + local parent_yaw = degrees(parent:get_yaw()) - 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)) + local head_rot = vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0) + set_bone_pos(player, "Head_Control", nil, head_rot) + set_bone_pos(player,"Body_Control", nil, vector.zero()) elseif control.sneak then -- controls head pitch when sneaking - set_bone_position_conditional(player,"Head_Control", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, player_vel_yaw - yaw)) + local head_rot = vector.new(pitch, player_vel_yaw - yaw, player_vel_yaw - yaw) + set_bone_pos(player, "Head_Control", nil, head_rot) + -- sets eye height, and nametag color accordingly - set_properties_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 }}) + set_properties(player, player_props_sneaking) + -- sneaking body conrols - set_bone_position_conditional(player,"Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0)) + set_bone_pos(player, "Body_Control", nil, vector.new(0, -player_vel_yaw + yaw, 0)) elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then -- set head pitch and yaw when swimming - 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 - 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 - 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 - 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 }}) + is_swimming = true + local head_rot = vector.new(pitch - degrees(dir_to_pitch(player_velocity)) + 20, player_vel_yaw - yaw, 0) + set_bone_pos(player, "Head_Control", nil, head_rot) - 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)) + -- sets eye height, and nametag color accordingly + set_properties(player, player_props_swimming) + + -- control body bone when swimming + local body_rot = vector.new((75 + degrees(dir_to_pitch(player_velocity))), player_vel_yaw - yaw, 180) + set_bone_pos(player,"Body_Control", nil, body_rot) + elseif get_item_group(mcl_playerinfo[name].node_head, "solid") == 0 + and get_item_group(mcl_playerinfo[name].node_head_top, "solid") == 0 then + -- sets eye height, and nametag color accordingly + is_swimming = false + set_properties(player, player_props_normal) + + set_bone_pos(player,"Head_Control", nil, vector.new(pitch, player_vel_yaw - yaw, 0)) + set_bone_pos(player,"Body_Control", nil, vector.new(0, -player_vel_yaw + yaw, 0)) end + if get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 then + if not hud_water[player] or hud_water[player] and calculate_water_depth(player:get_pos()) ~= #hud_water[player] then + remove_water_hud(player) + hud_water[player] = {} + for i=1, calculate_water_depth(player:get_pos()) do + table.insert(hud_water[player], player:hud_add({ + hud_elem_type = "image", + text = "mcl_playerplus_water.png", + position = {x = 0.5, y = 0.5}, + scale = {x = 32, y = 16}, + offset = {x = 0, y = 0}, + z_index = -1002, + })) + end + end + else + remove_water_hud(player) + end + + elytra.last_yaw = player:get_look_horizontal() -- Update jump status immediately since we need this info in real time. -- WARNING: This section is HACKY as hell since it is all just based on heuristics. @@ -398,10 +452,15 @@ minetest.register_globalstep(function(dtime) node_stand_below = mcl_playerinfo[name].node_stand_below node_head = mcl_playerinfo[name].node_head node_feet = mcl_playerinfo[name].node_feet + node_head_top = mcl_playerinfo[name].node_head_top if not node_stand or not node_stand_below or not node_head or not node_feet then return end - if not minetest.registered_nodes[node_stand] or not minetest.registered_nodes[node_stand_below] or not minetest.registered_nodes[node_head] or not minetest.registered_nodes[node_feet] then + if (not minetest.registered_nodes[node_stand] + or not minetest.registered_nodes[node_stand_below] + or not minetest.registered_nodes[node_head] + or not minetest.registered_nodes[node_feet] + or not minetest.registered_nodes[node_head_top]) then return end @@ -460,7 +519,8 @@ minetest.register_globalstep(function(dtime) local node_stand_below = mcl_playerinfo[name].node_stand_below local node_head = mcl_playerinfo[name].node_head local node_feet = mcl_playerinfo[name].node_feet - if not node_stand or not node_stand_below or not node_head or not node_feet then + local node_head_top = mcl_playerinfo[name].node_head_top + if not node_stand or not node_stand_below or not node_head or not node_feet or not node_head_top then return end @@ -493,8 +553,11 @@ minetest.register_globalstep(function(dtime) -- Is player suffocating inside node? (Only for solid full opaque cube type nodes -- without group disable_suffocation=1) + -- if swimming, check the feet node instead, because the head node will be above the player when swimming local ndef = minetest.registered_nodes[node_head] - + if is_swimming then + ndef = minetest.registered_nodes[node_feet] + end if (ndef.walkable == nil or ndef.walkable == true) and (ndef.collision_box == nil or ndef.collision_box.type == "regular") and (ndef.node_box == nil or ndef.node_box.type == "regular") @@ -616,7 +679,14 @@ minetest.register_on_joinplayer(function(player) swimDistance = 0, jump_cooldown = -1, -- Cooldown timer for jumping, we need this to prevent the jump exhaustion to increase rapidly } - mcl_playerplus.elytra[player] = {active = false, rocketing = 0} + mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0} + + -- Minetest bug: get_bone_position() returns all zeros vectors. + -- Workaround: call set_bone_position() one time first. + player:set_bone_position("Head_Control", vector.new(0, 6.75, 0)) + player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0)) + player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3, 5.785, 0)) + player:set_bone_position("Body_Control", vector.new(0, 6.75, 0)) end) -- clear when player leaves diff --git a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.ja.tr b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.ja.tr new file mode 100644 index 000000000..6395fa64e --- /dev/null +++ b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.ja.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/textures/mcl_playerplus_water.png b/mods/PLAYER/mcl_playerplus/textures/mcl_playerplus_water.png new file mode 100644 index 000000000..0524ce8d6 Binary files /dev/null and b/mods/PLAYER/mcl_playerplus/textures/mcl_playerplus_water.png differ diff --git a/mods/PLAYER/mcl_skins/LICENSE.txt b/mods/PLAYER/mcl_skins/LICENSE.txt index fec6f6aa5..da582622b 100644 --- a/mods/PLAYER/mcl_skins/LICENSE.txt +++ b/mods/PLAYER/mcl_skins/LICENSE.txt @@ -1,5 +1,6 @@ The MIT License (MIT) +Copyright (c) 2022 MrRar Copyright (c) 2016 TenPlus1 Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/mods/PLAYER/mcl_skins/README.md b/mods/PLAYER/mcl_skins/README.md index bbe5309ab..d05bf9a2e 100644 --- a/mods/PLAYER/mcl_skins/README.md +++ b/mods/PLAYER/mcl_skins/README.md @@ -1,13 +1,80 @@ -= Skins for MineClone 2 = +# Mineclone Skins -Simple mod to allow players to select a skin. -Use the chat command /setskin to change skin. +This mod allows advanced skin customization. +Use the /skin command to open the skin configuration screen. -Forked from Simple Skins by TenPlus1. -https://forum.minetest.net/viewtopic.php?id=9100 - -== License == +## License Code under MIT license -Origial authors: -- TenPlus1 -- Zeg9 +Author: TenPlus1, Zeg9, MrRar + +See image_credits.txt for image licensing. + +## API + +### `mcl_skins.register_item(item)` +Register a skin item. `item` is a table with item properties listed below. + +### Item properties +`type` +Set the item type. Valid values are: "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear" + +`texture` +Set to the image file that will be used. If this property is omitted "blank.png" is used. + +`mask` +Set the color mask texture. Coloring is only applied to non transparent areas of the texture. +Coloring only works for "base", "bottom, "top", and "hair". + +`preview_rotation` +A table containing properties x and y. x and y represent the x and y rotation of the item preview. + +`alex` +If set to true the item will be default for female character. + +`steve` +If set to true the item will be default for male character. + + +### `mcl_skins.show_formspec(player, active_tab, page_num)` +Show the skin configuration screen. +`player` is a player ObjectRef. +`active_tab` is the tab that will be displayed. This parameter is optional. +Can be one of: "arm", "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear" + +`page_num` The page number to display of there are multiple pages of items. +This parameter is optional. Must be a number. If it is not a valid page number the closest page number will be shown. + +### `mcl_skins.get_skin_list()` +This function is used by mods that want a list of skins to register nodes that use the player skin as a texture. +Returns an array of tables containing information about each skin. +Each table contains the following properties: + +`id`: A string representing the node ID. A node can be registered using this node ID. +`texture`: A texture string that can be used in the node defintion. +`slim_arms`: A boolean value. If true, this texture is used with the "female" player mesh. Otherwise the regular mesh is to be used. + +### `mcl_skins.get_node_id_by_player(player)` +`player` is a player ObjectRef. +Returns a string node ID based on players current skin for use by mods that want to register nodes that use the player skin. + +### `mcl_skins.save(player)` +Save player skin. `player` is a player ObjectRef. + +### `mcl_skins.update_player_skin(player)` +Update a player based on skin data in mcl_skins.players. +`player` is a player ObjectRef. + +### `mcl_skins.base_color` +A table of ColorSpec integers that the player can select to color the base item. +These colors are separate from `mcl_skins.color` because some mods register two nodes per base color so the amount of base colors needs to be limited. + +### `mcl_skins.color` +A table of ColorSpec integers that the player can select to color colorable skin items. + +### `mcl_skins.players` +A table mapped by player ObjectRef containing tables holding the player's selected skin items and colors. +Only stores skin information for logged in users. + +### mcl_skins.compile_skin(skin) +`skin` is a table with skin item properties. +Returns an image string. diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua new file mode 100644 index 000000000..3ced41d6d --- /dev/null +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -0,0 +1,590 @@ +local S = minetest.get_translator("mcl_skins") +local color_to_string = minetest.colorspec_to_colorstring + +mcl_skins = { + simple_skins = {}, + item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"}, + tab_names = {"template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear"}, + tab_descriptions = { + template = S("Templates"), + arm = S("Arm size"), + base = S("Bases"), + footwear = S("Footwears"), + eye = S("Eyes"), + mouth = S("Mouths"), + bottom = S("Bottoms"), + top = S("Tops"), + hair = S("Hairs"), + headwear = S("Headwears"), + skin = S("Skins"), + }, + steve = {}, -- Stores skin values for Steve skin + alex = {}, -- Stores skin values for Alex skin + base = {}, -- List of base textures + + -- Base color is separate to keep the number of junk nodes registered in check + base_color = {0xffeeb592, 0xffb47a57, 0xff8d471d}, + color = { + 0xff613915, -- 1 Dark brown + 0xff97491b, -- 2 Medium brown + 0xffb17050, -- 3 Light brown + 0xffe2bc7b, -- 4 Beige + 0xff706662, -- 5 Gray + 0xff151515, -- 6 Black + 0xffc21c1c, -- 7 Red + 0xff178c32, -- 8 Green + 0xffae2ad3, -- 9 Plum + 0xffebe8e4, -- 10 White + 0xffe3dd26, -- 11 Yellow + 0xff449acc, -- 12 Light blue + 0xff124d87, -- 13 Dark blue + 0xfffc0eb3, -- 14 Pink + 0xffd0672a, -- 15 Orange + }, + footwear = {}, + mouth = {}, + eye = {}, + bottom = {}, + top = {}, + hair = {}, + headwear = {}, + masks = {}, + preview_rotations = {}, + players = {} +} + +function mcl_skins.register_item(item) + assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.") + local texture = item.texture or "blank.png" + if item.steve then + mcl_skins.steve[item.type] = texture + end + + if item.alex then + mcl_skins.alex[item.type] = texture + end + + table.insert(mcl_skins[item.type], texture) + mcl_skins.masks[texture] = item.mask + if item.preview_rotation then + mcl_skins.preview_rotations[texture] = item.preview_rotation + end +end + +function mcl_skins.save(player) + local skin = mcl_skins.players[player] + if not skin then return end + + local meta = player:get_meta() + meta:set_string("mcl_skins:skin", minetest.serialize(skin)) + + meta:set_string("mcl_skins:skin_id", tostring(skin.simple_skins_id or "")) +end + +minetest.register_chatcommand("skin", { + description = S("Open skin configuration screen."), + privs = {}, + func = function(name, param) mcl_skins.show_formspec(minetest.get_player_by_name(name)) end +}) + +function mcl_skins.compile_skin(skin) + if skin.simple_skins_id then + return mcl_skins.simple_skins[skin.simple_skins_id].texture + end + + local output = "" + for i, item in pairs(mcl_skins.item_names) do + local texture = skin[item] + if texture and texture ~= "blank.png" then + + if skin[item .. "_color"] and mcl_skins.masks[texture] then + if #output > 0 then output = output .. "^" end + local color = color_to_string(skin[item .. "_color"]) + output = output .. + "(" .. mcl_skins.masks[texture] .. "^[colorize:" .. color .. ":alpha)" + end + if #output > 0 then output = output .. "^" end + output = output .. texture + end + end + return output +end + +function mcl_skins.update_player_skin(player) + if not player then + return + end + + local skin = mcl_skins.players[player] + + mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin)) + + local slim_arms + if skin.simple_skins_id then + slim_arms = mcl_skins.simple_skins[skin.simple_skins_id].slim_arms + else + slim_arms = skin.slim_arms + end + local model = slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d" + mcl_player.player_set_model(player, model) +end + +-- Load player skin on join +minetest.register_on_joinplayer(function(player) + local function table_get_random(t) + return t[math.random(#t)] + end + local skin = player:get_meta():get_string("mcl_skins:skin") + if skin then + skin = minetest.deserialize(skin) + end + if skin then + mcl_skins.players[player] = skin + else + if math.random() > 0.5 then + skin = table.copy(mcl_skins.steve) + else + skin = table.copy(mcl_skins.alex) + end + mcl_skins.players[player] = skin + end + + mcl_skins.players[player].simple_skins_id = nil + if #mcl_skins.simple_skins > 0 then + local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id")) + if skin_id and mcl_skins.simple_skins[skin_id] then + mcl_skins.players[player].simple_skins_id = skin_id + end + end + mcl_skins.save(player) + mcl_skins.update_player_skin(player) +end) + +minetest.register_on_leaveplayer(function(player) + mcl_skins.players[player] = nil +end) + +function mcl_skins.show_formspec(player, active_tab, page_num) + local skin = mcl_skins.players[player] + local default = #mcl_skins.simple_skins > 0 and "skin" or "template" + active_tab = active_tab or default + page_num = page_num or 1 + + local page_count + if page_num < 1 then page_num = 1 end + if mcl_skins[active_tab] then + page_count = math.ceil(#mcl_skins[active_tab] / 16) + if page_num > page_count then + page_num = page_count + end + elseif active_tab == "skin" then + page_count = math.ceil((#mcl_skins.simple_skins + 2) / 8) + if page_num > page_count then + page_num = page_count + end + else + page_num = 1 + page_count = 1 + end + + local formspec = "formspec_version[3]size[13.2,11]" + + for i, tab in pairs(mcl_skins.tab_names) do + if tab == active_tab then + formspec = formspec .. + "style[" .. tab .. ";bgcolor=green]" + end + + local y = 0.3 + (i - 1) * 0.8 + formspec = formspec .. + "button[0.3," .. y .. ";3,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]" + + if skin.simple_skins_id then break end + end + + local slim_arms + if skin.simple_skins_id then + slim_arms = mcl_skins.simple_skins[skin.simple_skins_id].slim_arms + else + slim_arms = skin.slim_arms + end + local mesh = slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d" + + formspec = formspec .. + "model[10,0.3;3,7;player_mesh;" .. mesh .. ";" .. + mcl_skins.compile_skin(skin) .. + ",blank.png,blank.png;0,180;false;true;0,0]" + + if active_tab == "skin" then + local page_start = (page_num - 1) * 8 - 1 + local page_end = math.min(page_start + 8 - 1, #mcl_skins.simple_skins) + formspec = formspec .. + "style_type[button;bgcolor=#00000000]" + + local skin = table.copy(skin) + local skin_id = skin.simple_skins_id or -1 + skin.simple_skins_id = nil + + local skins = table.copy(mcl_skins.simple_skins) + skins[-1] = { + slim_arms = skin.slim_arms, + texture = mcl_skins.compile_skin(skin), + } + + for i = page_start, page_end do + local skin = skins[i] + local j = i - page_start - 1 + local mesh = skin.slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d" + + local x = 3.5 + (j + 1) % 4 * 1.6 + local y = 0.3 + math.floor((j + 1) / 4) * 3.1 + + formspec = formspec .. + "model[" .. x .. "," .. y .. ";1.5,3;player_mesh;" .. mesh .. ";" .. + skin.texture .. + ",blank.png,blank.png;0,180;false;true;0,0]" + + if skin_id == i then + formspec = formspec .. + "style[" .. i .. + ";bgcolor=;bgimg=mcl_skins_select_overlay.png;" .. + "bgimg_pressed=mcl_skins_select_overlay.png;bgimg_middle=14,14]" + end + formspec = formspec .. + "button[" .. x .. "," .. y .. ";1.5,3;" .. i .. ";]" + end + + if page_start == -1 then + formspec = formspec .. "image[3.85,1;0.8,0.8;mcl_skins_button.png]" + end + elseif active_tab == "template" then + formspec = formspec .. + "model[4,2;2,3;player_mesh;mcl_armor_character.b3d;" .. + mcl_skins.compile_skin(mcl_skins.steve) .. + ",blank.png,blank.png;0,180;false;true;0,0]" .. + + "button[4,5.2;2,0.8;steve;" .. S("Select") .. "]" .. + + "model[6.5,2;2,3;player_mesh;mcl_armor_character_female.b3d;" .. + mcl_skins.compile_skin(mcl_skins.alex) .. + ",blank.png,blank.png;0,180;false;true;0,0]" .. + + "button[6.5,5.2;2,0.8;alex;" .. S("Select") .. "]" + + elseif mcl_skins[active_tab] then + formspec = formspec .. + "style_type[button;bgcolor=#00000000]" + local textures = mcl_skins[active_tab] + local page_start = (page_num - 1) * 16 + 1 + local page_end = math.min(page_start + 16 - 1, #textures) + + for j = page_start, page_end do + local i = j - page_start + 1 + local texture = textures[j] + local preview = mcl_skins.masks[skin.base] .. "^[colorize:gray^" .. skin.base + local color = color_to_string(skin[active_tab .. "_color"]) + local mask = mcl_skins.masks[texture] + if color and mask then + preview = preview .. "^(" .. mask .. "^[colorize:" .. color .. ":alpha)" + end + preview = preview .. "^" .. texture + + local mesh = "mcl_skins_head.obj" + if active_tab == "top" then + mesh = "mcl_skins_top.obj" + elseif active_tab == "bottom" or active_tab == "footwear" then + mesh = "mcl_skins_bottom.obj" + end + + local rot_x = -10 + local rot_y = 20 + if mcl_skins.preview_rotations[texture] then + rot_x = mcl_skins.preview_rotations[texture].x + rot_y = mcl_skins.preview_rotations[texture].y + end + + i = i - 1 + local x = 3.5 + i % 4 * 1.6 + local y = 0.3 + math.floor(i / 4) * 1.6 + formspec = formspec .. + "model[" .. x .. "," .. y .. + ";1.5,1.5;" .. mesh .. ";" .. mesh .. ";" .. + preview .. + ";" .. rot_x .. "," .. rot_y .. ";false;false;0,0]" + + if skin[active_tab] == texture then + formspec = formspec .. + "style[" .. texture .. + ";bgcolor=;bgimg=mcl_skins_select_overlay.png;" .. + "bgimg_pressed=mcl_skins_select_overlay.png;bgimg_middle=14,14]" + end + formspec = formspec .. "button[" .. x .. "," .. y .. ";1.5,1.5;" .. texture .. ";]" + end + elseif active_tab == "arm" then + local x = skin.slim_arms and 4.7 or 3.6 + formspec = formspec .. + "image_button[3.6,0.3;1,1;mcl_skins_thick_arms.png;thick_arms;]" .. + "image_button[4.7,0.3;1,1;mcl_skins_slim_arms.png;slim_arms;]" .. + "style[arm;bgcolor=;bgimg=mcl_skins_select_overlay.png;bgimg_middle=14,14;bgimg_pressed=mcl_skins_select_overlay.png]" .. + "button[" .. x .. ",0.3;1,1;arm;]" + end + + + if skin[active_tab .. "_color"] then + local colors = mcl_skins.color + if active_tab == "base" then colors = mcl_skins.base_color end + + local tab_color = active_tab .. "_color" + local selected_color = skin[tab_color] + for i, colorspec in pairs(colors) do + local color = color_to_string(colorspec) + i = i - 1 + local x = 3.6 + i % 6 * 0.9 + local y = 8 + math.floor(i / 6) * 0.9 + formspec = formspec .. + "image_button[" .. x .. "," .. y .. + ";0.8,0.8;blank.png^[noalpha^[colorize:" .. + color .. ":alpha;" .. colorspec .. ";]" + + if selected_color == colorspec then + formspec = formspec .. + "style[" .. color .. + ";bgcolor=;bgimg=mcl_skins_select_overlay.png;bgimg_middle=14,14;bgimg_pressed=mcl_skins_select_overlay.png]" .. + "button[" .. x .. "," .. y .. ";0.8,0.8;" .. color .. ";]" + end + + end + + if not (active_tab == "base") then + -- Bitwise Operations !?!?! + local red = math.floor(selected_color / 0x10000) - 0xff00 + local green = math.floor(selected_color / 0x100) - 0xff0000 - red * 0x100 + local blue = selected_color - 0xff000000 - red * 0x10000 - green * 0x100 + formspec = formspec .. + "container[9.2,8]" .. + "scrollbaroptions[min=0;max=255;smallstep=20]" .. + + "box[0.4,0;2.49,0.38;red]" .. + "label[0.2,0.2;-]" .. + "scrollbar[0.4,0;2.5,0.4;horizontal;red;" .. red .."]" .. + "label[2.9,0.2;+]" .. + + "box[0.4,0.6;2.49,0.38;green]" .. + "label[0.2,0.8;-]" .. + "scrollbar[0.4,0.6;2.5,0.4;horizontal;green;" .. green .."]" .. + "label[2.9,0.8;+]" .. + + "box[0.4,1.2;2.49,0.38;blue]" .. + "label[0.2,1.4;-]" .. + "scrollbar[0.4,1.2;2.5,0.4;horizontal;blue;" .. blue .. "]" .. + "label[2.9,1.4;+]" .. + + "container_end[]" + end + end + + if page_num > 1 then + formspec = formspec .. + "image_button[3.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" + end + + if page_num < page_count then + formspec = formspec .. + "image_button[8.8,6.7;1,1;mcl_skins_arrow.png;next_page;]" + end + + if page_count > 1 then + formspec = formspec .. + "label[6.3,7.2;" .. page_num .. " / " .. page_count .. "]" + end + + local player_name = player:get_player_name() + minetest.show_formspec(player_name, "mcl_skins:" .. active_tab .. "_" .. page_num, formspec) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if fields.__mcl_skins then + mcl_skins.show_formspec(player) + return false + end + + + if not formname:find("^mcl_skins:") then return false end + local _, _, active_tab, page_num = formname:find("^mcl_skins:(%a+)_(%d+)") + + local active_tab_found = false + for _, tab in pairs(mcl_skins.tab_names) do + if tab == active_tab then active_tab_found = true end + end + active_tab = active_tab_found and active_tab or "template" + + if not page_num or not active_tab then return true end + page_num = math.floor(tonumber(page_num) or 1) + + -- Cancel formspec resend after scrollbar move + if mcl_skins.players[player].form_send_job then + mcl_skins.players[player].form_send_job:cancel() + end + + if fields.quit then + mcl_skins.save(player) + return true + end + + if fields.alex then + mcl_skins.players[player] = table.copy(mcl_skins.alex) + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + return true + elseif fields.steve then + mcl_skins.players[player] = table.copy(mcl_skins.steve) + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + return true + end + + for i, tab in pairs(mcl_skins.tab_names) do + if fields[tab] then + mcl_skins.show_formspec(player, tab, page_num) + return true + end + end + + local skin = mcl_skins.players[player] + if not skin then return true end + + if fields.next_page then + page_num = page_num + 1 + mcl_skins.show_formspec(player, active_tab, page_num) + return true + elseif fields.previous_page then + page_num = page_num - 1 + mcl_skins.show_formspec(player, active_tab, page_num) + return true + end + + if active_tab == "arm" then + if fields.thick_arms then + skin.slim_arms = false + elseif fields.slim_arms then + skin.slim_arms = true + end + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + return true + end + + if + skin[active_tab .. "_color"] and ( + fields.red and fields.red:find("^CHG") or + fields.green and fields.green:find("^CHG") or + fields.blue and fields.blue:find("^CHG") + ) + then + local red = fields.red:gsub("%a%a%a:", "") + local green = fields.green:gsub("%a%a%a:", "") + local blue = fields.blue:gsub("%a%a%a:", "") + red = tonumber(red) or 0 + green = tonumber(green) or 0 + blue = tonumber(blue) or 0 + + local color = 0xff000000 + red * 0x10000 + green * 0x100 + blue + if color >= 0 and color <= 0xffffffff then + -- We delay resedning the form because otherwise it will break dragging scrollbars + mcl_skins.players[player].form_send_job = minetest.after(0.2, function() + if player and player:is_player() then + skin[active_tab .. "_color"] = color + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + mcl_skins.players[player].form_send_job = nil + end + end) + return true + end + end + + local field + for f, value in pairs(fields) do + if value == "" then + field = f + break + end + end + + if field and active_tab == "skin" then + local skin_id = tonumber(field) + skin_id = skin_id and math.floor(skin_id) or 0 + if + #mcl_skins.simple_skins > 0 and + skin_id >= -1 and skin_id <= #mcl_skins.simple_skins + then + if skin_id == -1 then skin_id = nil end + skin.simple_skins_id = skin_id + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + end + return true + end + + -- See if field is a texture + if field and mcl_skins[active_tab] then + for i, texture in pairs(mcl_skins[active_tab]) do + if texture == field then + skin[active_tab] = texture + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + return true + end + end + end + + -- See if field is a color + local number = tonumber(field) + if number and skin[active_tab .. "_color"] then + local color = math.floor(number) + if color and color >= 0 and color <= 0xffffffff then + skin[active_tab .. "_color"] = color + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + return true + end + end + + return true +end) + +local function init() + local function file_exists(name) + local f = io.open(name) + if not f then + return false + end + f:close() + return true + end + + local f = io.open(minetest.get_modpath("mcl_skins") .. "/list.json") + assert(f, "Can't open the file list.json") + local data = f:read("*all") + assert(data, "Can't read data from list.json") + local json, error = minetest.parse_json(data) + assert(json, error) + f:close() + + for _, item in pairs(json) do + mcl_skins.register_item(item) + end + mcl_skins.steve.base_color = mcl_skins.base_color[2] + mcl_skins.steve.hair_color = 0xff5d473b + mcl_skins.steve.top_color = 0xff993535 + mcl_skins.steve.bottom_color = 0xff644939 + mcl_skins.steve.slim_arms = false + + mcl_skins.alex.base_color = mcl_skins.base_color[1] + mcl_skins.alex.hair_color = 0xff715d57 + mcl_skins.alex.top_color = 0xff346840 + mcl_skins.alex.bottom_color = 0xff383532 + mcl_skins.alex.slim_arms = true +end + +init() diff --git a/mods/PLAYER/mcl_skins/init.lua b/mods/PLAYER/mcl_skins/init.lua index 485e342b1..f1192ba16 100644 --- a/mods/PLAYER/mcl_skins/init.lua +++ b/mods/PLAYER/mcl_skins/init.lua @@ -1,280 +1,8 @@ --- Skins for MineClone 2 - -local modname = minetest.get_current_modname() - -mcl_skins = { - skins = {}, list = {}, meta = {}, - modpath = minetest.get_modpath(modname), - skin_count = 0, -- counter of _custom_ skins (all skins except character.png) -} - -local S = minetest.get_translator(modname) -local has_mcl_inventory = minetest.get_modpath("mcl_inventory") - --- load skin list and metadata -local id, f, data, skin = 0 - -while true do - - if id == 0 then - skin = "character" - else - skin = "mcl_skins_character_" .. id - - -- Does skin file exist? - f = io.open(mcl_skins.modpath .. "/textures/" .. skin .. ".png") - - -- escape loop if not found - if not f then - break - end - f:close() - end - - mcl_skins.list[id] = skin - - local metafile - - -- does metadata exist for that skin file ? - if id == 0 then - metafile = "mcl_skins_character.txt" - else - metafile = "mcl_skins_character_"..id..".txt" - end - f = io.open(mcl_skins.modpath .. "/meta/" .. metafile) - - data = nil - if f then - data = minetest.deserialize("return {" .. f:read("*all") .. "}") - f:close() - end - - -- add metadata to list - mcl_skins.meta[skin] = { - name = data and data.name or "", - author = data and data.author or "", - gender = data and data.gender or "", - } - - if id > 0 then - mcl_skins.skin_count = mcl_skins.skin_count + 1 - end - id = id + 1 -end - -function mcl_skins.cycle_skin(player) - local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id")) - if not skin_id then - skin_id = 0 - end - skin_id = skin_id + 1 - if skin_id > mcl_skins.skin_count then - skin_id = 0 - end - mcl_skins.set_player_skin(player, skin_id) -end - -function mcl_skins.set_player_skin(player, skin_id) - if not player then - return false - end - local playername = player:get_player_name() - local skin - if skin_id == nil or type(skin_id) ~= "number" or skin_id < 0 or skin_id > mcl_skins.skin_count then - return false - elseif skin_id == 0 then - skin = "character" - mcl_player.player_set_model(player, "mcl_armor_character.b3d") - else - skin = "mcl_skins_character_" .. tostring(skin_id) - local meta = mcl_skins.meta[skin] - if meta.gender == "female" then - mcl_player.player_set_model(player, "mcl_armor_character_female.b3d") - else - mcl_player.player_set_model(player, "mcl_armor_character.b3d") - end - end - --local skin_file = skin .. ".png" - mcl_skins.skins[playername] = skin - player:get_meta():set_string("mcl_skins:skin_id", tostring(skin_id)) - mcl_skins.update_player_skin(player) - if has_mcl_inventory then - mcl_inventory.update_inventory_formspec(player) - end - for i=1, #mcl_skins.registered_on_set_skins do - mcl_skins.registered_on_set_skins[i](player, skin) - end - minetest.log("action", "[mcl_skins] Player skin for "..playername.." set to skin #"..skin_id) - return true -end - -function mcl_skins.update_player_skin(player) - if not player then - return - end - local playername = player:get_player_name() - mcl_player.player_set_skin(player, mcl_skins.skins[playername] .. ".png") -end - --- load player skin on join -minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() - local skin_id = player:get_meta():get_string("mcl_skins:skin_id") - local set_skin - -- do we already have a skin in player attributes? - if skin_id and skin_id ~= "" then - set_skin = tonumber(skin_id) - -- otherwise use random skin if not set - end - if not set_skin then - set_skin = math.random(0, mcl_skins.skin_count) - end - local ok = mcl_skins.set_player_skin(player, set_skin) - if not ok then - set_skin = math.random(0, mcl_skins.skin_count) - minetest.log("warning", "[mcl_skins] Player skin for "..name.." not found, falling back to skin #"..set_skin) - mcl_skins.set_player_skin(player, set_skin) - end -end) - -mcl_skins.registered_on_set_skins = {} - -function mcl_skins.register_on_set_skin(func) - table.insert(mcl_skins.registered_on_set_skins, func) -end - --- command to set player skin (usually for custom skins) -minetest.register_chatcommand("setskin", { - params = S("[] []"), - description = S("Select player skin of yourself or another player"), - privs = {}, - func = function(name, param) - - if param == "" and name ~= "" then - mcl_skins.show_formspec(name) - return true - end - local playername, skin_id = string.match(param, "([^ ]+) (%d+)") - if not playername or not skin_id then - skin_id = string.match(param, "(%d+)") - if not skin_id then - return false, S("Insufficient or wrong parameters") - end - playername = name - end - skin_id = tonumber(skin_id) - - local player = minetest.get_player_by_name(playername) - - if not player then - return false, S("Player @1 not online!", playername) - end - if name ~= playername then - local privs = minetest.get_player_privs(name) - if not privs.server then - return false, S("You need the “server” privilege to change the skin of other players!") - end - end - - local ok = mcl_skins.set_player_skin(player, skin_id) - if not ok then - return false, S("Invalid skin number! Valid numbers: 0 to @1", mcl_skins.skin_count) - end - local skinfile = "#"..skin_id - - local meta = mcl_skins.meta[mcl_skins.skins[playername]] - local your_msg - if not meta.name or meta.name == "" then - your_msg = S("Your skin has been set to: @1", skinfile) - else - your_msg = S("Your skin has been set to: @1 (@2)", meta.name, skinfile) - end - if name == playername then - return true, your_msg - else - minetest.chat_send_player(playername, your_msg) - return true, S("Skin of @1 set to: @2 (@3)", playername, meta.name, skinfile) - end - - end, -}) - -minetest.register_on_player_receive_fields(function(player, formname, fields) - if fields.__mcl_skins then - if mcl_skins.skin_count <= 6 then - -- Change skin immediately if there are not many skins - mcl_skins.cycle_skin(player) - if player:get_attach() then - mcl_player.player_set_animation(player, "sit") - end - else - -- Show skin selection formspec otherwise - mcl_skins.show_formspec(player:get_player_name()) - end - end -end) - -function mcl_skins.show_formspec(playername) - local formspec = "size[7,8.5]" - - formspec = formspec .. "label[2,2;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Select player skin:"))) .. "]" - .. "textlist[0,2.5;6.8,6;skins_set;" - - local meta - local selected = 1 - - for i = 0, mcl_skins.skin_count do - - local label = S("@1 (@2)", mcl_skins.meta[mcl_skins.list[i]].name, "#"..i) - - formspec = formspec .. minetest.formspec_escape(label) - - if mcl_skins.skins[playername] == mcl_skins.list[i] then - selected = i + 1 - meta = mcl_skins.meta[mcl_skins.list[i]] - end - - if i < #mcl_skins.list then - formspec = formspec .."," - end - end - - formspec = formspec .. ";" .. selected .. ";false]" - - local player = minetest.get_player_by_name(playername) - if player then - --maybe the function could accept both player object and player name? - formspec = formspec .. mcl_player.get_player_formspec_model(player, 0, 0, 1.35, 2.7, "mcl_skins:skin_select") - end - - if meta then - if meta.name and meta.name ~= "" then - formspec = formspec .. "label[2,0.5;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Name: @1", meta.name))) .. "]" - end - end - - minetest.show_formspec(playername, "mcl_skins:skin_select", formspec) -end - -minetest.register_on_player_receive_fields(function(player, formname, fields) - - if formname == "mcl_skins:skin_select" then - - local name = player:get_player_name() - - local event = minetest.explode_textlist_event(fields["skins_set"]) - - if event.type == "CHG" or event.type == "DCL" then - - local skin_id = math.min(event.index - 1, mcl_skins.skin_count) - if not mcl_skins.list[skin_id] then - return -- Do not update wrong skin number - end - - mcl_skins.set_player_skin(player, skin_id) - mcl_skins.show_formspec(name) - end - end -end) - -minetest.log("action", "[mcl_skins] Mod initialized with "..mcl_skins.skin_count.." custom skin(s)") +local mod_path = minetest.get_modpath(minetest.get_current_modname()) + +local mcl_skins_enabled = minetest.settings:get_bool("mcl_enable_skin_customization", true) +if mcl_skins_enabled then + dofile(mod_path .. "/edit_skin.lua") + dofile(mod_path .. "/simple_skins.lua") + dofile(mod_path .. "/mesh_hand.lua") +end diff --git a/mods/PLAYER/mcl_skins/list.json b/mods/PLAYER/mcl_skins/list.json new file mode 100644 index 000000000..01bb622e5 --- /dev/null +++ b/mods/PLAYER/mcl_skins/list.json @@ -0,0 +1,260 @@ +[ + { + "type": "footwear", + "texture": "mcl_skins_footwear_1.png", + "steve": true, + "alex": true + }, + { + "type": "footwear", + "texture": "mcl_skins_footwear_2.png" + }, + { + "type": "footwear", + "texture": "mcl_skins_footwear_3.png" + }, + { + "type": "footwear" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_1.png", + "alex": true + }, + { + "type": "eye", + "texture": "mcl_skins_eye_2.png", + "steve": true + }, + { + "type": "eye", + "texture": "mcl_skins_eye_3.png" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_4.png" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_5.png" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_6.png" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_7.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_1.png", + "steve": true + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_2.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_3.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_4.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_5.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_6.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_7.png" + }, + { + "type": "mouth", + "alex": true + }, + { + "type": "hair", + "texture": "mcl_skins_hair_1.png", + "mask": "mcl_skins_hair_1_mask.png", + "alex": true + }, + { + "type": "hair", + "texture": "mcl_skins_hair_2.png", + "mask": "mcl_skins_hair_2_mask.png", + "steve": true + }, + { + "type": "hair", + "texture": "mcl_skins_hair_3.png", + "mask": "mcl_skins_hair_3_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_4.png", + "mask": "mcl_skins_hair_4_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_5.png", + "mask": "mcl_skins_hair_5_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_6.png", + "mask": "mcl_skins_hair_6_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_7.png", + "mask": "mcl_skins_hair_7_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_8.png", + "mask": "mcl_skins_hair_8_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_9.png", + "mask": "mcl_skins_hair_9_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_10.png", + "mask": "mcl_skins_hair_10_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_11.png", + "mask": "mcl_skins_hair_11_mask.png" + }, + { + "type": "hair" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_1.png" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_2.png", + "alex": true + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_3.png" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_4.png" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_5.png" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_6.png", + "preview_rotation": { + "x": -10, + "y": 200 + } + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_7.png" + }, + { + "type": "headwear", + "steve": true + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_1.png", + "mask": "mcl_skins_bottom_1_mask.png", + "steve": true, + "alex": true + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_2.png", + "mask": "mcl_skins_bottom_2_mask.png" + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_3.png", + "mask": "mcl_skins_bottom_3_mask.png" + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_4.png", + "mask": "mcl_skins_bottom_4_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_1.png", + "mask": "mcl_skins_top_1_mask.png", + "steve": true, + "alex": true + }, + { + "type": "top", + "texture": "mcl_skins_top_2.png", + "mask": "mcl_skins_top_2_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_3.png", + "mask": "mcl_skins_top_3_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_4.png", + "mask": "mcl_skins_top_4_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_5.png", + "mask": "mcl_skins_top_5_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_6.png", + "mask": "mcl_skins_top_6_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_7.png", + "mask": "mcl_skins_top_7_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_8.png", + "mask": "mcl_skins_top_8_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_9.png", + "mask": "mcl_skins_top_9_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_10.png", + "mask": "mcl_skins_top_10_mask.png" + }, + { + "type": "base", + "texture": "mcl_skins_base_1.png", + "mask": "mcl_skins_base_1_mask.png", + "steve": true, + "alex": true + } +] diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.de.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.de.tr deleted file mode 100644 index 8f9b488db..000000000 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.de.tr +++ /dev/null @@ -1,13 +0,0 @@ -# textdomain: mcl_skins -[] []=[] [] -Select player skin of yourself or another player=Spieleraussehen von Ihnen oder einem anderen Spieler auswählen -Insufficient or wrong parameters=Unzureichende oder falsche Parameter -Player @1 not online!=Spieler @1 ist nicht online! -You need the “server” privilege to change the skin of other players!=Sie brauchen das „server“-Privileg, um das Aussehen anderer Spieler zu ändern! -Invalid skin number! Valid numbers: 0 to @1=Ungültige Aussehens-Nummer! Gültige Nummern: 0 bis @1 -Your skin has been set to: @1=Ihr Aussehen wurde geändert auf: @1 -Your skin has been set to: @1 (@2)=Ihr Aussehen wurde geändert auf: @1 (@2) -Skin of @1 set to: @2 (@3)=Aussehen von @1 gesetzt auf: @2 (@3) -Select player skin:=Spieleraussehen wählen: -@1 (@2)=@1 (@2) -Name: @1=Name: @1 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.es.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.es.tr deleted file mode 100644 index dcd5c8438..000000000 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.es.tr +++ /dev/null @@ -1,13 +0,0 @@ -# textdomain: mcl_skins -[] []=[] [] -Select player skin of yourself or another player=Selecciona el skin tuyo o de otro jugador -Insufficient or wrong parameters=Parámetros insuficientes o incorrectos -Player @1 not online!=¡El jugador @1 no está en línea! -You need the “server” privilege to change the skin of other players!=¡Necesitas el privilegio de "servidor" para cambiar el aspecto de otros jugadores! -Invalid skin number! Valid numbers: 0 to @1=¡Número de piel no válido! Números válidos: 0 a @1 -Your skin has been set to: @1=Su skin se ha configurado a: @1 -Your skin has been set to: @1 (@2)=Su skin se ha configurado a: @1 (@2) -Skin of @1 set to: @2 (@3)=El skin de @1 se ha configurado a: @2 (@3) -Select player skin:=Selecciona el skin del jugador: -@1 (@2)=@1 (@2) -Name: @1=Nombre: @1 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.fr.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.fr.tr index 146c6be5f..db937b040 100644 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.fr.tr +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.fr.tr @@ -1,14 +1,13 @@ # textdomain: mcl_skins -[] []=[] [] -Select player skin of yourself or another player=Sélectionner une apparence pour vous même ou un autre joueur -Insufficient or wrong parameters=Paramètres insuffisants ou incorrects -Player @1 not online!=Le joueur @1 n'est pas en ligne! -You need the “server” privilege to change the skin of other players!=Vous avez besoin du privilège “server” pour changer l'apparence des autres joueurs! -Invalid skin number! Valid numbers: 0 to @1=Numéro d'apparence incorrect! Numéros valides : 0 à @1 -Your skin has been set to: @1=Votre apparence a été définie à: @1 -Your skin has been set to: @1 (@2)=Votre apparence a été définie à: @1 (@2) -Skin of @1 set to: @2 (@3)=Apparence of @1 set to: @2 (@3)= -Select player skin:=Sélectionner l'apparence du joueur : -@1 (@2)=@1 (@2) -Name: @1=Nom : @ - +Templates=Modèles +Arm size=Taille des bras +Bases=Teint +Footwears=Chaussures +Eyes=Yeux +Mouths=Bouches +Bottoms=Bas +Tops=Haut +Hairs=Cheveux +Headwears=Coiffe +Open skin configuration screen.=Ouvrir l'écran de configuration du costume. +Select=Sélectionner \ No newline at end of file diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.ja.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.ja.tr new file mode 100644 index 000000000..87361bb75 --- /dev/null +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.ja.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_skins +Skins=スキン +Templates=テンプレート +Arm size=腕の大きさ +Bases=ベース +Footwears=靴 +Eyes=目 +Mouths=口 +Bottoms=下衣 +Tops=上衣 +Hairs=髪 +Headwears=帽子 +Open skin configuration screen.=スキン設定画面を開きます。 +Select=選択 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.ms.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.ms.tr deleted file mode 100644 index 58946f605..000000000 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.ms.tr +++ /dev/null @@ -1,16 +0,0 @@ -# textdomain: mcl_skins -# UNFINISHED translation! -# TODO: Remove the # sign from the translations below and add the missing translations. - -[] []= -Select player skin of yourself or another player= -Insufficient or wrong parameters= -Player @1 not online!= -You need the “server” privilege to change the skin of other players!= -Invalid skin number! Valid numbers: 0 to @1= -Your skin has been set to: @1= -Your skin has been set to: @1 (@2)= -Skin of @1 set to: @2 (@3)= -Select player skin:=Pilih Kulit Pemain: -@1 (@2)= -Name: @1=Nama: @1 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.pl.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.pl.tr deleted file mode 100644 index 9b07cea2c..000000000 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.pl.tr +++ /dev/null @@ -1,13 +0,0 @@ -# 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.ru.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr deleted file mode 100644 index 64eab0e3f..000000000 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr +++ /dev/null @@ -1,13 +0,0 @@ -# textdomain: mcl_skins -[] []=[<игрок>] [<номер скина>] -Select player skin of yourself or another player=Выберите скин для себя или для другого игрока -Insufficient or wrong parameters=Недопустимые или неправильные параметры -Player @1 not online!=Игрок @1 не в сети! -You need the “server” privilege to change the skin of other players!=Для смены скинов другим игрокам у вас должна быть привилегия “server”! -Invalid skin number! Valid numbers: 0 to @1=Недопустимый номер скина! Правильные номера: от 0 до @1 -Your skin has been set to: @1=Ваш скин выбран: @1 -Your skin has been set to: @1 (@2)=Ваш скин установлен: @1 (@2) -Skin of @1 set to: @2 (@3)=Скин игрока @1 установлен: @2 (@3) -Select player skin:=Выбор скина игрока: -@1 (@2)=@1 (@2) -Name: @1=Имя: @1 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.zh_TW.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.zh_TW.tr deleted file mode 100644 index 1347800ee..000000000 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.zh_TW.tr +++ /dev/null @@ -1,13 +0,0 @@ -# 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_skins/locale/template.txt b/mods/PLAYER/mcl_skins/locale/template.txt index c683fa4e4..12ba740d5 100644 --- a/mods/PLAYER/mcl_skins/locale/template.txt +++ b/mods/PLAYER/mcl_skins/locale/template.txt @@ -1,13 +1,14 @@ # textdomain: mcl_skins -[] []= -Select player skin of yourself or another player= -Insufficient or wrong parameters= -Player @1 not online!= -You need the “server” privilege to change the skin of other players!= -Invalid skin number! Valid numbers: 0 to @1= -Your skin has been set to: @1= -Your skin has been set to: @1 (@2)= -Skin of @1 set to: @2 (@3)= -Select player skin:= -@1 (@2)= -Name: @1= +Skins= +Templates= +Arm size= +Bases= +Footwears= +Eyes= +Mouths= +Bottoms= +Tops= +Hairs= +Headwears= +Open skin configuration screen.= +Select= diff --git a/mods/PLAYER/mcl_skins/media_credits.txt b/mods/PLAYER/mcl_skins/media_credits.txt new file mode 100644 index 000000000..cda321d60 --- /dev/null +++ b/mods/PLAYER/mcl_skins/media_credits.txt @@ -0,0 +1,115 @@ +mcl_skins_base_1.png +mcl_skins_button.png +mcl_skins_footwear_3.png +mcl_skins_headgear_1.png +mcl_skins_headgear_3.png +mcl_skins_headgear_4.png +mcl_skins_headgear_5.png +mcl_skins_mouth_2.png +mcl_skins_mouth_3.png +mcl_skins_mouth_4.png +mcl_skins_mouth_5.png +mcl_skins_select_overlay.png +mcl_skins_slim_arms.png +mcl_skins_thick_arms.png +mcl_skins_top_2.png +mcl_skins_top_5.png +mcl_skins_eye_5.png +mcl_skins_hair_8.png +mcl_skins_top_6.png +mcl_skins_bottom_3.png +mcl_skins_eye_7.png +mcl_skins_mouth_7.png +mcl_skins_hair_10.png +Original work by MrRar +License: CC BY-SA 4.0 + +mcl_skins_top_1.png +mcl_skins_mouth_1.png +mcl_skins_hair_1.png +mcl_skins_hair_2.png +mcl_skins_eye_1.png +mcl_skins_eye_2.png +mcl_skins_footwear_1.png +mcl_skins_headgear_2.png +mcl_skins_mouth_1.png +mcl_skins_top_1.png +mcl_skins_mouth_2.png +Name: Pixel Perfection resource pack for Minecraft 1.11 +Author: XSSheep. Adapted for mcl_skins by MrRar. +License: CC BY-SA 4.0 +Source: https://www.planetminecraft.com/texture_pack/131pixel-perfection/ + +mcl_skins_hair_3.png +mcl_skins_eye_3.png +mcl_skins_footwear_2.png +Name: the 10the doctor +Author: lovehart. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:367 + +mcl_skins_hair_4.png +Blonde Girl +Author: Rin. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=918 + +mcl_skins_hair_5.png +Name: hobbit from lottmob +Author: lovehart. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=336 + +mcl_skins_top_4.png +Name: Oliver_MV +Author: hansuke123. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:291 + +mcl_skins_hair_6.png +mcl_skins_eye_6.png +Name: Mumbo Jumbo +Author: ZestyZachary +License: CC 0 (1.0) +Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:2100 + +mcl_skins_eye_4.png +Name: lisa +Author: hansuke123 +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:88 + +mcl_skins_headwear_7.png +Name: Ryu +Author: Ginsu23. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=464 + +mcl_skins_top_8.png +Name: Hoodie Enderman +Author: Kpenguin. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=962 + +mcl_skins_hair_9.png +Name: Trader 1 +Author: TenPlus1. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=1258 + +mcl_skins_bottom_4.png +mcl_skins_top_9.png +mcl_skins_top_10.png +mcl_skins_hair_11.png +Name: Pixel Perfection Legacy 1.19 +Author: Nova_Wostra. Adapted for mcl_skins by MrRar. +License: CC BY-SA 4.0 +Source: https://www.planetminecraft.com/texture-pack/pixel-perfection-chorus-edit/ + +mcl_skins_bottom.obj +mcl_skins_head.obj +mcl_skins_top.obj +Name: character.blend in player_api mod from Minetest Game +Author: celeron55, MirceaKitsune, Jordach, kilbith, sofar, xunto, Rogier-5, TeTpaAka, Desour, stujones11, An0n3m0us. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: https://github.com/minetest/minetest_game diff --git a/mods/PLAYER/mcl_skins/mesh_hand.lua b/mods/PLAYER/mcl_skins/mesh_hand.lua new file mode 100644 index 000000000..8bbcff878 --- /dev/null +++ b/mods/PLAYER/mcl_skins/mesh_hand.lua @@ -0,0 +1,53 @@ +local function make_texture(base, colorspec) + local output = "" + if mcl_skins.masks[base] then + output = mcl_skins.masks[base] .. + "^[colorize:" .. minetest.colorspec_to_colorstring(colorspec) .. ":alpha" + end + if #output > 0 then output = output .. "^" end + output = output .. base + return output +end + +function mcl_skins.get_skin_list() + local list = {} + for _, base in pairs(mcl_skins.base) do + for _, base_color in pairs(mcl_skins.base_color) do + local id = base:gsub(".png$", "") .. minetest.colorspec_to_colorstring(base_color):gsub("#", "") + local female = { + texture = make_texture(base, base_color), + slim_arms = true, + id = id .. "_female" + } + table.insert(list, female) + + local male = { + texture = make_texture(base, base_color), + slim_arms = false, + id = id .. "_male" + } + table.insert(list, male) + end + end + for _, skin in pairs(mcl_skins.simple_skins) do + table.insert(list, { + texture = skin.texture, + slim_arms = skin.slim_arms, + id = skin.texture:gsub(".png$", "") .. "_" .. (skin.slim_arms and "female" or "male"), + }) + end + return list +end + +function mcl_skins.get_node_id_by_player(player) + local skin = mcl_skins.players[player] + if skin.simple_skins_id then + local skin = mcl_skins.simple_skins[skin.simple_skins_id] + return skin.texture:gsub(".png$", "") .. + "_" .. (skin.slim_arms and "female" or "male") + else + return skin.base:gsub(".png$", "") .. + minetest.colorspec_to_colorstring(skin.base_color):gsub("#", "") .. + "_" .. (skin.slim_arms and "female" or "male") + end +end diff --git a/mods/PLAYER/mcl_skins/mod.conf b/mods/PLAYER/mcl_skins/mod.conf index 657d3cc0e..bd2191097 100644 --- a/mods/PLAYER/mcl_skins/mod.conf +++ b/mods/PLAYER/mcl_skins/mod.conf @@ -1,5 +1,4 @@ name = mcl_skins -author = TenPlus1 -description = Mod that allows players to set their individual skins. +author = MrRar +description = Advanced player skin customization. depends = mcl_player -optional_depends = mcl_inventory, intllib diff --git a/mods/PLAYER/mcl_skins/models/mcl_skins_bottom.obj b/mods/PLAYER/mcl_skins/models/mcl_skins_bottom.obj new file mode 100644 index 000000000..bc12779af --- /dev/null +++ b/mods/PLAYER/mcl_skins/models/mcl_skins_bottom.obj @@ -0,0 +1,108 @@ +# Blender v2.93.5 OBJ File: '' +# www.blender.org +mtllib bottom.mtl +o bottom +v -2.100000 4.358421 1.050001 +v -2.100000 1.648314 1.049999 +v 2.100000 1.648314 1.049999 +v 2.100000 4.358421 1.050001 +v -2.100000 1.648314 -1.050001 +v -2.100000 4.358421 -1.049998 +v 2.100000 1.648314 -1.050001 +v 2.100000 4.358421 -1.049998 +v 0.000000 1.648314 -1.050001 +v 0.000000 -4.651686 -1.050003 +v 0.000000 -4.651686 1.049997 +v 0.000000 1.648314 1.049999 +v 0.000000 -4.651686 -1.050003 +v 0.000000 -4.651686 1.049997 +v -2.100000 -4.651685 1.049997 +v -2.100000 -4.651685 -1.050003 +v -2.100000 1.648315 1.049999 +v -2.100000 1.648315 -1.050001 +v 0.000000 1.648314 1.049999 +v 2.100000 1.648315 -1.050001 +v 2.100000 -4.651685 -1.050003 +v 0.000000 1.648314 -1.050001 +v 2.100000 -4.651685 1.049997 +v 2.100000 1.648315 1.049999 +vt 0.500000 0.161316 +vt 0.500000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.161316 +vt 0.437500 0.000000 +vt 0.437500 0.161316 +vt 0.312500 0.000000 +vt 0.312500 0.161316 +vt 0.562500 0.375000 +vt 0.562500 0.500000 +vt 0.437500 0.500000 +vt 0.437500 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.187500 0.375000 +vt 0.187500 0.375000 +vt 0.187500 0.500000 +vt 0.125000 0.500000 +vt 0.125000 0.375000 +vt 0.000000 0.375000 +vt 0.062500 0.375000 +vt 0.062500 0.000000 +vt 0.000000 0.000000 +vt 0.187500 0.375000 +vt 0.250000 0.375000 +vt 0.250000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.375000 +vt 0.062500 0.000000 +vt 0.125000 0.375000 +vt 0.125000 0.000000 +vt 0.250000 0.000000 +vt 0.250000 0.375000 +vt 0.000000 0.375000 +vt 0.000000 0.000000 +vt 0.250000 0.161316 +vt 0.250000 0.000000 +vt 0.125000 0.375000 +vt 0.125000 0.500000 +vt 0.062500 0.500000 +vt 0.062500 0.375000 +vt 0.187500 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.500000 +vt 0.187500 0.500000 +vt 0.125000 0.375000 +vt 0.062500 0.375000 +vt 0.062500 0.500000 +vt 0.125000 0.500000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 -0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Character +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/2 2/2/2 1/1/2 6/6/2 +f 7/7/3 5/5/3 6/6/3 8/8/3 +f 7/9/4 3/10/4 2/11/4 5/12/4 +f 9/13/2 10/14/2 11/15/2 12/16/2 +f 13/17/4 14/18/4 15/19/4 16/20/4 +f 17/21/2 18/22/2 16/23/2 15/24/2 +f 19/25/1 17/26/1 15/27/1 14/28/1 +f 20/29/3 21/30/3 10/14/3 9/13/3 +f 18/22/3 22/31/3 13/32/3 16/23/3 +f 12/16/1 11/15/1 23/33/1 24/34/1 +f 22/31/5 19/25/5 14/28/5 13/32/5 +f 24/35/5 23/36/5 21/30/5 20/29/5 +f 4/37/5 3/38/5 7/7/5 8/8/5 +f 18/39/6 17/40/6 19/41/6 22/42/6 +f 10/43/4 21/44/4 23/45/4 11/46/4 +f 20/47/6 9/48/6 12/49/6 24/50/6 +f 4/51/6 8/52/6 6/53/6 1/54/6 diff --git a/mods/PLAYER/mcl_skins/models/mcl_skins_head.obj b/mods/PLAYER/mcl_skins/models/mcl_skins_head.obj new file mode 100644 index 000000000..226a0d9bb --- /dev/null +++ b/mods/PLAYER/mcl_skins/models/mcl_skins_head.obj @@ -0,0 +1,72 @@ +# Blender v2.93.5 OBJ File: '' +# www.blender.org +mtllib head.mtl +o head +v -2.100000 -2.100004 2.099999 +v 2.100000 2.099997 -2.100001 +v 2.100000 2.099997 2.099999 +v 2.300000 -2.300003 -2.300001 +v 2.300000 2.299997 2.299999 +v 2.100000 -2.100004 2.099999 +v 2.100000 -2.100004 -2.100001 +v -2.100000 2.099997 2.099999 +v -2.100000 2.099997 -2.100001 +v -2.100000 -2.100004 -2.100001 +v 2.300000 2.299997 -2.300001 +v 2.300000 -2.300003 2.299999 +v -2.300000 2.299997 2.299999 +v -2.300000 -2.300003 2.299999 +v -2.300000 2.299997 -2.300001 +v -2.300000 -2.300003 -2.300001 +vt 0.500000 0.750000 +vt 0.375000 0.750000 +vt 0.375000 0.500000 +vt 0.500000 0.500000 +vt 0.250000 0.750000 +vt 0.250000 0.500000 +vt 0.125000 0.750000 +vt 0.125000 0.500000 +vt 0.375000 0.750000 +vt 0.375000 1.000000 +vt 0.250000 1.000000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.125000 1.000000 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 0.500000 +vt 1.000000 0.500000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +usemtl Character +s off +f 3/1/1 8/2/1 1/3/1 6/4/1 +f 8/2/2 9/5/2 10/6/2 1/3/2 +f 9/5/3 2/7/3 7/8/3 10/6/3 +f 7/9/4 6/10/4 1/11/4 10/12/4 +f 9/5/5 8/13/5 3/14/5 2/7/5 +f 3/15/6 6/16/6 7/8/6 2/7/6 +f 5/17/1 13/18/1 14/19/1 12/20/1 +f 13/18/2 15/21/2 16/22/2 14/19/2 +f 15/21/3 11/23/3 4/24/3 16/22/3 +f 4/25/4 12/26/4 14/27/4 16/28/4 +f 15/21/5 13/29/5 5/30/5 11/23/5 +f 5/31/6 12/32/6 4/24/6 11/23/6 diff --git a/mods/PLAYER/mcl_skins/models/mcl_skins_top.obj b/mods/PLAYER/mcl_skins/models/mcl_skins_top.obj new file mode 100644 index 000000000..845c7019a --- /dev/null +++ b/mods/PLAYER/mcl_skins/models/mcl_skins_top.obj @@ -0,0 +1,174 @@ +# Blender v2.93.5 OBJ File: '' +# www.blender.org +mtllib top.mtl +o top +v -2.100000 -3.149994 1.049999 +v -2.100000 -3.149994 -1.050001 +v -2.100000 3.150004 1.049999 +v -2.100000 3.150004 -1.050001 +v -4.200000 3.150003 -1.050001 +v -4.200000 3.150003 1.049999 +v -2.100000 3.150003 1.049999 +v -2.100000 3.150003 -1.050001 +v -4.200000 -3.149994 -1.050001 +v -4.200000 -3.149994 1.049999 +v -2.100000 -3.149994 1.049999 +v -2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 1.049999 +v 2.100000 3.150004 -1.050001 +v 2.100000 3.150004 1.049999 +v 2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 1.049999 +v 4.200000 -3.149994 1.049999 +v 4.200000 -3.149994 -1.050001 +v 2.100000 3.150003 -1.050001 +v 2.100000 3.150003 1.049999 +v 4.200000 3.150003 1.049999 +v 4.200000 3.150003 -1.050001 +v 2.100000 3.150004 -1.050001 +v 2.100000 3.150004 -1.050001 +v 2.100000 3.150004 1.049999 +v 2.100000 3.150004 1.049999 +v 2.100000 -3.149994 1.049999 +v 2.100000 -3.149994 1.049999 +v 2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 -1.050001 +v -2.100000 3.150004 1.049999 +v -2.100000 3.150004 1.049999 +v -2.100000 -3.149994 1.049999 +v -2.100000 -3.149994 1.049999 +v -2.100000 3.150004 -1.050001 +v -2.100000 3.150004 -1.050001 +v -2.100000 -3.149994 -1.050001 +v -2.100000 -3.149994 -1.050001 +v -4.200000 3.150003 -1.050001 +v -4.200000 3.150003 -1.050001 +v -4.200000 -3.149994 -1.050001 +v -4.200000 -3.149994 -1.050001 +v -2.100000 3.150003 1.049999 +v -2.100000 3.150003 1.049999 +v -2.100000 -3.149994 1.049999 +v -2.100000 -3.149994 1.049999 +v -4.200000 3.150003 1.049999 +v -4.200000 3.150003 1.049999 +v -4.200000 -3.149994 1.049999 +v -4.200000 -3.149994 1.049999 +v -2.100000 3.150003 -1.050001 +v -2.100000 3.150003 -1.050001 +v -2.100000 -3.149994 -1.050001 +v -2.100000 -3.149994 -1.050001 +v 2.100000 3.150003 -1.050001 +v 2.100000 3.150003 -1.050001 +v 2.100000 3.150003 1.049999 +v 2.100000 3.150003 1.049999 +v 2.100000 -3.149994 1.049999 +v 2.100000 -3.149994 1.049999 +v 2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 -1.050001 +v 4.200000 3.150003 1.049999 +v 4.200000 3.150003 1.049999 +v 4.200000 -3.149994 1.049999 +v 4.200000 -3.149994 1.049999 +v 4.200000 3.150003 -1.050001 +v 4.200000 3.150003 -1.050001 +v 4.200000 -3.149994 -1.050001 +v 4.200000 -3.149994 -1.050001 +vt 0.625000 0.375000 +vt 0.500000 0.375000 +vt 0.500000 0.000000 +vt 0.625000 0.000000 +vt 0.500000 0.375000 +vt 0.437500 0.375000 +vt 0.437500 0.000000 +vt 0.500000 0.000000 +vt 0.437500 0.375000 +vt 0.312500 0.375000 +vt 0.312500 0.000000 +vt 0.437500 0.000000 +vt 0.562500 0.375000 +vt 0.562500 0.500000 +vt 0.437500 0.500000 +vt 0.437500 0.375000 +vt 0.437500 0.375000 +vt 0.437500 0.500000 +vt 0.312500 0.500000 +vt 0.312500 0.375000 +vt 0.812500 0.375000 +vt 0.875000 0.375000 +vt 0.875000 0.000000 +vt 0.812500 0.000000 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.000000 +vt 0.750000 0.000000 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.500000 +vt 0.750000 0.500000 +vt 0.687500 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.500000 +vt 0.687500 0.500000 +vt 0.250000 0.375000 +vt 0.250000 0.000000 +vt 0.312500 0.000000 +vt 0.312500 0.375000 +vt 0.687500 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.000000 +vt 0.687500 0.000000 +vt 0.625000 0.375000 +vt 0.687500 0.375000 +vt 0.687500 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.375000 +vt 0.625000 0.000000 +vt 0.687500 0.000000 +vt 0.687500 0.375000 +vt 0.687500 0.375000 +vt 0.687500 0.500000 +vt 0.750000 0.500000 +vt 0.750000 0.375000 +vt 0.687500 0.375000 +vt 0.687500 0.000000 +vt 0.750000 0.000000 +vt 0.750000 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 0.812500 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.500000 +vt 0.812500 0.500000 +vt 0.812500 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.000000 +vt 0.875000 0.000000 +vt 0.875000 0.375000 +vn -0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +usemtl Character +s off +f 27/1/1 3/2/1 1/3/1 14/4/1 +f 33/5/2 4/6/2 2/7/2 35/8/2 +f 37/9/3 25/10/3 31/11/3 39/12/3 +f 13/13/4 29/14/4 36/15/4 40/16/4 +f 38/17/5 34/18/5 16/19/5 15/20/5 +f 7/21/1 6/22/1 10/23/1 11/24/1 +f 8/25/6 45/26/6 47/27/6 12/28/6 +f 17/29/4 20/30/4 19/31/4 18/32/4 +f 24/33/5 21/34/5 22/35/5 23/36/5 +f 28/37/6 30/38/6 32/39/6 26/40/6 +f 5/41/3 53/42/3 55/43/3 9/44/3 +f 49/45/2 41/46/2 43/47/2 51/48/2 +f 65/49/6 67/50/6 71/51/6 69/52/6 +f 42/53/5 50/54/5 46/55/5 54/56/5 +f 70/57/3 72/58/3 63/59/3 57/60/3 +f 58/61/2 64/62/2 61/63/2 59/64/2 +f 56/65/4 48/66/4 52/67/4 44/68/4 +f 60/69/1 62/70/1 68/71/1 66/72/1 diff --git a/mods/PLAYER/mcl_skins/simple_skins.lua b/mods/PLAYER/mcl_skins/simple_skins.lua new file mode 100644 index 000000000..523832f30 --- /dev/null +++ b/mods/PLAYER/mcl_skins/simple_skins.lua @@ -0,0 +1,52 @@ +local function init_simple_skins() + local id, f, data, skin = 0 + local mod_path = minetest.get_modpath("mcl_skins") + while true do + + if id == 0 then + skin = "character.png" + else + skin = "mcl_skins_character_" .. id .. ".png" + + -- Does skin file exist? + f = io.open(mod_path .. "/textures/" .. skin) + + -- escape loop if not found + if not f then + break + end + f:close() + end + + local metafile + + -- does metadata exist for that skin file ? + if id == 0 then + metafile = "mcl_skins_character.txt" + else + metafile = "mcl_skins_character_"..id..".txt" + end + f = io.open(mod_path .. "/meta/" .. metafile) + + data = nil + if f then + data = minetest.deserialize("return {" .. f:read("*all") .. "}") + f:close() + end + + -- add metadata to list + mcl_skins.simple_skins[id] = { + texture = skin, + slim_arms = data and data.gender == "female", + } + id = id + 1 + end + + if #mcl_skins.simple_skins > 0 then + table.insert(mcl_skins.tab_names, 1, "skin") + else + mcl_skins.simple_skins = {} + end +end + +init_simple_skins() diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_arrow.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_arrow.png new file mode 100644 index 000000000..4ca964a8d Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_arrow.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_base_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_base_1.png new file mode 100644 index 000000000..505331181 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_base_1.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_base_1_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_base_1_mask.png new file mode 100644 index 000000000..06c857c4d Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_base_1_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_1.png new file mode 100644 index 000000000..eccc15ebf Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_1.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_1_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_1_mask.png new file mode 100644 index 000000000..41f38d04f Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_1_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_2.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_2.png new file mode 100644 index 000000000..3053b422b Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_2.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_2_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_2_mask.png new file mode 100644 index 000000000..2758cf8b8 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_2_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_3.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_3.png new file mode 100644 index 000000000..aacfeb334 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_3.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_3_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_3_mask.png new file mode 100644 index 000000000..0a97de395 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_3_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_4.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_4.png new file mode 100644 index 000000000..304a2ccb5 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_4.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_4_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_4_mask.png new file mode 100644 index 000000000..3312073c9 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_bottom_4_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_button.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_button.png index 49acf8550..16801e918 100644 Binary files a/mods/PLAYER/mcl_skins/textures/mcl_skins_button.png and b/mods/PLAYER/mcl_skins/textures/mcl_skins_button.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_1.png new file mode 100644 index 000000000..ff19a09b3 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_1.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_2.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_2.png new file mode 100644 index 000000000..4fd1b207f Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_2.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_3.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_3.png new file mode 100644 index 000000000..6a6ebc74d Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_3.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_4.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_4.png new file mode 100644 index 000000000..1cd82bd48 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_4.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_5.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_5.png new file mode 100644 index 000000000..dacc5cb23 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_5.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_6.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_6.png new file mode 100644 index 000000000..8be76c317 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_6.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_7.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_7.png new file mode 100644 index 000000000..f800a90b7 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_eye_7.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_1.png new file mode 100644 index 000000000..1ff60f24b Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_1.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_2.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_2.png new file mode 100644 index 000000000..dc0ef6472 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_2.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_3.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_3.png new file mode 100644 index 000000000..69bb4d934 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_footwear_3.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_1.png new file mode 100644 index 000000000..789468518 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_1.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_10.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_10.png new file mode 100644 index 000000000..962d1aa70 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_10.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_10_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_10_mask.png new file mode 100644 index 000000000..775d8cd96 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_10_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_11.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_11.png new file mode 100644 index 000000000..3eff9bca4 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_11.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_11_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_11_mask.png new file mode 100644 index 000000000..05836b288 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_11_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_1_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_1_mask.png new file mode 100644 index 000000000..cc58ddd23 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_1_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_2.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_2.png new file mode 100644 index 000000000..d0f4a24e4 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_2.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_2_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_2_mask.png new file mode 100644 index 000000000..925821788 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_2_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_3.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_3.png new file mode 100644 index 000000000..d88945b41 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_3.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_3_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_3_mask.png new file mode 100644 index 000000000..6ac774343 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_3_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_4.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_4.png new file mode 100644 index 000000000..61fa3db8c Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_4.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_4_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_4_mask.png new file mode 100644 index 000000000..542717316 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_4_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_5.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_5.png new file mode 100644 index 000000000..55214fac5 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_5.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_5_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_5_mask.png new file mode 100644 index 000000000..ecee2e2bb Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_5_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_6.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_6.png new file mode 100644 index 000000000..40e6eb759 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_6.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_6_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_6_mask.png new file mode 100644 index 000000000..c1de86fd5 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_6_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_7.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_7.png new file mode 100644 index 000000000..2449a06ce Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_7.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_7_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_7_mask.png new file mode 100644 index 000000000..6b1aa0b34 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_7_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_8.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_8.png new file mode 100644 index 000000000..f332eebc0 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_8.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_8_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_8_mask.png new file mode 100644 index 000000000..751fb9bc0 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_8_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_9.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_9.png new file mode 100644 index 000000000..dfbe0b574 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_9.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_9_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_9_mask.png new file mode 100644 index 000000000..a5ba8f989 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_hair_9_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_1.png new file mode 100644 index 000000000..3a0fcf1a9 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_1.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_2.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_2.png new file mode 100644 index 000000000..5e288734d Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_2.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_3.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_3.png new file mode 100644 index 000000000..682eb4df4 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_3.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_4.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_4.png new file mode 100644 index 000000000..1b278d5b0 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_4.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_5.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_5.png new file mode 100644 index 000000000..0246dccda Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_5.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_6.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_6.png new file mode 100644 index 000000000..9c9ab1a02 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_6.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_7.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_7.png new file mode 100644 index 000000000..755b82a84 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_headwear_7.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_1.png new file mode 100644 index 000000000..7b48bc770 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_1.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_2.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_2.png new file mode 100644 index 000000000..2ac147e31 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_2.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_3.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_3.png new file mode 100644 index 000000000..9bb46f618 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_3.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_4.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_4.png new file mode 100644 index 000000000..a01f7ed05 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_4.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_5.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_5.png new file mode 100644 index 000000000..74a25a93e Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_5.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_6.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_6.png new file mode 100644 index 000000000..3b93aaead Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_6.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_7.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_7.png new file mode 100644 index 000000000..0b1afb994 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_mouth_7.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_select_overlay.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_select_overlay.png new file mode 100644 index 000000000..93e656703 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_select_overlay.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_slim_arms.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_slim_arms.png new file mode 100644 index 000000000..5e220587e Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_slim_arms.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_thick_arms.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_thick_arms.png new file mode 100644 index 000000000..95b189924 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_thick_arms.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_1.png new file mode 100644 index 000000000..aeddf5212 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_1.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_10.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_10.png new file mode 100644 index 000000000..d7e0191cd Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_10.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_10_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_10_mask.png new file mode 100644 index 000000000..f5d8d40b8 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_10_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_1_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_1_mask.png new file mode 100644 index 000000000..64df0b039 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_1_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_2.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_2.png new file mode 100644 index 000000000..5deb9f8bb Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_2.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_2_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_2_mask.png new file mode 100644 index 000000000..564f938a6 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_2_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_3.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_3.png new file mode 100644 index 000000000..14b65d09a Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_3.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_3_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_3_mask.png new file mode 100644 index 000000000..0e87301de Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_3_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_4.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_4.png new file mode 100644 index 000000000..693ef3216 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_4.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_4_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_4_mask.png new file mode 100644 index 000000000..a7e5ce8af Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_4_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_5.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_5.png new file mode 100644 index 000000000..fc1e798b7 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_5.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_5_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_5_mask.png new file mode 100644 index 000000000..b846c71e1 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_5_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_6.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_6.png new file mode 100644 index 000000000..6f9f7dcc0 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_6.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_6_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_6_mask.png new file mode 100644 index 000000000..c89bc3624 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_6_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_7.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_7.png new file mode 100644 index 000000000..844c09ac8 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_7.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_7_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_7_mask.png new file mode 100644 index 000000000..0a6e65227 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_7_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_8.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_8.png new file mode 100644 index 000000000..da32f24c6 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_8.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_8_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_8_mask.png new file mode 100644 index 000000000..e4f61a4cc Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_8_mask.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_9.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_9.png new file mode 100644 index 000000000..2b65eca98 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_9.png differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_top_9_mask.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_9_mask.png new file mode 100644 index 000000000..55c1dd993 Binary files /dev/null and b/mods/PLAYER/mcl_skins/textures/mcl_skins_top_9_mask.png differ diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index 9022dfc25..eb0208dcb 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -4,6 +4,10 @@ local S = minetest.get_translator(minetest.get_current_modname()) local mg_name = minetest.get_mapgen_setting("mg_name") local storage = minetest.get_mod_storage() +local function mcl_log (message) + mcl_util.mcl_log (message, "[Spawn]") +end + -- Parameters ------------- @@ -429,6 +433,43 @@ function mcl_spawn.set_spawn_pos(player, pos, message) else local oldpos = minetest.string_to_pos(meta:get_string("mcl_beds:spawn")) meta:set_string("mcl_beds:spawn", minetest.pos_to_string(pos)) + + -- Set player ownership on bed + local bed_node = minetest.get_node(pos) + local bed_meta = minetest.get_meta(pos) + + local bed_bottom = mcl_beds.get_bed_bottom (pos) + local bed_bottom_meta = minetest.get_meta(bed_bottom) + + if bed_meta then + if bed_node then + mcl_log("Bed name: " .. bed_node.name) + end + + mcl_log("Setting bed meta: " .. player:get_player_name()) + bed_meta:set_string("player", player:get_player_name()) + + -- Pass in villager as arg. Shouldn't know about villagers + if bed_bottom_meta then + mcl_log("Removing villager from bed bottom meta") + bed_bottom_meta:set_string("villager", nil) + else + mcl_log("Cannot remove villager from bed bottom meta") + end + + + + if oldpos and oldpos ~= pos then + local old_bed_meta = minetest.get_meta(oldpos) + if old_bed_meta then + mcl_log("Removing old bed meta") + old_bed_meta:set_string("player", "") + end + else + mcl_log("No old bed meta to remove or same as current") + end + end + if oldpos then -- We don't bother sending a message if the new spawn pos is basically the same spawn_changed = vector.distance(pos, oldpos) > 0.1 diff --git a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.fr.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.fr.tr index f1fab2bf1..a2e5fbd8e 100644 --- a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.fr.tr +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.fr.tr @@ -1,4 +1,5 @@ # textdomain: mcl_spawn -New respawn position set!=Nouvelle position de réapparition définie! -Respawn position cleared!=Position de réapparition supprimée! -Your spawn bed was missing or blocked.=Votre lit d'apparition était manquant ou bloqué. +New respawn position set!=Nouvelle position de réapparition définie ! +Respawn position cleared!=Position de réapparition supprimée ! +Couldn't get level of your respawn anchor!=Impossible d'obtenir le niveau de votre ancre de réapparition ! +Your spawn bed was missing or blocked, and you had no charged respawn anchor!=Votre lit d'apparition était manquant ou bloqué, et vou n'avez pas d'ancre de réapparition chargée ! \ No newline at end of file diff --git a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ja.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ja.tr new file mode 100644 index 000000000..079683f68 --- /dev/null +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_spawn +New respawn position set!=新しいリスポーン位置を設定しました! +Respawn position cleared!=リスポーン位置をクリアしました! +Couldn't get level of your respawn anchor!=リスポーン アンカーのレベルを取得できませんでした! +Your spawn bed was missing or blocked, and you had no charged respawn anchor!=リスポーン ベッドが見つからないかブロックされており、あとチャージされたリスポーン アンカーがありませんでした! \ No newline at end of file diff --git a/mods/PLAYER/mcl_sprint/init.lua b/mods/PLAYER/mcl_sprint/init.lua index 4c0d609c9..7449ad18c 100644 --- a/mods/PLAYER/mcl_sprint/init.lua +++ b/mods/PLAYER/mcl_sprint/init.lua @@ -65,6 +65,7 @@ local function cancelClientSprinting(name) end local function setSprinting(playerName, sprinting) --Sets the state of a player (0=stopped/moving, 1=sprinting) + if not sprinting and not mcl_sprint.is_sprinting(playerName) then return end local player = minetest.get_player_by_name(playerName) local controls = player:get_player_control() if players[playerName] then diff --git a/mods/PLAYER/mcl_wieldview/README.txt b/mods/PLAYER/mcl_wieldview/README.txt index 183e8c6d5..b6de5b208 100644 --- a/mods/PLAYER/mcl_wieldview/README.txt +++ b/mods/PLAYER/mcl_wieldview/README.txt @@ -1,21 +1,13 @@ -[mod] visible wielded items [wieldview] +[mod] visible wielded items [mcl_wieldview] ======================================= Makes hand wielded items visible to other players. -default settings: [minetest.conf] - -# Set number of seconds between visible wielded item updates. -wieldview_update_time = 2 - -# Show nodes as tiles, disabled by default -wieldview_node_tiles = false - Info for modders ################ -Wield image transformation: To apply a simple transformation to the item in -hand, add the group “wieldview_transform” to the item definition. The group -rating equals one of the numbers used for the [transform texture modifier -of the Lua API. +Register an item with the property "_mcl_wieldview_item" to change the third person wield view appearance of the item. +"_mcl_wieldview_item" should be set to an item name that will be shown by the wield view instead of the item. +If you use an empty string, nothing will be shown. + diff --git a/mods/PLAYER/mcl_wieldview/init.lua b/mods/PLAYER/mcl_wieldview/init.lua index ff70445e3..3a646a18a 100644 --- a/mods/PLAYER/mcl_wieldview/init.lua +++ b/mods/PLAYER/mcl_wieldview/init.lua @@ -1,126 +1,64 @@ -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 == "" or minetest.get_item_group(itemname, "no_wieldview") ~= 0 then - return - end - - local def = minetest.registered_items[itemname] - if not def then - return - end - - local inv_image = def.inventory_image - if inv_image == "" then - return - end - - local texture = inv_image - - 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 - texture = texture .. "^[transform" .. transform - end - - return texture -end - -function mcl_wieldview.update_wielded_item(player) - if not player then - return - end - local itemstack = player:get_wielded_item() - local itemname = itemstack:get_name() - - local def = mcl_wieldview.players[player] - - if def.item == itemname then - return - end - - def.item = itemname - def.texture = mcl_wieldview.get_item_texture(itemname) or "blank.png" - - mcl_player.player_set_wielditem(player, def.texture) -end - -minetest.register_on_joinplayer(function(player) - mcl_wieldview.players[player] = {item = "", texture = "blank.png"} - - minetest.after(0, function() - if not player:is_player() then - return - end - - mcl_wieldview.update_wielded_item(player) - - local itementity = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldnode") - itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45)) - itementity:get_luaentity().wielder = player - end) -end) - -minetest.register_on_leaveplayer(function(player) - mcl_wieldview.players[player] = nil -end) - -minetest.register_globalstep(function() - local players = get_connected_players() - for i = 1, #players do - mcl_wieldview.update_wielded_item(players[i]) - end -end) - -minetest.register_entity("mcl_wieldview:wieldnode", { +minetest.register_entity("mcl_wieldview:wieldview", { initial_properties = { hp_max = 1, visual = "wielditem", physical = false, - textures = {""}, - automatic_rotate = 1.5, - is_visible = true, + is_visible = false, pointable = false, collide_with_objects = false, static_save = false, collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, visual_size = {x = 0.21, y = 0.21}, - }, - - itemstring = "", - - on_step = function(self) - if self.wielder:is_player() then - local def = mcl_wieldview.players[self.wielder] - local itemstring = def.item - - if self.itemstring ~= itemstring then - local itemdef = minetest.registered_items[itemstring] - self.object:set_properties({glow = itemdef and itemdef.light_source or 0}) - - -- wield item as cubic - if def.texture == "blank.png" then - self.object:set_properties({textures = {itemstring}}) - -- wield item as flat - else - 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 - self.object:remove() - end - end, + } }) + +local wieldview_luaentites = {} + +local function update_wieldview_entity(player) + local luaentity = wieldview_luaentites[player] + if luaentity and luaentity.object:get_yaw() then + local item = player:get_wielded_item():get_name() + + if item == luaentity._item then return end + + luaentity._item = item + + local def = player:get_wielded_item():get_definition() + if def and def._mcl_wieldview_item then + item = def._mcl_wieldview_item + end + + local item_def = minetest.registered_items[item] + luaentity.object:set_properties({ + glow = item_def and item_def.light_source or 0, + wield_item = item, + is_visible = item ~= "" + }) + else + -- If the player is running through an unloaded area, + -- the wieldview entity will sometimes get unloaded. + -- This code path is also used to initalize the wieldview. + -- Creating entites from minetest.register_on_joinplayer + -- is unreliable as of Minetest 5.6 + local obj_ref = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldview") + if not obj_ref then return end + obj_ref:set_attach(player, "Wield_Item") + --obj_ref:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 45, 90)) + wieldview_luaentites[player] = obj_ref:get_luaentity() + end +end + +minetest.register_on_leaveplayer(function(player) + if wieldview_luaentites[player] then + wieldview_luaentites[player].object:remove() + end + wieldview_luaentites[player] = nil +end) + +minetest.register_globalstep(function(dtime) + local players = minetest.get_connected_players() + for i, player in pairs(players) do + update_wieldview_entity(player) + end +end) diff --git a/mods/PLAYER/mcl_wieldview/mod.conf b/mods/PLAYER/mcl_wieldview/mod.conf index 4b3097876..7ed41eeb4 100644 --- a/mods/PLAYER/mcl_wieldview/mod.conf +++ b/mods/PLAYER/mcl_wieldview/mod.conf @@ -1,4 +1,4 @@ name = mcl_wieldview author = stujones11 description = Makes hand wielded items visible to other players. -depends = mcl_player +depends = mcl_armor, mcl_playerplus diff --git a/screenshot.png b/screenshot.png index a92bd53e5..12cc5db22 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/settingtypes.txt b/settingtypes.txt index 8a0ebcce8..25ac943ea 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -20,6 +20,18 @@ enable_fire (Destructive and spreading fire) bool true # If enabled, the weather will change naturally over time. mcl_doWeatherCycle (Change weather) bool true +# Amount of rain particles. You can reduce this to get better FPS (default: 500) +mcl_weather_rain_particles (Rain particles) int 500 0 + +# Amount of thunderstorm rain particles. You can reduce this to get better FPS (default: 900) +mcl_weather_thunder_particles (Thunderstorm rain particles) int 900 0 + +# Amount of snow particles. You can reduce this to get better FPS (default: 100) +mcl_weather_snow_particles (Snow particles) int 100 0 + +# Amount of nether dust particles. You can reduce this to get better FPS (default: 150) +mcl_weather_dust_particles (Nether dust particles) int 150 0 + # If enabled, breaking blocks will cause them to drop as item. # Note that blocks never have drops when in Creative Mode. mcl_doTileDrops (Blocks have drops) bool true @@ -27,6 +39,12 @@ mcl_doTileDrops (Blocks have drops) bool true # If enabled, TNT explosions destroy blocks. mcl_tnt_griefing (TNT destroys blocks) bool true +# Comma separated list of disabled structure names +mcl_disabled_structures (Disabled structures) string + +# Comma separated list of disabled event names +mcl_disabled_events (Disabled events) string + [Players] # If enabled, players respawn at the bed they last lay on instead of normal # spawn. @@ -51,16 +69,26 @@ mcl_showDeathMessages (Show death messages) bool true # If disabled, all recipes will be shown. mcl_craftguide_progressive_mode (Learn crafting recipes progressively) bool true +# If disabled, the skin of all players will be character.png +mcl_enable_skin_customization (Enable player skin customization) bool true + +# How far the player hand can reach +# Default:4.5 +mcl_hand_range (Hand range) float 4.5 1 128 + +# How far the player hand can reach in creative mode (not gamemode-creative) +# Default:10 +mcl_hand_range_creative (Creative mode hand range) float 10 1 128 + +# If enabled the hunger mechanic will be active +mcl_enable_hunger (Hunger mechanic) bool true + [Mobs] # If enabled, mobs will spawn naturally. This does not affect # affect mob spawners. # This setting is only read at startup. mobs_spawn (Spawn mobs naturally) bool true -# Controls the overall amount of mobs that spawn. The higher the number, -# the less often mobs will spawn. This does not affect mob spawners. -mobs_spawn_chance (Mob spawn chance) float 2.5 0.0 - # If enabled, only peaceful mobs will appear naturally. This does not # affect mob spawners. # This setting is only read at startup. @@ -84,6 +112,29 @@ mobs_griefing (Mobs change blocks) bool true # If enabled, mobs won't damage particles when they got hurt. mobs_disable_blood (Disable mob damage particles) bool false +#Maximum amount mobs (default:500) +mcl_mob_cap_total (Global mob cap) int 500 0 2048 + +#Maximum amount of mobs per player (default:75) +mcl_mob_cap_player (Mob cap per player) int 75 0 2048 + +#Maximum amount of monsters that will spawn near a player (default:70) +mcl_mob_cap_monster (Mob cap monsters) int 70 0 2048 + +#Maximum amount of animals that will spawn near a player (default:10) +mcl_mob_cap_animal (Mob cap animals) int 10 0 1024 + +#Maximum amount of ambient mobs that will spawn near a player (default:15) +mcl_mob_cap_ambient (Mob cap ambient mobs) int 15 0 1024 + +#Display mob icons in inventory instead of mc-like spawn eggs +mcl_old_spawn_icons (Old spawn icons instead of eggs) bool false + +# How far from players should mobs stop moving +# Larger values will have a larger performance impact (default:48) +mcl_mob_active_range (Active mob range) int 48 0 256 + + [Audio] # Enable flame sound. flame_sound (Flame sound) bool true @@ -100,6 +151,13 @@ animated_chests (Animated chests) bool true # The maximum number of boss bars to simultaniously display on the screen max_bossbars (Maximum Boss bars) int 5 +# Default intensity of shadows (default: 0.33) +mcl_default_shadow_intensity (Default shadow intensity) float 0.33 0.0 1.0 + +# When enabled, when a player holds a bucket, a select box will be shown around liquid nodes. +# Selecting liquid nodes on clients without a cross hair will not work correctly if this setting is disabled. +mcl_buckets_use_select_box (Buckets use select box) bool false + [Experimental] # Whether ice is translucent. If disabled, ice is fully opaque. # @@ -129,6 +187,9 @@ mcl_generate_fallen_logs (Generate fallen logs) bool false # But creating new flat worlds after changing this setting should be safe. mcl_superflat_classic (Classic superflat map generation) bool false +# If disabled, no deepslate will be generated. +mcl_generate_deepslate (Generate Deepslate) bool true + # If disabled, no ores will be generated. mcl_generate_ores (Generate Ores) bool true @@ -154,6 +215,34 @@ fix_doubleplants (Mcimport double plant fixes) bool true # Allow players to create Minecraft-like maps. enable_real_maps (Enable Real Maps) bool true +[Additional Features] +# Enable Bookshelf inventories +mcl_bookshelf_inventories (Enable bookshelf inventories) bool true + +# Enable swiftness on enchanted golden apples +mcl_enable_fapples (Enable swiftness on enchanted golden apples) bool true + +# All tameable mobs listen to the "sit" righclick like dogs +mcl_extended_pet_control (Extended pet control) bool true + +# Enable hamburgers for villagers to follow +mcl_enable_hamburger (Enable Hamburger) bool true + [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 +mcl_item_id_debug (Item ID Debug) bool false + +#Log mob spawning and despawning events +mcl_logging_mobs_spawn (Log Mob Spawning) bool true + +# If enabled mapgen timings will be dumped to log +mcl_logging_mapgen (Chunk generation logging) bool false + +# If enabled generated structures will be logged +mcl_logging_structures (Structure generation logging) bool true + +#Complete debug logging for mcl_signs events. Use this if you have issues with signs. +mcl_logging_mcl_signs (Complete debug logging for mcl_signs) bool false + +#Debug logging for mcl_events. +mcl_logging_event_api (Debug logging for mcl_events) bool false diff --git a/tools/Texture_Converter.py b/tools/Texture_Converter.py index bdf249113..67800ccfc 100755 --- a/tools/Texture_Converter.py +++ b/tools/Texture_Converter.py @@ -196,7 +196,8 @@ def convert_textures(): [ tex_dir + "/models/armor/chainmail_layer_1.png", tex_dir + "/models/armor/chainmail_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_chain.png", "mcl_armor_chestplate_chain.png", "mcl_armor_leggings_chain.png", "mcl_armor_boots_chain.png" ], [ tex_dir + "/models/armor/gold_layer_1.png", tex_dir + "/models/armor/gold_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_gold.png", "mcl_armor_chestplate_gold.png", "mcl_armor_leggings_gold.png", "mcl_armor_boots_gold.png" ], [ tex_dir + "/models/armor/iron_layer_1.png", tex_dir + "/models/armor/iron_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_iron.png", "mcl_armor_chestplate_iron.png", "mcl_armor_leggings_iron.png", "mcl_armor_boots_iron.png" ], - [ tex_dir + "/models/armor/diamond_layer_1.png", tex_dir + "/models/armor/diamond_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_diamond.png", "mcl_armor_chestplate_diamond.png", "mcl_armor_leggings_diamond.png", "mcl_armor_boots_diamond.png" ] + [ tex_dir + "/models/armor/diamond_layer_1.png", tex_dir + "/models/armor/diamond_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_diamond.png", "mcl_armor_chestplate_diamond.png", "mcl_armor_leggings_diamond.png", "mcl_armor_boots_diamond.png" ], + [ tex_dir + "/models/armor/netherite_layer_1.png", tex_dir + "/models/armor/netherite_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_netherite.png", "mcl_armor_chestplate_netherite.png", "mcl_armor_leggings_netherite.png", "mcl_armor_boots_netherite.png" ] ] for a in armor_files: APXSIZE = 16 # for some reason MineClone2 requires this diff --git a/tools/colors.txt b/tools/colors.txt new file mode 100644 index 000000000..de20aa49a --- /dev/null +++ b/tools/colors.txt @@ -0,0 +1,2240 @@ +## Mcl2 colors.txt file for minetestmapper +## by Ranko Saotome using the tools provided by minetestmapper + +# mcl_amethyst +mcl_amethyst:amethyst_block 143 94 174 +mcl_amethyst:amethyst_cluster 165 121 193 +mcl_amethyst:budding_amethyst_block 138 88 170 +mcl_amethyst:calcite 189 193 207 +mcl_amethyst:large_amethyst_bud 177 136 203 +mcl_amethyst:medium_amethyst_bud 187 148 212 +mcl_amethyst:small_amethyst_bud 181 140 206 +mcl_amethyst:tinted_glass 126 74 160 + +# mcl_anvils +mcl_anvils:anvil 53 53 53 +mcl_anvils:anvil_damage_1 52 52 52 +mcl_anvils:anvil_damage_2 50 50 50 + +# mcl_armor_stand +mcl_armor_stand:armor_stand 115 89 68 + +# mcl_banners +mcl_banners:hanging_banner 102 88 74 +mcl_banners:standing_banner 102 88 74 + +# mcl_barrels +mcl_barrels:barrel_closed 81 63 49 +mcl_barrels:barrel_open 60 46 36 + +# mcl_beacons +mcl_beacons:beacon 116 168 197 + +# mcl_beds +mcl_beds:bed_black_bottom 109 90 78 +mcl_beds:bed_black_top 109 90 78 +mcl_beds:bed_blue_bottom 108 98 107 +mcl_beds:bed_blue_top 108 98 107 +mcl_beds:bed_brown_bottom 121 94 79 +mcl_beds:bed_brown_top 121 94 79 +mcl_beds:bed_cyan_bottom 109 106 102 +mcl_beds:bed_cyan_top 109 106 102 +mcl_beds:bed_green_bottom 109 103 79 +mcl_beds:bed_green_top 109 103 79 +mcl_beds:bed_grey_bottom 119 100 89 +mcl_beds:bed_grey_top 119 100 89 +mcl_beds:bed_light_blue_bottom 118 118 134 +mcl_beds:bed_light_blue_top 118 118 134 +mcl_beds:bed_lime_bottom 122 123 87 +mcl_beds:bed_lime_top 122 123 87 +mcl_beds:bed_magenta_bottom 136 101 112 +mcl_beds:bed_magenta_top 136 101 112 +mcl_beds:bed_orange_bottom 152 107 81 +mcl_beds:bed_orange_top 152 107 81 +mcl_beds:bed_pink_bottom 152 111 106 +mcl_beds:bed_pink_top 152 111 106 +mcl_beds:bed_purple_bottom 119 94 102 +mcl_beds:bed_purple_top 119 94 102 +mcl_beds:bed_red_bottom 136 90 79 +mcl_beds:bed_red_top 136 90 79 +mcl_beds:bed_silver_bottom 137 118 109 +mcl_beds:bed_silver_top 137 118 109 +mcl_beds:bed_white_bottom 170 152 135 +mcl_beds:bed_white_top 170 152 135 +mcl_beds:bed_yellow_bottom 161 134 86 +mcl_beds:bed_yellow_top 161 134 86 +mcl_beds:respawn_anchor 93 75 91 +mcl_beds:respawn_anchor_charged_1 105 75 136 +mcl_beds:respawn_anchor_charged_2 105 75 136 +mcl_beds:respawn_anchor_charged_3 105 75 136 +mcl_beds:respawn_anchor_charged_4 105 75 136 + +# mcl_bells +mcl_bells:bell 207 203 82 + +# mcl_blackstone +mcl_blackstone:basalt 71 71 71 +mcl_blackstone:basalt_polished 80 79 79 +mcl_blackstone:basalt_smooth 88 87 88 +mcl_blackstone:blackstone 33 31 35 +mcl_blackstone:blackstone_brick_polished 42 39 44 +mcl_blackstone:blackstone_chiseled_polished 42 39 44 +mcl_blackstone:blackstone_gilded 33 31 35 +mcl_blackstone:blackstone_polished 44 42 47 +mcl_blackstone:nether_gold 133 52 40 +mcl_blackstone:quartz_brick 190 185 182 +mcl_blackstone:soul_fire 89 169 169 +mcl_blackstone:soul_soil 94 72 54 +mcl_blackstone:soul_torch 98 108 100 +mcl_blackstone:soul_torch_wall 98 108 100 +mcl_blackstone:wall 33 31 35 +mcl_blackstone:wall_0 33 31 35 +mcl_blackstone:wall_1 33 31 35 +mcl_blackstone:wall_10 33 31 35 +mcl_blackstone:wall_11 33 31 35 +mcl_blackstone:wall_12 33 31 35 +mcl_blackstone:wall_13 33 31 35 +mcl_blackstone:wall_14 33 31 35 +mcl_blackstone:wall_15 33 31 35 +mcl_blackstone:wall_16 33 31 35 +mcl_blackstone:wall_2 33 31 35 +mcl_blackstone:wall_21 33 31 35 +mcl_blackstone:wall_3 33 31 35 +mcl_blackstone:wall_4 33 31 35 +mcl_blackstone:wall_5 33 31 35 +mcl_blackstone:wall_6 33 31 35 +mcl_blackstone:wall_7 33 31 35 +mcl_blackstone:wall_8 33 31 35 +mcl_blackstone:wall_9 33 31 35 + +# mcl_blast_furnace +mcl_blast_furnace:blast_furnace 130 120 115 +mcl_blast_furnace:blast_furnace_active 130 120 115 + +# mcl_books +mcl_books:bookshelf 111 86 66 + +# mcl_brewing +mcl_brewing:stand_000 141 134 134 +mcl_brewing:stand_001 141 134 134 +mcl_brewing:stand_010 141 134 134 +mcl_brewing:stand_011 141 134 134 +mcl_brewing:stand_100 141 134 134 +mcl_brewing:stand_101 141 134 134 +mcl_brewing:stand_110 141 134 134 +mcl_brewing:stand_111 141 134 134 + +# mcl_cake +mcl_cake:cake 241 233 231 +mcl_cake:cake_1 241 233 231 +mcl_cake:cake_2 241 233 231 +mcl_cake:cake_3 241 233 231 +mcl_cake:cake_4 241 233 231 +mcl_cake:cake_5 241 233 231 +mcl_cake:cake_6 241 233 231 + +# mcl_campfires +mcl_campfires:campfire 83 69 65 +mcl_campfires:campfire_lit 210 114 39 +mcl_campfires:soul_campfire 83 69 65 +mcl_campfires:soul_campfire_lit 39 189 195 + +# mcl_cartography_table +mcl_cartography_table:cartography_table 127 110 96 + +# mcl_cauldrons +mcl_cauldrons:cauldron 25 25 25 +mcl_cauldrons:cauldron_1 38 98 129 +mcl_cauldrons:cauldron_1_lava 183 54 21 +mcl_cauldrons:cauldron_1r 32 121 138 +mcl_cauldrons:cauldron_2 38 98 129 +mcl_cauldrons:cauldron_2_lava 183 54 21 +mcl_cauldrons:cauldron_2r 32 121 138 +mcl_cauldrons:cauldron_3 38 98 129 +mcl_cauldrons:cauldron_3_lava 183 54 21 +mcl_cauldrons:cauldron_3r 32 121 138 + +# mcl_chests +mcl_chests:black_shulker_box 101 92 87 +mcl_chests:blue_shulker_box 107 109 128 +mcl_chests:brown_shulker_box 110 95 82 +mcl_chests:chest 100 79 62 +mcl_chests:cyan_shulker_box 107 121 130 +mcl_chests:dark_green_shulker_box 107 128 92 +mcl_chests:dark_grey_shulker_box 119 112 113 +mcl_chests:dark_grey_shulker_box_small 0 0 0 +mcl_chests:ender_chest 75 68 62 +mcl_chests:green_shulker_box 120 136 95 +mcl_chests:grey_shulker_box 147 142 145 +mcl_chests:lightblue_shulker_box 124 143 159 +mcl_chests:magenta_shulker_box 148 106 132 +mcl_chests:orange_shulker_box 160 102 80 +mcl_chests:pink_shulker_box 176 131 161 +mcl_chests:red_shulker_box 151 92 83 +mcl_chests:trapped_chest 100 79 62 +mcl_chests:trapped_chest_on 100 79 62 +mcl_chests:violet_shulker_box 142 99 104 +mcl_chests:white_shulker_box 186 183 187 +mcl_chests:yellow_shulker_box 178 132 81 + +# mcl_cocoas +mcl_cocoas:cocoa_3 140 74 54 + +# mcl_colorblocks +mcl_colorblocks:concrete_black 8 10 15 +mcl_colorblocks:concrete_blue 46 48 147 +mcl_colorblocks:concrete_brown 98 60 32 +mcl_colorblocks:concrete_cyan 21 123 140 +mcl_colorblocks:concrete_green 75 94 37 +mcl_colorblocks:concrete_grey 56 59 64 +mcl_colorblocks:concrete_light_blue 37 140 200 +mcl_colorblocks:concrete_lime 96 171 25 +mcl_colorblocks:concrete_magenta 171 49 162 +mcl_colorblocks:concrete_orange 226 101 1 +mcl_colorblocks:concrete_pink 213 103 144 +mcl_colorblocks:concrete_powder_black 23 26 30 +mcl_colorblocks:concrete_powder_blue 72 76 169 +mcl_colorblocks:concrete_powder_brown 128 87 54 +mcl_colorblocks:concrete_powder_cyan 38 150 160 +mcl_colorblocks:concrete_powder_green 104 127 45 +mcl_colorblocks:concrete_powder_grey 91 98 103 +mcl_colorblocks:concrete_powder_light_blue 76 181 212 +mcl_colorblocks:concrete_powder_lime 126 186 42 +mcl_colorblocks:concrete_powder_magenta 196 94 189 +mcl_colorblocks:concrete_powder_orange 227 141 38 +mcl_colorblocks:concrete_powder_pink 224 149 176 +mcl_colorblocks:concrete_powder_purple 138 58 180 +mcl_colorblocks:concrete_powder_red 172 57 52 +mcl_colorblocks:concrete_powder_silver 160 160 155 +mcl_colorblocks:concrete_powder_white 224 225 225 +mcl_colorblocks:concrete_powder_yellow 230 198 54 +mcl_colorblocks:concrete_purple 103 32 159 +mcl_colorblocks:concrete_red 146 34 34 +mcl_colorblocks:concrete_silver 128 129 118 +mcl_colorblocks:concrete_white 208 214 215 +mcl_colorblocks:concrete_yellow 241 177 21 +mcl_colorblocks:glazed_terracotta_black 61 28 28 +mcl_colorblocks:glazed_terracotta_blue 35 83 135 +mcl_colorblocks:glazed_terracotta_brown 116 93 73 +mcl_colorblocks:glazed_terracotta_cyan 117 144 148 +mcl_colorblocks:glazed_terracotta_green 122 141 83 +mcl_colorblocks:glazed_terracotta_grey 96 96 96 +mcl_colorblocks:glazed_terracotta_light_blue 123 174 208 +mcl_colorblocks:glazed_terracotta_lime 160 213 86 +mcl_colorblocks:glazed_terracotta_magenta 210 112 216 +mcl_colorblocks:glazed_terracotta_orange 196 150 102 +mcl_colorblocks:glazed_terracotta_pink 251 145 173 +mcl_colorblocks:glazed_terracotta_purple 118 55 159 +mcl_colorblocks:glazed_terracotta_red 189 72 63 +mcl_colorblocks:glazed_terracotta_silver 150 160 160 +mcl_colorblocks:glazed_terracotta_white 205 217 219 +mcl_colorblocks:glazed_terracotta_yellow 236 205 111 +mcl_colorblocks:hardened_clay 143 104 88 +mcl_colorblocks:hardened_clay_black 70 53 46 +mcl_colorblocks:hardened_clay_blue 68 91 143 +mcl_colorblocks:hardened_clay_brown 96 69 61 +mcl_colorblocks:hardened_clay_cyan 71 108 124 +mcl_colorblocks:hardened_clay_green 75 102 63 +mcl_colorblocks:hardened_clay_grey 110 92 85 +mcl_colorblocks:hardened_clay_light_blue 91 128 171 +mcl_colorblocks:hardened_clay_lime 106 135 73 +mcl_colorblocks:hardened_clay_magenta 150 80 85 +mcl_colorblocks:hardened_clay_orange 157 95 70 +mcl_colorblocks:hardened_clay_pink 164 80 76 +mcl_colorblocks:hardened_clay_purple 82 71 124 +mcl_colorblocks:hardened_clay_red 159 82 67 +mcl_colorblocks:hardened_clay_silver 149 129 117 +mcl_colorblocks:hardened_clay_white 213 197 184 +mcl_colorblocks:hardened_clay_yellow 177 128 51 + +# mcl_comparators +mcl_comparators:comparator_off_comp 116 106 102 +mcl_comparators:comparator_off_sub 116 106 102 +mcl_comparators:comparator_on_comp 118 106 102 +mcl_comparators:comparator_on_sub 118 106 102 + +# mcl_compass +mcl_compass:lodestone 86 76 72 + +# mcl_composters +mcl_composters:composter 143 112 88 +mcl_composters:composter_1 76 76 41 +mcl_composters:composter_2 76 76 41 +mcl_composters:composter_3 76 76 41 +mcl_composters:composter_4 76 76 41 +mcl_composters:composter_5 76 76 41 +mcl_composters:composter_6 76 76 41 +mcl_composters:composter_7 76 76 41 +mcl_composters:composter_ready 124 120 95 + +# mcl_copper +mcl_copper:block 150 78 57 +mcl_copper:block_cut 150 78 58 +mcl_copper:block_exposed 130 94 84 +mcl_copper:block_exposed_cut 132 94 84 +mcl_copper:block_oxidized 90 110 111 +mcl_copper:block_oxidized_cut 91 112 112 +mcl_copper:block_raw 171 91 69 +mcl_copper:block_weathered 104 104 102 +mcl_copper:block_weathered_cut 109 105 102 +mcl_copper:stone_with_copper 131 123 118 + +# mcl_core +mcl_core:acacialeaves 110 88 44 +mcl_core:acaciasapling 111 94 65 +mcl_core:acaciatree 137 89 58 +mcl_core:acaciatree_bark 107 94 77 +mcl_core:acaciawood 153 103 71 +mcl_core:andesite 105 111 107 +mcl_core:andesite_smooth 107 114 110 +mcl_core:bedrock 92 79 68 +mcl_core:birchleaves 27 56 27 +mcl_core:birchsapling 93 114 84 +mcl_core:birchtree 160 137 119 +mcl_core:birchtree_bark 199 190 180 +mcl_core:birchwood 147 116 90 +mcl_core:bone_block 222 203 171 +mcl_core:brick_block 140 92 81 +mcl_core:cactus 90 106 66 +mcl_core:clay 124 124 124 +mcl_core:coalblock 54 51 54 +mcl_core:coarse_dirt 119 94 78 +mcl_core:cobble 114 108 105 +mcl_core:cobweb 203 190 168 +mcl_core:crying_obsidian 26 19 41 +mcl_core:darkleaves 20 69 28 +mcl_core:darksapling 70 98 85 +mcl_core:darktree 87 74 66 +mcl_core:darktree_bark 77 65 58 +mcl_core:darkwood 89 76 63 +mcl_core:deadbush 121 91 70 +mcl_core:diamondblock 98 164 203 +mcl_core:diorite 154 150 148 +mcl_core:diorite_smooth 158 155 153 +mcl_core:dirt 109 84 70 +mcl_core:dirt_with_grass 64 111 26 +mcl_core:dirt_with_grass_snow 221 229 234 +mcl_core:emeraldblock 56 146 49 +mcl_core:frosted_ice_0 141 194 224 +mcl_core:frosted_ice_1 149 199 227 +mcl_core:frosted_ice_2 155 203 229 +mcl_core:frosted_ice_3 168 210 233 +mcl_core:glass 215 224 235 +mcl_core:glass_black 25 25 25 +mcl_core:glass_blue 51 76 178 +mcl_core:glass_brown 102 76 51 +mcl_core:glass_cyan 76 127 153 +mcl_core:glass_gray 76 76 76 +mcl_core:glass_green 102 127 51 +mcl_core:glass_light_blue 102 153 216 +mcl_core:glass_lime 127 204 25 +mcl_core:glass_magenta 178 76 216 +mcl_core:glass_orange 216 127 51 +mcl_core:glass_pink 242 127 165 +mcl_core:glass_purple 127 63 178 +mcl_core:glass_red 153 51 51 +mcl_core:glass_silver 153 153 153 +mcl_core:glass_white 255 255 255 +mcl_core:glass_yellow 229 229 51 +mcl_core:goldblock 196 153 69 +mcl_core:granite 155 122 111 +mcl_core:granite_smooth 151 122 111 +mcl_core:grass_path 148 122 65 +mcl_core:gravel 137 142 140 +mcl_core:ice 146 198 227 +mcl_core:ironblock 164 157 157 +mcl_core:jungleleaves 29 84 30 +mcl_core:junglesapling 66 91 40 +mcl_core:jungletree 132 92 70 +mcl_core:jungletree_bark 90 62 46 +mcl_core:junglewood 114 80 60 +mcl_core:ladder 85 66 51 +mcl_core:lapisblock 58 97 165 +mcl_core:lava_source 255 100 0 +mcl_core:lava_flowing 255 100 0 +mcl_core:leaves 40 80 39 +mcl_core:mossycobble 105 106 97 +mcl_core:mycelium 109 89 118 +mcl_core:mycelium_snow 221 229 234 +mcl_core:obsidian 26 19 41 +mcl_core:packed_ice 166 212 231 +mcl_core:podzol 86 64 43 +mcl_core:podzol_snow 221 229 234 +mcl_core:redsand 225 137 111 +mcl_core:redsandstone 212 126 108 +mcl_core:redsandstonecarved 212 126 108 +mcl_core:redsandstonesmooth 212 126 108 +mcl_core:redsandstonesmooth2 212 126 108 +mcl_core:reeds 107 107 107 +mcl_core:sand 221 171 127 +mcl_core:sandstone 202 155 121 +mcl_core:sandstonecarved 202 155 121 +mcl_core:sandstonesmooth 202 155 121 +mcl_core:sandstonesmooth2 202 155 121 +mcl_core:sapling 66 93 47 +mcl_core:slimeblock 93 157 87 +mcl_core:snow 221 229 234 +mcl_core:snow_2 221 229 234 +mcl_core:snow_3 221 229 234 +mcl_core:snow_4 221 229 234 +mcl_core:snow_5 221 229 234 +mcl_core:snow_6 221 229 234 +mcl_core:snow_7 221 229 234 +mcl_core:snow_8 221 229 234 +mcl_core:snowblock 221 229 234 +mcl_core:spruceleaves 38 75 47 +mcl_core:sprucesapling 59 76 56 +mcl_core:sprucetree 104 75 59 +mcl_core:sprucetree_bark 69 53 45 +mcl_core:sprucewood 82 66 54 +mcl_core:stone 131 123 118 +mcl_core:stone_smooth 128 119 115 +mcl_core:stone_with_coal 114 106 103 +mcl_core:stone_with_diamond 124 128 133 +mcl_core:stone_with_emerald 120 124 108 +mcl_core:stone_with_gold 136 121 107 +mcl_core:stone_with_iron 137 125 119 +mcl_core:stone_with_lapis 116 115 128 +mcl_core:stone_with_redstone 131 101 98 +mcl_core:stone_with_redstone_lit 131 101 98 +mcl_core:stonebrick 122 122 122 +mcl_core:stonebrickcarved 100 92 88 +mcl_core:stonebrickcracked 96 89 85 +mcl_core:stonebrickmossy 86 104 79 +mcl_core:stripped_acacia 157 99 63 +mcl_core:stripped_acacia_bark 151 90 57 +mcl_core:stripped_birch 170 136 108 +mcl_core:stripped_birch_bark 179 144 115 +mcl_core:stripped_dark_oak 92 79 70 +mcl_core:stripped_dark_oak_bark 91 79 70 +mcl_core:stripped_jungle 170 114 84 +mcl_core:stripped_jungle_bark 176 117 86 +mcl_core:stripped_oak 155 117 81 +mcl_core:stripped_oak_bark 162 122 84 +mcl_core:stripped_spruce 109 80 65 +mcl_core:stripped_spruce_bark 109 82 67 +mcl_core:tree 142 108 77 +mcl_core:tree_bark 99 78 59 +mcl_core:vine 21 62 22 +mcl_core:water_source 0 94 184 224 +mcl_core:wood 115 89 68 + +# mcl_crafting_table +mcl_crafting_table:crafting_table 154 123 95 + +# mcl_crimson +mcl_crimson:crimson_door_t_1 119 46 40 +mcl_crimson:crimson_door_t_2 119 46 40 +mcl_crimson:crimson_fence 107 40 48 +mcl_crimson:crimson_fence_gate 107 40 48 +mcl_crimson:crimson_fence_gate_open 107 40 48 +mcl_crimson:crimson_fungus 153 60 41 +mcl_crimson:crimson_hyphae 176 81 69 +mcl_crimson:crimson_hyphae_bark 100 74 62 +mcl_crimson:crimson_hyphae_wood 119 46 40 +mcl_crimson:crimson_nylium 133 31 35 +mcl_crimson:crimson_roots 129 39 39 +mcl_crimson:crimson_trapdoor 91 40 47 +mcl_crimson:crimson_trapdoor_open 119 46 40 +mcl_crimson:nether_sprouts 115 90 156 +mcl_crimson:shroomlight 253 187 125 +mcl_crimson:stripped_crimson_hyphae 177 74 67 +mcl_crimson:stripped_crimson_hyphae_bark 117 40 48 +mcl_crimson:stripped_warped_hyphae 20 94 82 +mcl_crimson:stripped_warped_hyphae_bark 117 40 48 +mcl_crimson:twisting_vines 101 82 133 +mcl_crimson:warped_fungus 128 139 114 +mcl_crimson:warped_hyphae 90 71 121 +mcl_crimson:warped_hyphae_bark 51 44 61 +mcl_crimson:warped_hyphae_wood 78 64 108 +mcl_crimson:warped_nylium 86 72 116 +mcl_crimson:warped_roots 97 79 128 +mcl_crimson:warped_trapdoor 37 60 54 +mcl_crimson:warped_trapdoor_open 78 64 108 +mcl_crimson:warped_wart_block 70 56 97 +mcl_crimson:weeping_vines 145 47 38 + +# mcl_deepslate +mcl_deepslate:deepslate 75 73 73 +mcl_deepslate:deepslate_bricks 64 62 62 +mcl_deepslate:deepslate_bricks_cracked 62 60 60 +mcl_deepslate:deepslate_chiseled 46 45 45 +mcl_deepslate:deepslate_cobbled 80 78 76 +mcl_deepslate:deepslate_polished 69 68 67 +mcl_deepslate:deepslate_tiles 51 50 49 +mcl_deepslate:deepslate_tiles_cracked 49 48 48 +mcl_deepslate:deepslate_with_coal 65 62 61 +mcl_deepslate:deepslate_with_copper 88 72 68 +mcl_deepslate:deepslate_with_diamond 76 105 118 +mcl_deepslate:deepslate_with_emerald 66 88 73 +mcl_deepslate:deepslate_with_gold 98 84 66 +mcl_deepslate:deepslate_with_iron 98 91 86 +mcl_deepslate:deepslate_with_lapis 67 77 100 +mcl_deepslate:deepslate_with_redstone 97 63 62 +mcl_deepslate:deepslate_with_redstone_lit 97 63 62 +mcl_deepslate:deepslatebrickswall 64 62 62 +mcl_deepslate:deepslatebrickswall_0 64 62 62 +mcl_deepslate:deepslatebrickswall_1 64 62 62 +mcl_deepslate:deepslatebrickswall_10 64 62 62 +mcl_deepslate:deepslatebrickswall_11 64 62 62 +mcl_deepslate:deepslatebrickswall_12 64 62 62 +mcl_deepslate:deepslatebrickswall_13 64 62 62 +mcl_deepslate:deepslatebrickswall_14 64 62 62 +mcl_deepslate:deepslatebrickswall_15 64 62 62 +mcl_deepslate:deepslatebrickswall_16 64 62 62 +mcl_deepslate:deepslatebrickswall_2 64 62 62 +mcl_deepslate:deepslatebrickswall_21 64 62 62 +mcl_deepslate:deepslatebrickswall_3 64 62 62 +mcl_deepslate:deepslatebrickswall_4 64 62 62 +mcl_deepslate:deepslatebrickswall_5 64 62 62 +mcl_deepslate:deepslatebrickswall_6 64 62 62 +mcl_deepslate:deepslatebrickswall_7 64 62 62 +mcl_deepslate:deepslatebrickswall_8 64 62 62 +mcl_deepslate:deepslatebrickswall_9 64 62 62 +mcl_deepslate:deepslatecobbledwall 80 78 76 +mcl_deepslate:deepslatecobbledwall_0 80 78 76 +mcl_deepslate:deepslatecobbledwall_1 80 78 76 +mcl_deepslate:deepslatecobbledwall_10 80 78 76 +mcl_deepslate:deepslatecobbledwall_11 80 78 76 +mcl_deepslate:deepslatecobbledwall_12 80 78 76 +mcl_deepslate:deepslatecobbledwall_13 80 78 76 +mcl_deepslate:deepslatecobbledwall_14 80 78 76 +mcl_deepslate:deepslatecobbledwall_15 80 78 76 +mcl_deepslate:deepslatecobbledwall_16 80 78 76 +mcl_deepslate:deepslatecobbledwall_2 80 78 76 +mcl_deepslate:deepslatecobbledwall_21 80 78 76 +mcl_deepslate:deepslatecobbledwall_3 80 78 76 +mcl_deepslate:deepslatecobbledwall_4 80 78 76 +mcl_deepslate:deepslatecobbledwall_5 80 78 76 +mcl_deepslate:deepslatecobbledwall_6 80 78 76 +mcl_deepslate:deepslatecobbledwall_7 80 78 76 +mcl_deepslate:deepslatecobbledwall_8 80 78 76 +mcl_deepslate:deepslatecobbledwall_9 80 78 76 +mcl_deepslate:deepslatepolishedwall 69 68 67 +mcl_deepslate:deepslatepolishedwall_0 69 68 67 +mcl_deepslate:deepslatepolishedwall_1 69 68 67 +mcl_deepslate:deepslatepolishedwall_10 69 68 67 +mcl_deepslate:deepslatepolishedwall_11 69 68 67 +mcl_deepslate:deepslatepolishedwall_12 69 68 67 +mcl_deepslate:deepslatepolishedwall_13 69 68 67 +mcl_deepslate:deepslatepolishedwall_14 69 68 67 +mcl_deepslate:deepslatepolishedwall_15 69 68 67 +mcl_deepslate:deepslatepolishedwall_16 69 68 67 +mcl_deepslate:deepslatepolishedwall_2 69 68 67 +mcl_deepslate:deepslatepolishedwall_21 69 68 67 +mcl_deepslate:deepslatepolishedwall_3 69 68 67 +mcl_deepslate:deepslatepolishedwall_4 69 68 67 +mcl_deepslate:deepslatepolishedwall_5 69 68 67 +mcl_deepslate:deepslatepolishedwall_6 69 68 67 +mcl_deepslate:deepslatepolishedwall_7 69 68 67 +mcl_deepslate:deepslatepolishedwall_8 69 68 67 +mcl_deepslate:deepslatepolishedwall_9 69 68 67 +mcl_deepslate:deepslatetileswall 51 50 49 +mcl_deepslate:deepslatetileswall_0 51 50 49 +mcl_deepslate:deepslatetileswall_1 51 50 49 +mcl_deepslate:deepslatetileswall_10 51 50 49 +mcl_deepslate:deepslatetileswall_11 51 50 49 +mcl_deepslate:deepslatetileswall_12 51 50 49 +mcl_deepslate:deepslatetileswall_13 51 50 49 +mcl_deepslate:deepslatetileswall_14 51 50 49 +mcl_deepslate:deepslatetileswall_15 51 50 49 +mcl_deepslate:deepslatetileswall_16 51 50 49 +mcl_deepslate:deepslatetileswall_2 51 50 49 +mcl_deepslate:deepslatetileswall_21 51 50 49 +mcl_deepslate:deepslatetileswall_3 51 50 49 +mcl_deepslate:deepslatetileswall_4 51 50 49 +mcl_deepslate:deepslatetileswall_5 51 50 49 +mcl_deepslate:deepslatetileswall_6 51 50 49 +mcl_deepslate:deepslatetileswall_7 51 50 49 +mcl_deepslate:deepslatetileswall_8 51 50 49 +mcl_deepslate:deepslatetileswall_9 51 50 49 +mcl_deepslate:infested_deepslate 75 73 73 +mcl_deepslate:tuff 99 82 70 + +# mcl_dispensers +mcl_dispensers:dispenser 149 139 133 +mcl_dispensers:dispenser_down 149 139 133 +mcl_dispensers:dispenser_up 123 113 108 + +# mcl_doors +mcl_doors:acacia_door_t_1 134 81 53 +mcl_doors:acacia_door_t_2 134 81 53 +mcl_doors:acacia_trapdoor 150 100 69 +mcl_doors:acacia_trapdoor_open 156 105 73 +mcl_doors:birch_door_t_1 154 121 94 +mcl_doors:birch_door_t_2 154 121 94 +mcl_doors:birch_trapdoor 180 163 146 +mcl_doors:birch_trapdoor_open 147 116 90 +mcl_doors:dark_oak_door_t_1 103 90 76 +mcl_doors:dark_oak_door_t_2 103 90 76 +mcl_doors:dark_oak_trapdoor 82 70 58 +mcl_doors:dark_oak_trapdoor_open 86 73 61 +mcl_doors:iron_door_t_1 157 151 150 +mcl_doors:iron_door_t_2 157 151 150 +mcl_doors:iron_trapdoor 151 143 143 +mcl_doors:iron_trapdoor_open 151 142 142 +mcl_doors:jungle_door_t_1 110 76 57 +mcl_doors:jungle_door_t_2 110 76 57 +mcl_doors:jungle_trapdoor 106 73 53 +mcl_doors:jungle_trapdoor_open 122 88 63 +mcl_doors:spruce_door_t_1 93 80 69 +mcl_doors:spruce_door_t_2 93 80 69 +mcl_doors:spruce_trapdoor 73 59 48 +mcl_doors:spruce_trapdoor_open 76 60 49 +mcl_doors:trapdoor 100 76 60 +mcl_doors:trapdoor_open 114 86 67 +mcl_doors:wooden_door_t_1 85 65 52 +mcl_doors:wooden_door_t_2 85 65 52 + +# mcl_droppers +mcl_droppers:dropper 149 139 133 +mcl_droppers:dropper_down 149 139 133 +mcl_droppers:dropper_up 126 115 111 + +# mcl_enchanting +mcl_enchanting:table 97 97 96 + +# mcl_end +mcl_end:chorus_flower 96 100 127 +mcl_end:chorus_flower_dead 83 82 119 +mcl_end:chorus_plant 79 74 115 +mcl_end:dragon_egg 56 36 34 +mcl_end:end_bricks 195 189 123 +mcl_end:end_rod 124 77 97 +mcl_end:end_stone 221 214 131 +mcl_end:purpur_block 161 112 175 +mcl_end:purpur_pillar 160 111 173 + +# mcl_farming +mcl_farming:beetroot 84 109 72 +mcl_farming:beetroot_0 56 122 76 +mcl_farming:beetroot_1 55 119 73 +mcl_farming:beetroot_2 56 120 74 +mcl_farming:carrot 105 106 59 +mcl_farming:carrot_1 76 113 62 +mcl_farming:carrot_2 76 113 62 +mcl_farming:carrot_3 74 109 59 +mcl_farming:carrot_4 74 109 59 +mcl_farming:carrot_5 72 108 58 +mcl_farming:carrot_6 72 108 58 +mcl_farming:carrot_7 72 108 58 +mcl_farming:hay_block 156 119 83 +mcl_farming:melon 59 82 34 +mcl_farming:melontige_unconnect 100 100 100 +mcl_farming:potato 86 111 59 +mcl_farming:potato_1 75 120 65 +mcl_farming:potato_2 75 120 65 +mcl_farming:potato_3 71 115 62 +mcl_farming:potato_4 71 115 62 +mcl_farming:potato_5 74 119 64 +mcl_farming:potato_6 74 119 64 +mcl_farming:potato_7 74 119 64 +mcl_farming:pumpkin 174 90 40 +mcl_farming:pumpkin_face 174 90 40 +mcl_farming:pumpkin_face_light 174 90 40 +mcl_farming:pumpkintige_unconnect 100 100 100 +mcl_farming:soil 103 81 69 +mcl_farming:soil_wet 70 56 47 +mcl_farming:sweet_berry_bush_0 0 111 29 +mcl_farming:sweet_berry_bush_1 0 101 25 +mcl_farming:sweet_berry_bush_2 76 95 24 +mcl_farming:sweet_berry_bush_3 107 87 39 +mcl_farming:wheat 167 120 78 +mcl_farming:wheat_1 55 103 48 +mcl_farming:wheat_2 51 99 46 +mcl_farming:wheat_3 51 98 46 +mcl_farming:wheat_4 67 115 53 +mcl_farming:wheat_5 87 130 66 +mcl_farming:wheat_6 104 144 68 +mcl_farming:wheat_7 148 147 71 + +# mcl_fences +mcl_fences:acacia_fence 153 101 70 +mcl_fences:acacia_fence_gate 153 101 70 +mcl_fences:acacia_fence_gate_open 153 101 70 +mcl_fences:birch_fence 152 120 93 +mcl_fences:birch_fence_gate 152 120 93 +mcl_fences:birch_fence_gate_open 152 120 93 +mcl_fences:dark_oak_fence 85 73 60 +mcl_fences:dark_oak_fence_gate 85 73 60 +mcl_fences:dark_oak_fence_gate_open 85 73 60 +mcl_fences:fence 110 84 65 +mcl_fences:fence_gate 110 84 65 +mcl_fences:fence_gate_open 110 84 65 +mcl_fences:jungle_fence 116 82 61 +mcl_fences:jungle_fence_gate 116 82 61 +mcl_fences:jungle_fence_gate_open 116 82 61 +mcl_fences:nether_brick_fence 50 25 26 +mcl_fences:spruce_fence 85 68 55 +mcl_fences:spruce_fence_gate 85 68 55 +mcl_fences:spruce_fence_gate_open 85 68 55 + +# mcl_fire +mcl_fire:eternal_fire 209 112 39 +mcl_fire:fire 209 112 39 + +# mcl_fletching_table +mcl_fletching_table:fletching_table 174 116 83 + +# mcl_flowerpots +mcl_flowerpots:flower_pot 121 57 48 +mcl_flowerpots:flower_pot_cactus 114 92 57 + +# mcl_flowers +mcl_flowers:allium 130 121 159 +mcl_flowers:azure_bluet 118 124 125 +mcl_flowers:blue_orchid 0 118 191 +mcl_flowers:dandelion 136 120 59 +mcl_flowers:double_fern 142 132 114 +mcl_flowers:double_fern_top 150 139 120 +mcl_flowers:double_grass 0 255 0 +mcl_flowers:double_grass_top 0 255 0 +mcl_flowers:fern 144 134 116 +mcl_flowers:lilac 198 161 207 +mcl_flowers:lilac_top 198 161 207 +mcl_flowers:oxeye_daisy 162 158 139 +mcl_flowers:peony 242 172 185 +mcl_flowers:peony_top 242 172 185 +mcl_flowers:poppy 161 0 14 +mcl_flowers:rose_bush 161 0 14 +mcl_flowers:rose_bush_top 161 0 14 +mcl_flowers:sunflower 247 247 73 +mcl_flowers:sunflower_top 247 247 73 +mcl_flowers:tulip_orange 132 87 55 +mcl_flowers:tulip_pink 242 172 185 +mcl_flowers:tulip_red 161 0 14 +mcl_flowers:tulip_white 255 255 255 +mcl_flowers:waterlily 29 83 29 +mcl_flowers:tallgrass 21 71 52 + +# mcl_furnaces +mcl_furnaces:furnace 149 139 133 +mcl_furnaces:furnace_active 149 139 133 + +# mcl_grindstone +mcl_grindstone:grindstone 216 216 216 + +# mcl_heads +mcl_heads:creeper22_5 94 115 69 +mcl_heads:creeper45 94 115 69 +mcl_heads:creeper67_5 94 115 69 +mcl_heads:skeleton22_5 126 126 126 +mcl_heads:skeleton45 126 126 126 +mcl_heads:skeleton67_5 126 126 126 +mcl_heads:steve22_5 123 87 69 +mcl_heads:steve45 123 87 69 +mcl_heads:steve67_5 123 87 69 +mcl_heads:wither_skeleton22_5 50 50 50 +mcl_heads:wither_skeleton45 50 50 50 +mcl_heads:wither_skeleton67_5 50 50 50 +mcl_heads:zombie22_5 67 105 70 +mcl_heads:zombie45 67 105 70 +mcl_heads:zombie67_5 67 105 70 + +# mcl_hoppers +mcl_hoppers:hopper 50 50 50 +mcl_hoppers:hopper_disabled 50 50 50 +mcl_hoppers:hopper_side 50 50 50 +mcl_hoppers:hopper_side_disabled 50 50 50 + +# mcl_itemframes +mcl_itemframes:glow_item_frame 182 132 79 +mcl_itemframes:item_frame 127 94 66 + +# mcl_jukebox +mcl_jukebox:jukebox 77 60 46 + +# mcl_lanterns +mcl_lanterns:chain 41 41 41 +mcl_lanterns:lantern_ceiling 102 73 51 +mcl_lanterns:lantern_floor 102 73 51 +mcl_lanterns:soul_lantern_ceiling 62 91 92 +mcl_lanterns:soul_lantern_floor 62 91 92 + +# mcl_lightning_rods + +# mcl_loom +mcl_loom:loom 130 121 119 + +# mcl_mangrove +mcl_mangrove:hanging_propagule_1 80 100 48 +mcl_mangrove:mangrove_door_t_1 125 61 55 +mcl_mangrove:mangrove_door_t_2 125 61 55 +mcl_mangrove:mangrove_mud_roots 66 61 58 +mcl_mangrove:mangrove_roots 97 75 49 +mcl_mangrove:mangrove_stripped_bark 141 68 57 +mcl_mangrove:mangrove_stripped_trunk 127 62 56 +mcl_mangrove:mangrove_trapdoor 123 60 55 +mcl_mangrove:mangrove_trapdoor_open 125 61 55 +mcl_mangrove:mangrove_tree 125 66 54 +mcl_mangrove:mangrove_tree_bark 88 68 46 +mcl_mangrove:mangrove_wood 125 61 55 +mcl_mangrove:mangrove_wood_fence 125 61 55 +mcl_mangrove:mangrove_wood_fence_gate 125 61 55 +mcl_mangrove:mangrove_wood_fence_gate_open 125 61 55 +mcl_mangrove:mangroveleaves 34 50 14 +mcl_mangrove:propagule 71 114 46 +mcl_mangrove:propagule_clay 124 124 124 +mcl_mangrove:propagule_coarse_dirt 119 94 78 +mcl_mangrove:propagule_dirt 109 84 70 +mcl_mangrove:propagule_mud 66 61 58 +mcl_mangrove:river_water_logged_roots 32 121 138 +mcl_mangrove:water_logged_roots 38 98 129 + +# mcl_maps +mcl_maps:filled_map_character_male 123 77 64 +mcl_maps:filled_map_mcl_skins_base_18D471DFF_female 0 0 0 +mcl_maps:filled_map_mcl_skins_base_18D471DFF_male 0 0 0 +mcl_maps:filled_map_mcl_skins_base_1B47A57FF_female 0 0 0 +mcl_maps:filled_map_mcl_skins_base_1B47A57FF_male 0 0 0 +mcl_maps:filled_map_mcl_skins_base_1EEB592FF_female 0 0 0 +mcl_maps:filled_map_mcl_skins_base_1EEB592FF_male 0 0 0 +mcl_maps:filled_map_mcl_skins_character_1_female 106 100 86 + +# mcl_meshhand +mcl_meshhand:character_male 123 77 64 +mcl_meshhand:mcl_skins_base_18D471DFF_female 0 0 0 +mcl_meshhand:mcl_skins_base_18D471DFF_male 0 0 0 +mcl_meshhand:mcl_skins_base_1B47A57FF_female 0 0 0 +mcl_meshhand:mcl_skins_base_1B47A57FF_male 0 0 0 +mcl_meshhand:mcl_skins_base_1EEB592FF_female 0 0 0 +mcl_meshhand:mcl_skins_base_1EEB592FF_male 0 0 0 +mcl_meshhand:mcl_skins_character_1_female 106 100 86 + +# mcl_minecarts +mcl_minecarts:activator_rail 87 70 59 +mcl_minecarts:activator_rail_on 95 69 59 +mcl_minecarts:detector_rail 94 81 73 +mcl_minecarts:detector_rail_on 96 81 73 +mcl_minecarts:golden_rail 107 88 63 +mcl_minecarts:golden_rail_on 110 88 63 +mcl_minecarts:rail 92 75 63 + +# mcl_mobspawners +mcl_mobspawners:spawner 42 42 42 + +# mcl_monster_eggs +mcl_monster_eggs:monster_egg_cobble 114 108 105 +mcl_monster_eggs:monster_egg_stone 131 123 118 +mcl_monster_eggs:monster_egg_stonebrick 99 91 88 +mcl_monster_eggs:monster_egg_stonebrickcarved 100 92 88 +mcl_monster_eggs:monster_egg_stonebrickcracked 96 89 85 +mcl_monster_eggs:monster_egg_stonebrickmossy 86 104 79 + +# mcl_mud +mcl_mud:mud 66 61 58 +mcl_mud:mud_bricks 109 96 87 +mcl_mud:packed_mud 102 90 83 + +# mcl_mushrooms +mcl_mushrooms:brown_mushroom_block_cap_000000 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000001 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000010 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000011 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000100 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000101 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000110 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000111 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001000 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001001 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001010 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001011 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001100 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001101 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001110 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001111 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010000 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010001 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010010 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010011 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010100 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010101 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010110 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010111 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011000 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011001 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011010 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011011 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011100 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011101 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011110 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011111 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_100000 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100001 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100010 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100011 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100100 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100101 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100110 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100111 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101000 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101001 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101010 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101011 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101100 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101101 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101110 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101111 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110000 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110001 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110010 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110011 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110100 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110101 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110110 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110111 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111000 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111001 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111010 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111011 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111100 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111101 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111110 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111111 132 87 69 +mcl_mushrooms:brown_mushroom_block_stem 218 176 137 +mcl_mushrooms:brown_mushroom_block_stem_full 205 184 151 +mcl_mushrooms:mushroom_brown 123 84 61 +mcl_mushrooms:mushroom_red 173 71 66 +mcl_mushrooms:red_mushroom_block_cap_000000 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000001 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000010 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000011 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000100 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000101 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000110 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000111 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001000 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001001 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001010 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001011 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001100 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001101 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001110 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001111 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010000 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010001 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010010 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010011 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010100 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010101 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010110 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010111 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011000 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011001 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011010 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011011 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011100 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011101 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011110 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011111 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_100000 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100001 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100010 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100011 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100100 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100101 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100110 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100111 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101000 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101001 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101010 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101011 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101100 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101101 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101110 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101111 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110000 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110001 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110010 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110011 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110100 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110101 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110110 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110111 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111000 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111001 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111010 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111011 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111100 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111101 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111110 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111111 138 40 26 +mcl_mushrooms:red_mushroom_block_stem 218 176 137 +mcl_mushrooms:red_mushroom_block_stem_full 205 184 151 + +# mcl_nether +mcl_nether:ancient_debris 63 57 50 +mcl_nether:glowstone 206 160 102 +mcl_nether:magma 99 35 28 +mcl_nether:nether_brick 49 25 26 +mcl_nether:nether_lava_flowing 180 50 19 +mcl_nether:nether_lava_source 183 54 21 +mcl_nether:nether_wart 129 61 57 +mcl_nether:nether_wart_0 59 42 39 +mcl_nether:nether_wart_1 103 59 56 +mcl_nether:nether_wart_2 103 59 56 +mcl_nether:nether_wart_block 179 79 74 +mcl_nether:netheriteblock 36 34 33 +mcl_nether:netherrack 133 52 40 +mcl_nether:quartz_block 198 191 187 +mcl_nether:quartz_chiseled 198 190 187 +mcl_nether:quartz_ore 137 75 67 +mcl_nether:quartz_pillar 196 188 186 +mcl_nether:quartz_smooth 198 191 187 +mcl_nether:red_nether_brick 72 17 6 +mcl_nether:soul_sand 92 71 52 + +# mcl_observers +mcl_observers:observer_down_off 89 82 79 +mcl_observers:observer_down_on 92 82 79 +mcl_observers:observer_off 142 131 126 +mcl_observers:observer_on 142 131 126 +mcl_observers:observer_up_off 111 91 91 +mcl_observers:observer_up_on 111 91 91 + +# mcl_ocean +mcl_ocean:brain_coral 202 85 149 +mcl_ocean:brain_coral_block 202 85 149 +mcl_ocean:brain_coral_fan 202 85 149 +mcl_ocean:bubble_coral 145 76 196 +mcl_ocean:bubble_coral_block 145 76 196 +mcl_ocean:bubble_coral_fan 145 76 196 +mcl_ocean:dead_brain_coral 131 114 124 +mcl_ocean:dead_brain_coral_block 131 114 124 +mcl_ocean:dead_brain_coral_fan 131 114 124 +mcl_ocean:dead_bubble_coral 115 106 123 +mcl_ocean:dead_bubble_coral_block 115 106 123 +mcl_ocean:dead_bubble_coral_fan 115 106 123 +mcl_ocean:dead_fire_coral 129 103 101 +mcl_ocean:dead_fire_coral_block 129 103 101 +mcl_ocean:dead_fire_coral_fan 129 103 101 +mcl_ocean:dead_horn_coral 154 147 127 +mcl_ocean:dead_horn_coral_block 154 147 127 +mcl_ocean:dead_horn_coral_fan 154 147 127 +mcl_ocean:dead_tube_coral 100 106 129 +mcl_ocean:dead_tube_coral_block 100 106 129 +mcl_ocean:dead_tube_coral_fan 100 106 129 +mcl_ocean:dried_kelp_block 56 71 57 +mcl_ocean:fire_coral 201 75 62 +mcl_ocean:fire_coral_block 201 75 62 +mcl_ocean:fire_coral_fan 201 75 62 +mcl_ocean:horn_coral 232 195 70 +mcl_ocean:horn_coral_block 232 195 70 +mcl_ocean:horn_coral_fan 232 195 70 +mcl_ocean:kelp_dirt 109 84 70 +mcl_ocean:kelp_gravel 115 109 103 +mcl_ocean:kelp_redsand 225 137 111 +mcl_ocean:kelp_sand 221 171 127 +mcl_ocean:prismarine 106 127 123 +mcl_ocean:prismarine_brick 107 116 117 +mcl_ocean:prismarine_dark 77 90 97 +mcl_ocean:sea_lantern 141 152 152 +mcl_ocean:sea_pickle_1_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_1_off_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_2_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_2_off_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_3_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_3_off_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_4_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_4_off_dead_brain_coral_block 131 114 124 +mcl_ocean:seagrass_dirt 109 84 70 +mcl_ocean:seagrass_gravel 115 109 103 +mcl_ocean:seagrass_redsand 225 137 111 +mcl_ocean:seagrass_sand 221 171 127 +mcl_ocean:tube_coral 58 91 211 +mcl_ocean:tube_coral_block 58 91 211 +mcl_ocean:tube_coral_fan 58 91 211 + +# mcl_portals +mcl_portals:end_portal_frame 101 92 80 +mcl_portals:end_portal_frame_eye 101 92 80 +mcl_portals:portal_end 15 15 15 +mcl_portals:portal_gateway 15 15 15 + +# mcl_potions +mcl_potions:fire_resistance_arrow_box 148 132 127 +mcl_potions:fire_resistance_plus_arrow_box 148 132 127 +mcl_potions:harming_2_arrow_box 148 132 127 +mcl_potions:harming_arrow_box 148 132 127 +mcl_potions:healing_2_arrow_box 148 132 127 +mcl_potions:healing_arrow_box 148 132 127 +mcl_potions:invisibility_arrow_box 148 132 127 +mcl_potions:invisibility_plus_arrow_box 148 132 127 +mcl_potions:leaping_2_arrow_box 148 132 127 +mcl_potions:leaping_arrow_box 148 132 127 +mcl_potions:leaping_plus_arrow_box 148 132 127 +mcl_potions:night_vision_arrow_box 148 132 127 +mcl_potions:night_vision_plus_arrow_box 148 132 127 +mcl_potions:poison_2_arrow_box 148 132 127 +mcl_potions:poison_arrow_box 148 132 127 +mcl_potions:poison_plus_arrow_box 148 132 127 +mcl_potions:regeneration_2_arrow_box 148 132 127 +mcl_potions:regeneration_arrow_box 148 132 127 +mcl_potions:regeneration_plus_arrow_box 148 132 127 +mcl_potions:slowness_2_arrow_box 148 132 127 +mcl_potions:slowness_arrow_box 148 132 127 +mcl_potions:slowness_plus_arrow_box 148 132 127 +mcl_potions:swiftness_2_arrow_box 148 132 127 +mcl_potions:swiftness_arrow_box 148 132 127 +mcl_potions:swiftness_plus_arrow_box 148 132 127 +mcl_potions:water_breathing_arrow_box 148 132 127 +mcl_potions:water_breathing_plus_arrow_box 148 132 127 + +# mcl_raw_ores +mcl_raw_ores:raw_gold_block 210 169 85 +mcl_raw_ores:raw_iron_block 195 175 159 + +# mcl_sculk +mcl_sculk:catalyst 5 19 24 +mcl_sculk:sculk 5 19 24 +mcl_sculk:vein 6 17 24 + +# mcl_signs +mcl_signs:standing_sign 119 93 72 +mcl_signs:standing_sign22_5 119 93 72 +mcl_signs:standing_sign22_5_acaciawood 234 116 121 +mcl_signs:standing_sign22_5_birchwood 255 219 167 +mcl_signs:standing_sign22_5_crimson_hyphae_wood 195 95 81 +mcl_signs:standing_sign22_5_darkwood 133 100 67 +mcl_signs:standing_sign22_5_junglewood 134 98 73 +mcl_signs:standing_sign22_5_mangrove_wood 184 105 61 +mcl_signs:standing_sign22_5_sprucewood 85 62 36 +mcl_signs:standing_sign22_5_warped_hyphae_wood 159 125 207 +mcl_signs:standing_sign45 119 93 72 +mcl_signs:standing_sign45_acaciawood 234 116 121 +mcl_signs:standing_sign45_birchwood 255 219 167 +mcl_signs:standing_sign45_crimson_hyphae_wood 195 95 81 +mcl_signs:standing_sign45_darkwood 133 100 67 +mcl_signs:standing_sign45_junglewood 134 98 73 +mcl_signs:standing_sign45_mangrove_wood 134 105 61 +mcl_signs:standing_sign45_sprucewood 85 62 36 +mcl_signs:standing_sign45_warped_hyphae_wood 159 125 207 +mcl_signs:standing_sign67_5 119 93 72 +mcl_signs:standing_sign67_5_acaciawood 234 116 121 +mcl_signs:standing_sign67_5_birchwood 255 219 167 +mcl_signs:standing_sign67_5_crimson_hyphae_wood 195 95 81 +mcl_signs:standing_sign67_5_darkwood 133 100 67 +mcl_signs:standing_sign67_5_junglewood 134 98 73 +mcl_signs:standing_sign67_5_mangrove_wood 184 105 61 +mcl_signs:standing_sign67_5_sprucewood 85 62 36 +mcl_signs:standing_sign67_5_warped_hyphae_wood 159 125 207 +mcl_signs:standing_sign_acaciawood 234 116 121 +mcl_signs:standing_sign_birchwood 255 219 167 +mcl_signs:standing_sign_crimson_hyphae_wood 195 95 81 +mcl_signs:standing_sign_darkwood 133 100 67 +mcl_signs:standing_sign_junglewood 134 98 73 +mcl_signs:standing_sign_mangrove_wood 119 93 72 +mcl_signs:standing_sign_sprucewood 85 62 36 +mcl_signs:standing_sign_warped_hyphae_wood 159 125 207 +mcl_signs:wall_sign 119 93 72 +mcl_signs:wall_sign_acaciawood 234 116 121 +mcl_signs:wall_sign_birchwood 255 219 255 +mcl_signs:wall_sign_crimson_hyphae_wood 195 95 81 +mcl_signs:wall_sign_darkwood 133 100 67 +mcl_signs:wall_sign_junglewood 134 98 73 +mcl_signs:wall_sign_mangrove_wood 184 105 61 +mcl_signs:wall_sign_sprucewood 85 62 36 +mcl_signs:wall_sign_warped_hyphae_wood 159 125 207 + +# mcl_smithing_table +mcl_smithing_table:table 51 48 45 + +# mcl_smoker +mcl_smoker:smoker 121 110 106 +mcl_smoker:smoker_active 121 110 106 + +# mcl_sponges +mcl_sponges:sponge 211 179 120 +mcl_sponges:sponge_wet 157 136 94 +mcl_sponges:sponge_wet_river_water 158 142 105 + +# mcl_stairs +mcl_stairs:slab_acaciatree_bark 107 94 77 +mcl_stairs:slab_acaciatree_bark_double 107 94 77 +mcl_stairs:slab_acaciatree_bark_top 107 94 77 +mcl_stairs:slab_acaciawood 153 103 71 +mcl_stairs:slab_acaciawood_double 153 103 71 +mcl_stairs:slab_acaciawood_top 153 103 71 +mcl_stairs:slab_andesite 105 111 107 +mcl_stairs:slab_andesite_double 105 111 107 +mcl_stairs:slab_andesite_smooth 107 114 110 +mcl_stairs:slab_andesite_smooth_double 107 114 110 +mcl_stairs:slab_andesite_smooth_top 107 114 110 +mcl_stairs:slab_andesite_top 105 111 107 +mcl_stairs:slab_birchtree_bark 199 190 180 +mcl_stairs:slab_birchtree_bark_double 199 190 180 +mcl_stairs:slab_birchtree_bark_top 199 190 180 +mcl_stairs:slab_birchwood 147 116 90 +mcl_stairs:slab_birchwood_double 147 116 90 +mcl_stairs:slab_birchwood_top 147 116 90 +mcl_stairs:slab_blackstone 33 31 35 +mcl_stairs:slab_blackstone_brick_polished 42 39 44 +mcl_stairs:slab_blackstone_brick_polished_double 42 39 44 +mcl_stairs:slab_blackstone_brick_polished_top 42 39 44 +mcl_stairs:slab_blackstone_chiseled_polished 42 39 44 +mcl_stairs:slab_blackstone_chiseled_polished_double 42 39 44 +mcl_stairs:slab_blackstone_chiseled_polished_top 42 39 44 +mcl_stairs:slab_blackstone_double 33 31 35 +mcl_stairs:slab_blackstone_polished 44 42 47 +mcl_stairs:slab_blackstone_polished_double 44 42 47 +mcl_stairs:slab_blackstone_polished_top 44 42 47 +mcl_stairs:slab_blackstone_top 33 31 35 +mcl_stairs:slab_brick_block 140 92 81 +mcl_stairs:slab_brick_block_double 140 92 81 +mcl_stairs:slab_brick_block_top 140 92 81 +mcl_stairs:slab_cobble 114 108 105 +mcl_stairs:slab_cobble_double 114 108 105 +mcl_stairs:slab_cobble_top 114 108 105 +mcl_stairs:slab_concrete_black 8 10 15 +mcl_stairs:slab_concrete_black_double 8 10 15 +mcl_stairs:slab_concrete_black_top 8 10 15 +mcl_stairs:slab_concrete_blue 46 48 147 +mcl_stairs:slab_concrete_blue_double 46 48 147 +mcl_stairs:slab_concrete_blue_top 46 48 147 +mcl_stairs:slab_concrete_brown 98 60 32 +mcl_stairs:slab_concrete_brown_double 98 60 32 +mcl_stairs:slab_concrete_brown_top 98 60 32 +mcl_stairs:slab_concrete_cyan 21 123 140 +mcl_stairs:slab_concrete_cyan_double 21 123 140 +mcl_stairs:slab_concrete_cyan_top 21 123 140 +mcl_stairs:slab_concrete_green 75 94 37 +mcl_stairs:slab_concrete_green_double 75 94 37 +mcl_stairs:slab_concrete_green_top 75 94 37 +mcl_stairs:slab_concrete_grey 56 59 64 +mcl_stairs:slab_concrete_grey_double 56 59 64 +mcl_stairs:slab_concrete_grey_top 56 59 64 +mcl_stairs:slab_concrete_light_blue 37 140 200 +mcl_stairs:slab_concrete_light_blue_double 37 140 200 +mcl_stairs:slab_concrete_light_blue_top 37 140 200 +mcl_stairs:slab_concrete_lime 96 171 25 +mcl_stairs:slab_concrete_lime_double 96 171 25 +mcl_stairs:slab_concrete_lime_top 96 171 25 +mcl_stairs:slab_concrete_magenta 171 49 162 +mcl_stairs:slab_concrete_magenta_double 171 49 162 +mcl_stairs:slab_concrete_magenta_top 171 49 162 +mcl_stairs:slab_concrete_orange 226 101 1 +mcl_stairs:slab_concrete_orange_double 226 101 1 +mcl_stairs:slab_concrete_orange_top 226 101 1 +mcl_stairs:slab_concrete_pink 213 103 144 +mcl_stairs:slab_concrete_pink_double 213 103 144 +mcl_stairs:slab_concrete_pink_top 213 103 144 +mcl_stairs:slab_concrete_purple 103 32 159 +mcl_stairs:slab_concrete_purple_double 103 32 159 +mcl_stairs:slab_concrete_purple_top 103 32 159 +mcl_stairs:slab_concrete_red 146 34 34 +mcl_stairs:slab_concrete_red_double 146 34 34 +mcl_stairs:slab_concrete_red_top 146 34 34 +mcl_stairs:slab_concrete_silver 128 129 118 +mcl_stairs:slab_concrete_silver_double 128 129 118 +mcl_stairs:slab_concrete_silver_top 128 129 118 +mcl_stairs:slab_concrete_white 208 214 215 +mcl_stairs:slab_concrete_white_double 208 214 215 +mcl_stairs:slab_concrete_white_top 208 214 215 +mcl_stairs:slab_concrete_yellow 241 177 21 +mcl_stairs:slab_concrete_yellow_double 241 177 21 +mcl_stairs:slab_concrete_yellow_top 241 177 21 +mcl_stairs:slab_copper_cut 150 78 58 +mcl_stairs:slab_copper_cut_double 150 78 58 +mcl_stairs:slab_copper_cut_top 150 78 58 +mcl_stairs:slab_copper_exposed_cut 132 94 84 +mcl_stairs:slab_copper_exposed_cut_double 132 94 84 +mcl_stairs:slab_copper_exposed_cut_top 132 94 84 +mcl_stairs:slab_copper_oxidized_cut 91 112 112 +mcl_stairs:slab_copper_oxidized_cut_double 91 112 112 +mcl_stairs:slab_copper_oxidized_cut_top 91 112 112 +mcl_stairs:slab_copper_weathered_cut 109 105 102 +mcl_stairs:slab_copper_weathered_cut_double 109 105 102 +mcl_stairs:slab_copper_weathered_cut_top 109 105 102 +mcl_stairs:slab_crimson_hyphae_wood 119 46 40 +mcl_stairs:slab_crimson_hyphae_wood_double 119 46 40 +mcl_stairs:slab_crimson_hyphae_wood_top 119 46 40 +mcl_stairs:slab_darktree_bark 77 65 58 +mcl_stairs:slab_darktree_bark_double 77 65 58 +mcl_stairs:slab_darktree_bark_top 77 65 58 +mcl_stairs:slab_darkwood 89 76 63 +mcl_stairs:slab_darkwood_double 89 76 63 +mcl_stairs:slab_darkwood_top 89 76 63 +mcl_stairs:slab_deepslate_bricks 64 62 62 +mcl_stairs:slab_deepslate_bricks_double 64 62 62 +mcl_stairs:slab_deepslate_bricks_top 64 62 62 +mcl_stairs:slab_deepslate_cobbled 80 78 76 +mcl_stairs:slab_deepslate_cobbled_double 80 78 76 +mcl_stairs:slab_deepslate_cobbled_top 80 78 76 +mcl_stairs:slab_deepslate_polished 69 68 67 +mcl_stairs:slab_deepslate_polished_double 69 68 67 +mcl_stairs:slab_deepslate_polished_top 69 68 67 +mcl_stairs:slab_deepslate_tiles 51 50 49 +mcl_stairs:slab_deepslate_tiles_double 51 50 49 +mcl_stairs:slab_deepslate_tiles_top 51 50 49 +mcl_stairs:slab_diorite 154 150 148 +mcl_stairs:slab_diorite_double 154 150 148 +mcl_stairs:slab_diorite_smooth 158 155 153 +mcl_stairs:slab_diorite_smooth_double 158 155 153 +mcl_stairs:slab_diorite_smooth_top 158 155 153 +mcl_stairs:slab_diorite_top 154 150 148 +mcl_stairs:slab_end_bricks 195 189 123 +mcl_stairs:slab_end_bricks_double 195 189 123 +mcl_stairs:slab_end_bricks_top 195 189 123 +mcl_stairs:slab_goldblock 196 153 69 +mcl_stairs:slab_goldblock_double 196 153 69 +mcl_stairs:slab_goldblock_top 196 153 69 +mcl_stairs:slab_granite 155 122 111 +mcl_stairs:slab_granite_double 155 122 111 +mcl_stairs:slab_granite_smooth 151 122 111 +mcl_stairs:slab_granite_smooth_double 151 122 111 +mcl_stairs:slab_granite_smooth_top 151 122 111 +mcl_stairs:slab_granite_top 155 122 111 +mcl_stairs:slab_ironblock 164 157 157 +mcl_stairs:slab_ironblock_double 164 157 157 +mcl_stairs:slab_ironblock_top 164 157 157 +mcl_stairs:slab_jungletree_bark 90 62 46 +mcl_stairs:slab_jungletree_bark_double 90 62 46 +mcl_stairs:slab_jungletree_bark_top 90 62 46 +mcl_stairs:slab_junglewood 114 80 60 +mcl_stairs:slab_junglewood_double 114 80 60 +mcl_stairs:slab_junglewood_top 114 80 60 +mcl_stairs:slab_lapisblock 58 97 165 +mcl_stairs:slab_lapisblock_double 58 97 165 +mcl_stairs:slab_lapisblock_top 58 97 165 +mcl_stairs:slab_mangrove_wood 125 61 55 +mcl_stairs:slab_mangrove_wood_double 125 61 55 +mcl_stairs:slab_mangrove_wood_top 125 61 55 +mcl_stairs:slab_mossycobble 105 106 97 +mcl_stairs:slab_mossycobble_double 105 106 97 +mcl_stairs:slab_mossycobble_top 105 106 97 +mcl_stairs:slab_mud_brick 109 96 87 +mcl_stairs:slab_mud_brick_double 109 96 87 +mcl_stairs:slab_mud_brick_top 109 96 87 +mcl_stairs:slab_nether_brick 49 25 26 +mcl_stairs:slab_nether_brick_double 49 25 26 +mcl_stairs:slab_nether_brick_top 49 25 26 +mcl_stairs:slab_prismarine 106 127 123 +mcl_stairs:slab_prismarine_brick 107 116 117 +mcl_stairs:slab_prismarine_brick_double 107 116 117 +mcl_stairs:slab_prismarine_brick_top 107 116 117 +mcl_stairs:slab_prismarine_dark 77 90 97 +mcl_stairs:slab_prismarine_dark_double 77 90 97 +mcl_stairs:slab_prismarine_dark_top 77 90 97 +mcl_stairs:slab_prismarine_double 106 127 123 +mcl_stairs:slab_prismarine_top 106 127 123 +mcl_stairs:slab_purpur_block 161 112 175 +mcl_stairs:slab_purpur_block_double 161 112 175 +mcl_stairs:slab_purpur_block_top 161 112 175 +mcl_stairs:slab_quartz_smooth 198 191 187 +mcl_stairs:slab_quartz_smooth_double 198 191 187 +mcl_stairs:slab_quartz_smooth_top 198 191 187 +mcl_stairs:slab_quartzblock 198 191 187 +mcl_stairs:slab_quartzblock_double 198 191 187 +mcl_stairs:slab_quartzblock_top 198 191 187 +mcl_stairs:slab_red_nether_brick 72 17 6 +mcl_stairs:slab_red_nether_brick_double 72 17 6 +mcl_stairs:slab_red_nether_brick_top 72 17 6 +mcl_stairs:slab_redsandstone 212 126 108 +mcl_stairs:slab_redsandstone_double 212 126 108 +mcl_stairs:slab_redsandstone_top 212 126 108 +mcl_stairs:slab_redsandstonesmooth2 212 126 108 +mcl_stairs:slab_redsandstonesmooth2_double 212 126 108 +mcl_stairs:slab_redsandstonesmooth2_top 212 126 108 +mcl_stairs:slab_sandstone 202 155 121 +mcl_stairs:slab_sandstone_double 202 155 121 +mcl_stairs:slab_sandstone_top 202 155 121 +mcl_stairs:slab_sandstonesmooth2 202 155 121 +mcl_stairs:slab_sandstonesmooth2_double 202 155 121 +mcl_stairs:slab_sandstonesmooth2_top 202 155 121 +mcl_stairs:slab_sprucetree_bark 69 53 45 +mcl_stairs:slab_sprucetree_bark_double 69 53 45 +mcl_stairs:slab_sprucetree_bark_top 69 53 45 +mcl_stairs:slab_sprucewood 82 66 54 +mcl_stairs:slab_sprucewood_double 82 66 54 +mcl_stairs:slab_sprucewood_top 82 66 54 +mcl_stairs:slab_stone 128 119 115 +mcl_stairs:slab_stone_double 128 119 115 +mcl_stairs:slab_stone_rough 131 123 118 +mcl_stairs:slab_stone_rough_double 131 123 118 +mcl_stairs:slab_stone_rough_top 131 123 118 +mcl_stairs:slab_stone_top 128 119 115 +mcl_stairs:slab_stonebrick 99 91 88 +mcl_stairs:slab_stonebrick_double 99 91 88 +mcl_stairs:slab_stonebrick_top 99 91 88 +mcl_stairs:slab_stonebrickcracked 96 89 85 +mcl_stairs:slab_stonebrickcracked_double 96 89 85 +mcl_stairs:slab_stonebrickcracked_top 96 89 85 +mcl_stairs:slab_stonebrickmossy 86 104 79 +mcl_stairs:slab_stonebrickmossy_double 86 104 79 +mcl_stairs:slab_stonebrickmossy_top 86 104 79 +mcl_stairs:slab_tree_bark 99 78 59 +mcl_stairs:slab_tree_bark_double 99 78 59 +mcl_stairs:slab_tree_bark_top 99 78 59 +mcl_stairs:slab_warped_hyphae_wood 78 64 108 +mcl_stairs:slab_warped_hyphae_wood_double 78 64 108 +mcl_stairs:slab_warped_hyphae_wood_top 78 64 108 +mcl_stairs:slab_wood 115 89 68 +mcl_stairs:slab_wood_double 115 89 68 +mcl_stairs:slab_wood_top 115 89 68 +mcl_stairs:stair_acaciatree_bark 107 94 77 +mcl_stairs:stair_acaciatree_bark_inner 107 94 77 +mcl_stairs:stair_acaciatree_bark_outer 107 94 77 +mcl_stairs:stair_acaciawood 153 103 71 +mcl_stairs:stair_acaciawood_inner 153 103 71 +mcl_stairs:stair_acaciawood_outer 153 103 71 +mcl_stairs:stair_andesite 105 111 107 +mcl_stairs:stair_andesite_inner 105 111 107 +mcl_stairs:stair_andesite_outer 105 111 107 +mcl_stairs:stair_andesite_smooth 107 114 109 +mcl_stairs:stair_andesite_smooth_inner 107 114 109 +mcl_stairs:stair_andesite_smooth_outer 107 114 109 +mcl_stairs:stair_birchtree_bark 199 190 180 +mcl_stairs:stair_birchtree_bark_inner 199 190 180 +mcl_stairs:stair_birchtree_bark_outer 199 190 180 +mcl_stairs:stair_birchwood 147 116 90 +mcl_stairs:stair_birchwood_inner 147 116 90 +mcl_stairs:stair_birchwood_outer 147 116 90 +mcl_stairs:stair_blackstone 33 31 35 +mcl_stairs:stair_blackstone_brick_polished 42 39 44 +mcl_stairs:stair_blackstone_brick_polished_inner 42 39 44 +mcl_stairs:stair_blackstone_brick_polished_outer 42 39 44 +mcl_stairs:stair_blackstone_chiseled_polished 42 39 44 +mcl_stairs:stair_blackstone_chiseled_polished_inner 42 39 44 +mcl_stairs:stair_blackstone_chiseled_polished_outer 42 39 44 +mcl_stairs:stair_blackstone_inner 33 31 35 +mcl_stairs:stair_blackstone_outer 33 31 35 +mcl_stairs:stair_blackstone_polished 44 42 47 +mcl_stairs:stair_blackstone_polished_inner 44 42 47 +mcl_stairs:stair_blackstone_polished_outer 44 42 47 +mcl_stairs:stair_brick_block 140 92 81 +mcl_stairs:stair_brick_block_inner 140 92 81 +mcl_stairs:stair_brick_block_outer 140 92 81 +mcl_stairs:stair_cobble 114 108 105 +mcl_stairs:stair_cobble_inner 114 108 105 +mcl_stairs:stair_cobble_outer 114 108 105 +mcl_stairs:stair_concrete_black 8 10 15 +mcl_stairs:stair_concrete_black_inner 8 10 15 +mcl_stairs:stair_concrete_black_outer 8 10 15 +mcl_stairs:stair_concrete_blue 46 48 147 +mcl_stairs:stair_concrete_blue_inner 46 48 147 +mcl_stairs:stair_concrete_blue_outer 46 48 147 +mcl_stairs:stair_concrete_brown 98 60 32 +mcl_stairs:stair_concrete_brown_inner 98 60 32 +mcl_stairs:stair_concrete_brown_outer 98 60 32 +mcl_stairs:stair_concrete_cyan 21 123 140 +mcl_stairs:stair_concrete_cyan_inner 21 123 140 +mcl_stairs:stair_concrete_cyan_outer 21 123 140 +mcl_stairs:stair_concrete_green 75 94 37 +mcl_stairs:stair_concrete_green_inner 75 94 37 +mcl_stairs:stair_concrete_green_outer 75 94 37 +mcl_stairs:stair_concrete_grey 56 59 64 +mcl_stairs:stair_concrete_grey_inner 56 59 64 +mcl_stairs:stair_concrete_grey_outer 56 59 64 +mcl_stairs:stair_concrete_light_blue 37 140 200 +mcl_stairs:stair_concrete_light_blue_inner 37 140 200 +mcl_stairs:stair_concrete_light_blue_outer 37 140 200 +mcl_stairs:stair_concrete_lime 96 171 25 +mcl_stairs:stair_concrete_lime_inner 96 171 25 +mcl_stairs:stair_concrete_lime_outer 96 171 25 +mcl_stairs:stair_concrete_magenta 171 49 162 +mcl_stairs:stair_concrete_magenta_inner 171 49 162 +mcl_stairs:stair_concrete_magenta_outer 171 49 162 +mcl_stairs:stair_concrete_orange 226 101 1 +mcl_stairs:stair_concrete_orange_inner 226 101 1 +mcl_stairs:stair_concrete_orange_outer 226 101 1 +mcl_stairs:stair_concrete_pink 213 103 144 +mcl_stairs:stair_concrete_pink_inner 213 103 144 +mcl_stairs:stair_concrete_pink_outer 213 103 144 +mcl_stairs:stair_concrete_purple 103 32 159 +mcl_stairs:stair_concrete_purple_inner 103 32 159 +mcl_stairs:stair_concrete_purple_outer 103 32 159 +mcl_stairs:stair_concrete_red 146 34 34 +mcl_stairs:stair_concrete_red_inner 146 34 34 +mcl_stairs:stair_concrete_red_outer 146 34 34 +mcl_stairs:stair_concrete_silver 128 129 118 +mcl_stairs:stair_concrete_silver_inner 128 129 118 +mcl_stairs:stair_concrete_silver_outer 128 129 118 +mcl_stairs:stair_concrete_white 208 214 215 +mcl_stairs:stair_concrete_white_inner 208 214 215 +mcl_stairs:stair_concrete_white_outer 208 214 215 +mcl_stairs:stair_concrete_yellow 241 177 21 +mcl_stairs:stair_concrete_yellow_inner 241 177 21 +mcl_stairs:stair_concrete_yellow_outer 241 177 21 +mcl_stairs:stair_copper_cut 150 78 58 +mcl_stairs:stair_copper_cut_inner 150 78 58 +mcl_stairs:stair_copper_cut_outer 150 78 58 +mcl_stairs:stair_copper_exposed_cut 132 94 84 +mcl_stairs:stair_copper_exposed_cut_inner 132 94 84 +mcl_stairs:stair_copper_exposed_cut_outer 132 94 84 +mcl_stairs:stair_copper_oxidized_cut 91 112 112 +mcl_stairs:stair_copper_oxidized_cut_inner 91 112 112 +mcl_stairs:stair_copper_oxidized_cut_outer 91 112 112 +mcl_stairs:stair_copper_weathered_cut 109 105 102 +mcl_stairs:stair_copper_weathered_cut_inner 109 105 102 +mcl_stairs:stair_copper_weathered_cut_outer 109 105 102 +mcl_stairs:stair_crimson_hyphae_wood 119 46 40 +mcl_stairs:stair_crimson_hyphae_wood_inner 119 46 40 +mcl_stairs:stair_crimson_hyphae_wood_outer 119 46 40 +mcl_stairs:stair_darktree_bark 77 65 58 +mcl_stairs:stair_darktree_bark_inner 77 65 58 +mcl_stairs:stair_darktree_bark_outer 77 65 58 +mcl_stairs:stair_darkwood 89 76 63 +mcl_stairs:stair_darkwood_inner 89 76 63 +mcl_stairs:stair_darkwood_outer 89 76 63 +mcl_stairs:stair_deepslate_bricks 64 62 62 +mcl_stairs:stair_deepslate_bricks_inner 64 62 62 +mcl_stairs:stair_deepslate_bricks_outer 64 62 62 +mcl_stairs:stair_deepslate_cobbled 80 78 76 +mcl_stairs:stair_deepslate_cobbled_inner 80 78 76 +mcl_stairs:stair_deepslate_cobbled_outer 80 78 76 +mcl_stairs:stair_deepslate_polished 69 68 67 +mcl_stairs:stair_deepslate_polished_inner 69 68 67 +mcl_stairs:stair_deepslate_polished_outer 69 68 67 +mcl_stairs:stair_deepslate_tiles 51 50 49 +mcl_stairs:stair_deepslate_tiles_inner 51 50 49 +mcl_stairs:stair_deepslate_tiles_outer 51 50 49 +mcl_stairs:stair_diorite 154 150 148 +mcl_stairs:stair_diorite_inner 154 150 148 +mcl_stairs:stair_diorite_outer 154 150 148 +mcl_stairs:stair_diorite_smooth 158 155 152 +mcl_stairs:stair_diorite_smooth_inner 158 155 152 +mcl_stairs:stair_diorite_smooth_outer 158 155 152 +mcl_stairs:stair_end_bricks 195 189 123 +mcl_stairs:stair_end_bricks_inner 195 189 123 +mcl_stairs:stair_end_bricks_outer 195 189 123 +mcl_stairs:stair_goldblock 195 152 65 +mcl_stairs:stair_goldblock_inner 195 152 65 +mcl_stairs:stair_goldblock_outer 195 152 65 +mcl_stairs:stair_granite 155 122 111 +mcl_stairs:stair_granite_inner 155 122 111 +mcl_stairs:stair_granite_outer 155 122 111 +mcl_stairs:stair_granite_smooth 152 122 110 +mcl_stairs:stair_granite_smooth_inner 152 122 110 +mcl_stairs:stair_granite_smooth_outer 152 122 110 +mcl_stairs:stair_ironblock 173 167 167 +mcl_stairs:stair_ironblock_inner 173 167 167 +mcl_stairs:stair_ironblock_outer 173 167 167 +mcl_stairs:stair_jungletree_bark 90 62 46 +mcl_stairs:stair_jungletree_bark_inner 90 62 46 +mcl_stairs:stair_jungletree_bark_outer 90 62 46 +mcl_stairs:stair_junglewood 114 80 60 +mcl_stairs:stair_junglewood_inner 114 80 60 +mcl_stairs:stair_junglewood_outer 114 80 60 +mcl_stairs:stair_lapisblock 57 95 161 +mcl_stairs:stair_lapisblock_inner 57 95 161 +mcl_stairs:stair_lapisblock_outer 57 95 161 +mcl_stairs:stair_mangrove_wood 125 61 55 +mcl_stairs:stair_mangrove_wood_inner 125 61 55 +mcl_stairs:stair_mangrove_wood_outer 125 61 55 +mcl_stairs:stair_mossycobble 105 106 97 +mcl_stairs:stair_mossycobble_inner 105 106 97 +mcl_stairs:stair_mossycobble_outer 105 106 97 +mcl_stairs:stair_mud_brick 109 96 87 +mcl_stairs:stair_mud_brick_inner 109 96 87 +mcl_stairs:stair_mud_brick_outer 109 96 87 +mcl_stairs:stair_nether_brick 49 25 26 +mcl_stairs:stair_nether_brick_inner 49 25 26 +mcl_stairs:stair_nether_brick_outer 49 25 26 +mcl_stairs:stair_prismarine 106 127 123 +mcl_stairs:stair_prismarine_brick 107 116 117 +mcl_stairs:stair_prismarine_brick_inner 107 116 117 +mcl_stairs:stair_prismarine_brick_outer 107 116 117 +mcl_stairs:stair_prismarine_dark 77 90 97 +mcl_stairs:stair_prismarine_dark_inner 77 90 97 +mcl_stairs:stair_prismarine_dark_outer 77 90 97 +mcl_stairs:stair_prismarine_inner 106 127 123 +mcl_stairs:stair_prismarine_outer 106 127 123 +mcl_stairs:stair_purpur_block 161 112 175 +mcl_stairs:stair_purpur_block_inner 161 112 175 +mcl_stairs:stair_purpur_block_outer 161 112 175 +mcl_stairs:stair_quartz_smooth 198 191 187 +mcl_stairs:stair_quartz_smooth_inner 198 191 187 +mcl_stairs:stair_quartz_smooth_outer 198 191 187 +mcl_stairs:stair_quartzblock 198 191 187 +mcl_stairs:stair_quartzblock_inner 198 191 187 +mcl_stairs:stair_quartzblock_outer 198 191 187 +mcl_stairs:stair_red_nether_brick 72 17 6 +mcl_stairs:stair_red_nether_brick_inner 72 17 6 +mcl_stairs:stair_red_nether_brick_outer 72 17 6 +mcl_stairs:stair_redsandstone 212 126 108 +mcl_stairs:stair_redsandstone_inner 212 126 108 +mcl_stairs:stair_redsandstone_outer 212 126 108 +mcl_stairs:stair_redsandstonesmooth2 212 126 108 +mcl_stairs:stair_redsandstonesmooth2_inner 212 126 108 +mcl_stairs:stair_redsandstonesmooth2_outer 212 126 108 +mcl_stairs:stair_sandstone 202 155 121 +mcl_stairs:stair_sandstone_inner 202 155 121 +mcl_stairs:stair_sandstone_outer 202 155 121 +mcl_stairs:stair_sandstonesmooth2 202 155 121 +mcl_stairs:stair_sandstonesmooth2_inner 202 155 121 +mcl_stairs:stair_sandstonesmooth2_outer 202 155 121 +mcl_stairs:stair_sprucetree_bark 69 53 45 +mcl_stairs:stair_sprucetree_bark_inner 69 53 45 +mcl_stairs:stair_sprucetree_bark_outer 69 53 45 +mcl_stairs:stair_sprucewood 82 66 54 +mcl_stairs:stair_sprucewood_inner 82 66 54 +mcl_stairs:stair_sprucewood_outer 82 66 54 +mcl_stairs:stair_stone_rough 131 123 118 +mcl_stairs:stair_stone_rough_inner 131 123 118 +mcl_stairs:stair_stone_rough_outer 131 123 118 +mcl_stairs:stair_stonebrick 99 91 88 +mcl_stairs:stair_stonebrick_inner 99 91 88 +mcl_stairs:stair_stonebrick_outer 99 91 88 +mcl_stairs:stair_stonebrickcracked 96 89 85 +mcl_stairs:stair_stonebrickcracked_inner 96 89 85 +mcl_stairs:stair_stonebrickcracked_outer 96 89 85 +mcl_stairs:stair_stonebrickmossy 86 104 79 +mcl_stairs:stair_stonebrickmossy_inner 86 104 79 +mcl_stairs:stair_stonebrickmossy_outer 86 104 79 +mcl_stairs:stair_tree_bark 99 78 59 +mcl_stairs:stair_tree_bark_inner 99 78 59 +mcl_stairs:stair_tree_bark_outer 99 78 59 +mcl_stairs:stair_warped_hyphae_wood 78 64 108 +mcl_stairs:stair_warped_hyphae_wood_inner 78 64 108 +mcl_stairs:stair_warped_hyphae_wood_outer 78 64 108 +mcl_stairs:stair_wood 115 89 68 +mcl_stairs:stair_wood_inner 115 89 68 +mcl_stairs:stair_wood_outer 115 89 68 + +# mcl_stonecutter +mcl_stonecutter:stonecutter 88 82 80 + +# mcl_structures + +# mcl_target +mcl_target:target_off 182 137 112 +mcl_target:target_on 182 137 112 + +# mcl_tnt +mcl_tnt:tnt 134 55 57 + +# mcl_torches +mcl_torches:torch 94 72 58 +mcl_torches:torch_wall 94 72 58 + +# mcl_villages +mcl_villages:stonebrickcarved 100 92 88 + +# mcl_walls +mcl_walls:andesite 105 111 107 +mcl_walls:andesite_0 105 111 107 +mcl_walls:andesite_1 105 111 107 +mcl_walls:andesite_10 105 111 107 +mcl_walls:andesite_11 105 111 107 +mcl_walls:andesite_12 105 111 107 +mcl_walls:andesite_13 105 111 107 +mcl_walls:andesite_14 105 111 107 +mcl_walls:andesite_15 105 111 107 +mcl_walls:andesite_16 105 111 107 +mcl_walls:andesite_2 105 111 107 +mcl_walls:andesite_21 105 111 107 +mcl_walls:andesite_3 105 111 107 +mcl_walls:andesite_4 105 111 107 +mcl_walls:andesite_5 105 111 107 +mcl_walls:andesite_6 105 111 107 +mcl_walls:andesite_7 105 111 107 +mcl_walls:andesite_8 105 111 107 +mcl_walls:andesite_9 105 111 107 +mcl_walls:brick 140 92 81 +mcl_walls:brick_0 140 92 81 +mcl_walls:brick_1 140 92 81 +mcl_walls:brick_10 140 92 81 +mcl_walls:brick_11 140 92 81 +mcl_walls:brick_12 140 92 81 +mcl_walls:brick_13 140 92 81 +mcl_walls:brick_14 140 92 81 +mcl_walls:brick_15 140 92 81 +mcl_walls:brick_16 140 92 81 +mcl_walls:brick_2 140 92 81 +mcl_walls:brick_21 140 92 81 +mcl_walls:brick_3 140 92 81 +mcl_walls:brick_4 140 92 81 +mcl_walls:brick_5 140 92 81 +mcl_walls:brick_6 140 92 81 +mcl_walls:brick_7 140 92 81 +mcl_walls:brick_8 140 92 81 +mcl_walls:brick_9 140 92 81 +mcl_walls:cobble 122 116 113 +mcl_walls:cobble_0 122 116 113 +mcl_walls:cobble_1 122 116 113 +mcl_walls:cobble_10 122 116 113 +mcl_walls:cobble_11 122 116 113 +mcl_walls:cobble_12 122 116 113 +mcl_walls:cobble_13 122 116 113 +mcl_walls:cobble_14 122 116 113 +mcl_walls:cobble_15 122 116 113 +mcl_walls:cobble_16 122 116 113 +mcl_walls:cobble_2 122 116 113 +mcl_walls:cobble_21 122 116 113 +mcl_walls:cobble_3 122 116 113 +mcl_walls:cobble_4 122 116 113 +mcl_walls:cobble_5 122 116 113 +mcl_walls:cobble_6 122 116 113 +mcl_walls:cobble_7 122 116 113 +mcl_walls:cobble_8 122 116 113 +mcl_walls:cobble_9 122 116 113 +mcl_walls:diorite 154 150 148 +mcl_walls:diorite_0 154 150 148 +mcl_walls:diorite_1 154 150 148 +mcl_walls:diorite_10 154 150 148 +mcl_walls:diorite_11 154 150 148 +mcl_walls:diorite_12 154 150 148 +mcl_walls:diorite_13 154 150 148 +mcl_walls:diorite_14 154 150 148 +mcl_walls:diorite_15 154 150 148 +mcl_walls:diorite_16 154 150 148 +mcl_walls:diorite_2 154 150 148 +mcl_walls:diorite_21 154 150 148 +mcl_walls:diorite_3 154 150 148 +mcl_walls:diorite_4 154 150 148 +mcl_walls:diorite_5 154 150 148 +mcl_walls:diorite_6 154 150 148 +mcl_walls:diorite_7 154 150 148 +mcl_walls:diorite_8 154 150 148 +mcl_walls:diorite_9 154 150 148 +mcl_walls:endbricks 195 189 123 +mcl_walls:endbricks_0 195 189 123 +mcl_walls:endbricks_1 195 189 123 +mcl_walls:endbricks_10 195 189 123 +mcl_walls:endbricks_11 195 189 123 +mcl_walls:endbricks_12 195 189 123 +mcl_walls:endbricks_13 195 189 123 +mcl_walls:endbricks_14 195 189 123 +mcl_walls:endbricks_15 195 189 123 +mcl_walls:endbricks_16 195 189 123 +mcl_walls:endbricks_2 195 189 123 +mcl_walls:endbricks_21 195 189 123 +mcl_walls:endbricks_3 195 189 123 +mcl_walls:endbricks_4 195 189 123 +mcl_walls:endbricks_5 195 189 123 +mcl_walls:endbricks_6 195 189 123 +mcl_walls:endbricks_7 195 189 123 +mcl_walls:endbricks_8 195 189 123 +mcl_walls:endbricks_9 195 189 123 +mcl_walls:granite 155 122 111 +mcl_walls:granite_0 155 122 111 +mcl_walls:granite_1 155 122 111 +mcl_walls:granite_10 155 122 111 +mcl_walls:granite_11 155 122 111 +mcl_walls:granite_12 155 122 111 +mcl_walls:granite_13 155 122 111 +mcl_walls:granite_14 155 122 111 +mcl_walls:granite_15 155 122 111 +mcl_walls:granite_16 155 122 111 +mcl_walls:granite_2 155 122 111 +mcl_walls:granite_21 155 122 111 +mcl_walls:granite_3 155 122 111 +mcl_walls:granite_4 155 122 111 +mcl_walls:granite_5 155 122 111 +mcl_walls:granite_6 155 122 111 +mcl_walls:granite_7 155 122 111 +mcl_walls:granite_8 155 122 111 +mcl_walls:granite_9 155 122 111 +mcl_walls:mossycobble 59 98 63 +mcl_walls:mossycobble_0 59 98 63 +mcl_walls:mossycobble_1 59 98 63 +mcl_walls:mossycobble_10 59 98 63 +mcl_walls:mossycobble_11 59 98 63 +mcl_walls:mossycobble_12 59 98 63 +mcl_walls:mossycobble_13 59 98 63 +mcl_walls:mossycobble_14 59 98 63 +mcl_walls:mossycobble_15 59 98 63 +mcl_walls:mossycobble_16 59 98 63 +mcl_walls:mossycobble_2 59 98 63 +mcl_walls:mossycobble_21 59 98 63 +mcl_walls:mossycobble_3 59 98 63 +mcl_walls:mossycobble_4 59 98 63 +mcl_walls:mossycobble_5 59 98 63 +mcl_walls:mossycobble_6 59 98 63 +mcl_walls:mossycobble_7 59 98 63 +mcl_walls:mossycobble_8 59 98 63 +mcl_walls:mossycobble_9 59 98 63 +mcl_walls:mudbrick 109 96 87 +mcl_walls:mudbrick_0 109 96 87 +mcl_walls:mudbrick_1 109 96 87 +mcl_walls:mudbrick_10 109 96 87 +mcl_walls:mudbrick_11 109 96 87 +mcl_walls:mudbrick_12 109 96 87 +mcl_walls:mudbrick_13 109 96 87 +mcl_walls:mudbrick_14 109 96 87 +mcl_walls:mudbrick_15 109 96 87 +mcl_walls:mudbrick_16 109 96 87 +mcl_walls:mudbrick_2 109 96 87 +mcl_walls:mudbrick_21 109 96 87 +mcl_walls:mudbrick_3 109 96 87 +mcl_walls:mudbrick_4 109 96 87 +mcl_walls:mudbrick_5 109 96 87 +mcl_walls:mudbrick_6 109 96 87 +mcl_walls:mudbrick_7 109 96 87 +mcl_walls:mudbrick_8 109 96 87 +mcl_walls:mudbrick_9 109 96 87 +mcl_walls:netherbrick 49 25 26 +mcl_walls:netherbrick_0 49 25 26 +mcl_walls:netherbrick_1 49 25 26 +mcl_walls:netherbrick_10 49 25 26 +mcl_walls:netherbrick_11 49 25 26 +mcl_walls:netherbrick_12 49 25 26 +mcl_walls:netherbrick_13 49 25 26 +mcl_walls:netherbrick_14 49 25 26 +mcl_walls:netherbrick_15 49 25 26 +mcl_walls:netherbrick_16 49 25 26 +mcl_walls:netherbrick_2 49 25 26 +mcl_walls:netherbrick_21 49 25 26 +mcl_walls:netherbrick_3 49 25 26 +mcl_walls:netherbrick_4 49 25 26 +mcl_walls:netherbrick_5 49 25 26 +mcl_walls:netherbrick_6 49 25 26 +mcl_walls:netherbrick_7 49 25 26 +mcl_walls:netherbrick_8 49 25 26 +mcl_walls:netherbrick_9 49 25 26 +mcl_walls:prismarine 106 127 123 +mcl_walls:prismarine_0 106 127 123 +mcl_walls:prismarine_1 106 127 123 +mcl_walls:prismarine_10 106 127 123 +mcl_walls:prismarine_11 106 127 123 +mcl_walls:prismarine_12 106 127 123 +mcl_walls:prismarine_13 106 127 123 +mcl_walls:prismarine_14 106 127 123 +mcl_walls:prismarine_15 106 127 123 +mcl_walls:prismarine_16 106 127 123 +mcl_walls:prismarine_2 106 127 123 +mcl_walls:prismarine_21 106 127 123 +mcl_walls:prismarine_3 106 127 123 +mcl_walls:prismarine_4 106 127 123 +mcl_walls:prismarine_5 106 127 123 +mcl_walls:prismarine_6 106 127 123 +mcl_walls:prismarine_7 106 127 123 +mcl_walls:prismarine_8 106 127 123 +mcl_walls:prismarine_9 106 127 123 +mcl_walls:rednetherbrick 72 17 6 +mcl_walls:rednetherbrick_0 72 17 6 +mcl_walls:rednetherbrick_1 72 17 6 +mcl_walls:rednetherbrick_10 72 17 6 +mcl_walls:rednetherbrick_11 72 17 6 +mcl_walls:rednetherbrick_12 72 17 6 +mcl_walls:rednetherbrick_13 72 17 6 +mcl_walls:rednetherbrick_14 72 17 6 +mcl_walls:rednetherbrick_15 72 17 6 +mcl_walls:rednetherbrick_16 72 17 6 +mcl_walls:rednetherbrick_2 72 17 6 +mcl_walls:rednetherbrick_21 72 17 6 +mcl_walls:rednetherbrick_3 72 17 6 +mcl_walls:rednetherbrick_4 72 17 6 +mcl_walls:rednetherbrick_5 72 17 6 +mcl_walls:rednetherbrick_6 72 17 6 +mcl_walls:rednetherbrick_7 72 17 6 +mcl_walls:rednetherbrick_8 72 17 6 +mcl_walls:rednetherbrick_9 72 17 6 +mcl_walls:redsandstone 212 126 108 +mcl_walls:redsandstone_0 212 126 108 +mcl_walls:redsandstone_1 212 126 108 +mcl_walls:redsandstone_10 212 126 108 +mcl_walls:redsandstone_11 212 126 108 +mcl_walls:redsandstone_12 212 126 108 +mcl_walls:redsandstone_13 212 126 108 +mcl_walls:redsandstone_14 212 126 108 +mcl_walls:redsandstone_15 212 126 108 +mcl_walls:redsandstone_16 212 126 108 +mcl_walls:redsandstone_2 212 126 108 +mcl_walls:redsandstone_21 212 126 108 +mcl_walls:redsandstone_3 212 126 108 +mcl_walls:redsandstone_4 212 126 108 +mcl_walls:redsandstone_5 212 126 108 +mcl_walls:redsandstone_6 212 126 108 +mcl_walls:redsandstone_7 212 126 108 +mcl_walls:redsandstone_8 212 126 108 +mcl_walls:redsandstone_9 212 126 108 +mcl_walls:sandstone 202 155 121 +mcl_walls:sandstone_0 202 155 121 +mcl_walls:sandstone_1 202 155 121 +mcl_walls:sandstone_10 202 155 121 +mcl_walls:sandstone_11 202 155 121 +mcl_walls:sandstone_12 202 155 121 +mcl_walls:sandstone_13 202 155 121 +mcl_walls:sandstone_14 202 155 121 +mcl_walls:sandstone_15 202 155 121 +mcl_walls:sandstone_16 202 155 121 +mcl_walls:sandstone_2 202 155 121 +mcl_walls:sandstone_21 202 155 121 +mcl_walls:sandstone_3 202 155 121 +mcl_walls:sandstone_4 202 155 121 +mcl_walls:sandstone_5 202 155 121 +mcl_walls:sandstone_6 202 155 121 +mcl_walls:sandstone_7 202 155 121 +mcl_walls:sandstone_8 202 155 121 +mcl_walls:sandstone_9 202 155 121 +mcl_walls:stonebrick 99 91 88 +mcl_walls:stonebrick_0 99 91 88 +mcl_walls:stonebrick_1 99 91 88 +mcl_walls:stonebrick_10 99 91 88 +mcl_walls:stonebrick_11 99 91 88 +mcl_walls:stonebrick_12 99 91 88 +mcl_walls:stonebrick_13 99 91 88 +mcl_walls:stonebrick_14 99 91 88 +mcl_walls:stonebrick_15 99 91 88 +mcl_walls:stonebrick_16 99 91 88 +mcl_walls:stonebrick_2 99 91 88 +mcl_walls:stonebrick_21 99 91 88 +mcl_walls:stonebrick_3 99 91 88 +mcl_walls:stonebrick_4 99 91 88 +mcl_walls:stonebrick_5 99 91 88 +mcl_walls:stonebrick_6 99 91 88 +mcl_walls:stonebrick_7 99 91 88 +mcl_walls:stonebrick_8 99 91 88 +mcl_walls:stonebrick_9 99 91 88 +mcl_walls:stonebrickmossy 86 104 79 +mcl_walls:stonebrickmossy_0 86 104 79 +mcl_walls:stonebrickmossy_1 86 104 79 +mcl_walls:stonebrickmossy_10 86 104 79 +mcl_walls:stonebrickmossy_11 86 104 79 +mcl_walls:stonebrickmossy_12 86 104 79 +mcl_walls:stonebrickmossy_13 86 104 79 +mcl_walls:stonebrickmossy_14 86 104 79 +mcl_walls:stonebrickmossy_15 86 104 79 +mcl_walls:stonebrickmossy_16 86 104 79 +mcl_walls:stonebrickmossy_2 86 104 79 +mcl_walls:stonebrickmossy_21 86 104 79 +mcl_walls:stonebrickmossy_3 86 104 79 +mcl_walls:stonebrickmossy_4 86 104 79 +mcl_walls:stonebrickmossy_5 86 104 79 +mcl_walls:stonebrickmossy_6 86 104 79 +mcl_walls:stonebrickmossy_7 86 104 79 +mcl_walls:stonebrickmossy_8 86 104 79 +mcl_walls:stonebrickmossy_9 86 104 79 + +# mcl_wool +mcl_wool:black 46 43 43 +mcl_wool:black_carpet 46 43 43 +mcl_wool:blue 43 75 126 +mcl_wool:blue_carpet 43 75 126 +mcl_wool:brown 87 57 43 +mcl_wool:brown_carpet 87 57 43 +mcl_wool:cyan 30 95 113 +mcl_wool:cyan_carpet 30 95 113 +mcl_wool:green 54 92 51 +mcl_wool:green_carpet 54 92 51 +mcl_wool:grey 97 88 88 +mcl_wool:grey_carpet 97 88 88 +mcl_wool:light_blue 92 132 180 +mcl_wool:light_blue_carpet 92 132 180 +mcl_wool:lime 110 152 77 +mcl_wool:lime_carpet 110 152 77 +mcl_wool:magenta 142 86 126 +mcl_wool:magenta_carpet 142 86 126 +mcl_wool:orange 188 107 46 +mcl_wool:orange_carpet 188 107 46 +mcl_wool:pink 171 92 108 +mcl_wool:pink_carpet 171 92 108 +mcl_wool:purple 79 57 103 +mcl_wool:purple_carpet 79 57 103 +mcl_wool:red 133 42 45 +mcl_wool:red_carpet 133 42 45 +mcl_wool:silver 143 135 135 +mcl_wool:silver_carpet 143 135 135 +mcl_wool:white 212 199 183 +mcl_wool:white_carpet 212 199 183 +mcl_wool:yellow 201 164 70 +mcl_wool:yellow_carpet 201 164 70 + +# mclx_core +mclx_core:river_water_flowing 0 122 139 +mclx_core:river_water_source 32 121 138 + +# mclx_fences +mclx_fences:nether_brick_fence_gate 51 27 27 +mclx_fences:nether_brick_fence_gate_open 51 27 27 +mclx_fences:red_nether_brick_fence 72 18 0 +mclx_fences:red_nether_brick_fence_gate 68 16 0 +mclx_fences:red_nether_brick_fence_gate_open 68 16 0 + +# mesecons +mesecons:wire_00000000_off 171 171 171 +mesecons:wire_00000000_on 171 171 171 +mesecons:wire_00010000_off 171 171 171 +mesecons:wire_00010000_on 171 171 171 +mesecons:wire_00010001_off 171 171 171 +mesecons:wire_00010001_on 171 171 171 +mesecons:wire_00100000_off 171 171 171 +mesecons:wire_00100000_on 171 171 171 +mesecons:wire_00100010_off 171 171 171 +mesecons:wire_00100010_on 171 171 171 +mesecons:wire_00110000_off 171 171 171 +mesecons:wire_00110000_on 171 171 171 +mesecons:wire_00110001_off 171 171 171 +mesecons:wire_00110001_on 171 171 171 +mesecons:wire_00110010_off 171 171 171 +mesecons:wire_00110010_on 171 171 171 +mesecons:wire_00110011_off 171 171 171 +mesecons:wire_00110011_on 171 171 171 +mesecons:wire_01000000_off 171 171 171 +mesecons:wire_01000000_on 171 171 171 +mesecons:wire_01000100_off 171 171 171 +mesecons:wire_01000100_on 171 171 171 +mesecons:wire_01010000_off 171 171 171 +mesecons:wire_01010000_on 171 171 171 +mesecons:wire_01010001_off 171 171 171 +mesecons:wire_01010001_on 171 171 171 +mesecons:wire_01010100_off 171 171 171 +mesecons:wire_01010100_on 171 171 171 +mesecons:wire_01010101_off 171 171 171 +mesecons:wire_01010101_on 171 171 171 +mesecons:wire_01100000_off 171 171 171 +mesecons:wire_01100000_on 171 171 171 +mesecons:wire_01100010_off 171 171 171 +mesecons:wire_01100010_on 171 171 171 +mesecons:wire_01100100_off 171 171 171 +mesecons:wire_01100100_on 171 171 171 +mesecons:wire_01100110_off 171 171 171 +mesecons:wire_01100110_on 171 171 171 +mesecons:wire_01110000_off 171 171 171 +mesecons:wire_01110000_on 171 171 171 +mesecons:wire_01110001_off 171 171 171 +mesecons:wire_01110001_on 171 171 171 +mesecons:wire_01110010_off 171 171 171 +mesecons:wire_01110010_on 171 171 171 +mesecons:wire_01110011_off 171 171 171 +mesecons:wire_01110011_on 171 171 171 +mesecons:wire_01110100_off 171 171 171 +mesecons:wire_01110100_on 171 171 171 +mesecons:wire_01110101_off 171 171 171 +mesecons:wire_01110101_on 171 171 171 +mesecons:wire_01110110_off 171 171 171 +mesecons:wire_01110110_on 171 171 171 +mesecons:wire_01110111_off 171 171 171 +mesecons:wire_01110111_on 171 171 171 +mesecons:wire_10000000_off 171 171 171 +mesecons:wire_10000000_on 171 171 171 +mesecons:wire_10001000_off 171 171 171 +mesecons:wire_10001000_on 171 171 171 +mesecons:wire_10010000_off 171 171 171 +mesecons:wire_10010000_on 171 171 171 +mesecons:wire_10010001_off 171 171 171 +mesecons:wire_10010001_on 171 171 171 +mesecons:wire_10011000_off 171 171 171 +mesecons:wire_10011000_on 171 171 171 +mesecons:wire_10011001_off 171 171 171 +mesecons:wire_10011001_on 171 171 171 +mesecons:wire_10100000_off 171 171 171 +mesecons:wire_10100000_on 171 171 171 +mesecons:wire_10100010_off 171 171 171 +mesecons:wire_10100010_on 171 171 171 +mesecons:wire_10101000_off 171 171 171 +mesecons:wire_10101000_on 171 171 171 +mesecons:wire_10101010_off 171 171 171 +mesecons:wire_10101010_on 171 171 171 +mesecons:wire_10110000_off 171 171 171 +mesecons:wire_10110000_on 171 171 171 +mesecons:wire_10110001_off 171 171 171 +mesecons:wire_10110001_on 171 171 171 +mesecons:wire_10110010_off 171 171 171 +mesecons:wire_10110010_on 171 171 171 +mesecons:wire_10110011_off 171 171 171 +mesecons:wire_10110011_on 171 171 171 +mesecons:wire_10111000_off 171 171 171 +mesecons:wire_10111000_on 171 171 171 +mesecons:wire_10111001_off 171 171 171 +mesecons:wire_10111001_on 171 171 171 +mesecons:wire_10111010_off 171 171 171 +mesecons:wire_10111010_on 171 171 171 +mesecons:wire_10111011_off 171 171 171 +mesecons:wire_10111011_on 171 171 171 +mesecons:wire_11000000_off 171 171 171 +mesecons:wire_11000000_on 171 171 171 +mesecons:wire_11000100_off 171 171 171 +mesecons:wire_11000100_on 171 171 171 +mesecons:wire_11001000_off 171 171 171 +mesecons:wire_11001000_on 171 171 171 +mesecons:wire_11001100_off 171 171 171 +mesecons:wire_11001100_on 171 171 171 +mesecons:wire_11010000_off 171 171 171 +mesecons:wire_11010000_on 171 171 171 +mesecons:wire_11010001_off 171 171 171 +mesecons:wire_11010001_on 171 171 171 +mesecons:wire_11010100_off 171 171 171 +mesecons:wire_11010100_on 171 171 171 +mesecons:wire_11010101_off 171 171 171 +mesecons:wire_11010101_on 171 171 171 +mesecons:wire_11011000_off 171 171 171 +mesecons:wire_11011000_on 171 171 171 +mesecons:wire_11011001_off 171 171 171 +mesecons:wire_11011001_on 171 171 171 +mesecons:wire_11011100_off 171 171 171 +mesecons:wire_11011100_on 171 171 171 +mesecons:wire_11011101_off 171 171 171 +mesecons:wire_11011101_on 171 171 171 +mesecons:wire_11100000_off 171 171 171 +mesecons:wire_11100000_on 171 171 171 +mesecons:wire_11100010_off 171 171 171 +mesecons:wire_11100010_on 171 171 171 +mesecons:wire_11100100_off 171 171 171 +mesecons:wire_11100100_on 171 171 171 +mesecons:wire_11100110_off 171 171 171 +mesecons:wire_11100110_on 171 171 171 +mesecons:wire_11101000_off 171 171 171 +mesecons:wire_11101000_on 171 171 171 +mesecons:wire_11101010_off 171 171 171 +mesecons:wire_11101010_on 171 171 171 +mesecons:wire_11101100_off 171 171 171 +mesecons:wire_11101100_on 171 171 171 +mesecons:wire_11101110_off 171 171 171 +mesecons:wire_11101110_on 171 171 171 +mesecons:wire_11110000_off 171 171 171 +mesecons:wire_11110000_on 171 171 171 +mesecons:wire_11110001_off 171 171 171 +mesecons:wire_11110001_on 171 171 171 +mesecons:wire_11110010_off 171 171 171 +mesecons:wire_11110010_on 171 171 171 +mesecons:wire_11110011_off 171 171 171 +mesecons:wire_11110011_on 171 171 171 +mesecons:wire_11110100_off 171 171 171 +mesecons:wire_11110100_on 171 171 171 +mesecons:wire_11110101_off 171 171 171 +mesecons:wire_11110101_on 171 171 171 +mesecons:wire_11110110_off 171 171 171 +mesecons:wire_11110110_on 171 171 171 +mesecons:wire_11110111_off 171 171 171 +mesecons:wire_11110111_on 171 171 171 +mesecons:wire_11111000_off 171 171 171 +mesecons:wire_11111000_on 171 171 171 +mesecons:wire_11111001_off 171 171 171 +mesecons:wire_11111001_on 171 171 171 +mesecons:wire_11111010_off 171 171 171 +mesecons:wire_11111010_on 171 171 171 +mesecons:wire_11111011_off 171 171 171 +mesecons:wire_11111011_on 171 171 171 +mesecons:wire_11111100_off 171 171 171 +mesecons:wire_11111100_on 171 171 171 +mesecons:wire_11111101_off 171 171 171 +mesecons:wire_11111101_on 171 171 171 +mesecons:wire_11111110_off 171 171 171 +mesecons:wire_11111110_on 171 171 171 +mesecons:wire_11111111_off 171 171 171 +mesecons:wire_11111111_on 171 171 171 + +# mesecons_button +mesecons_button:button_acaciawood_off 153 103 71 +mesecons_button:button_acaciawood_on 153 103 71 +mesecons_button:button_birchwood_off 147 116 90 +mesecons_button:button_birchwood_on 147 116 90 +mesecons_button:button_darkwood_off 89 76 63 +mesecons_button:button_darkwood_on 89 76 63 +mesecons_button:button_junglewood_off 114 80 60 +mesecons_button:button_junglewood_on 114 80 60 +mesecons_button:button_sprucewood_off 82 66 54 +mesecons_button:button_sprucewood_on 82 66 54 +mesecons_button:button_stone_off 131 123 118 +mesecons_button:button_stone_on 131 123 118 +mesecons_button:button_wood_off 115 89 68 +mesecons_button:button_wood_on 115 89 68 + +# mesecons_commandblock +mesecons_commandblock:commandblock_off 128 113 105 +mesecons_commandblock:commandblock_on 128 113 105 + +# mesecons_delayer +mesecons_delayer:delayer_off_1 115 105 101 +mesecons_delayer:delayer_off_2 115 105 101 +mesecons_delayer:delayer_off_3 115 105 101 +mesecons_delayer:delayer_off_4 115 105 101 +mesecons_delayer:delayer_off_locked 113 104 99 +mesecons_delayer:delayer_on_1 118 105 101 +mesecons_delayer:delayer_on_2 118 105 101 +mesecons_delayer:delayer_on_3 118 105 101 +mesecons_delayer:delayer_on_4 118 105 101 +mesecons_delayer:delayer_on_locked 116 104 99 + +# mesecons_lightstone +mesecons_lightstone:lightstone_off 73 52 44 +mesecons_lightstone:lightstone_on 122 65 41 + +# mesecons_noteblock +mesecons_noteblock:noteblock 114 89 69 + +# mesecons_pistons +mesecons_pistons:piston_down_normal_off 117 108 104 +mesecons_pistons:piston_down_normal_on 117 108 104 +mesecons_pistons:piston_down_pusher_normal 110 85 67 +mesecons_pistons:piston_down_pusher_sticky 110 85 67 +mesecons_pistons:piston_down_sticky_off 117 108 104 +mesecons_pistons:piston_down_sticky_on 117 108 104 +mesecons_pistons:piston_normal_off 123 111 103 +mesecons_pistons:piston_normal_on 123 111 103 +mesecons_pistons:piston_pusher_normal 110 85 67 +mesecons_pistons:piston_pusher_sticky 110 85 67 +mesecons_pistons:piston_sticky_off 123 111 103 +mesecons_pistons:piston_sticky_on 123 111 103 +mesecons_pistons:piston_up_normal_off 110 85 67 +mesecons_pistons:piston_up_normal_on 116 107 104 +mesecons_pistons:piston_up_pusher_normal 110 85 67 +mesecons_pistons:piston_up_pusher_sticky 103 84 65 +mesecons_pistons:piston_up_sticky_off 103 84 65 +mesecons_pistons:piston_up_sticky_on 116 107 104 + +# mesecons_pressureplates +mesecons_pressureplates:pressure_plate_acaciawood_off 153 103 71 +mesecons_pressureplates:pressure_plate_acaciawood_on 153 103 71 +mesecons_pressureplates:pressure_plate_birchwood_off 147 116 90 +mesecons_pressureplates:pressure_plate_birchwood_on 147 116 90 +mesecons_pressureplates:pressure_plate_darkwood_off 89 76 63 +mesecons_pressureplates:pressure_plate_darkwood_on 89 76 63 +mesecons_pressureplates:pressure_plate_junglewood_off 114 80 60 +mesecons_pressureplates:pressure_plate_junglewood_on 114 80 60 +mesecons_pressureplates:pressure_plate_sprucewood_off 82 66 54 +mesecons_pressureplates:pressure_plate_sprucewood_on 82 66 54 +mesecons_pressureplates:pressure_plate_stone_off 131 123 118 +mesecons_pressureplates:pressure_plate_stone_on 131 123 118 +mesecons_pressureplates:pressure_plate_wood_off 115 89 68 +mesecons_pressureplates:pressure_plate_wood_on 115 89 68 + +# mesecons_solarpanel +mesecons_solarpanel:solar_panel_inverted_off 118 132 149 +mesecons_solarpanel:solar_panel_inverted_on 118 132 149 +mesecons_solarpanel:solar_panel_off 150 141 130 +mesecons_solarpanel:solar_panel_on 150 141 130 + +# mesecons_torch +mesecons_torch:mesecon_torch_off 93 71 57 +mesecons_torch:mesecon_torch_off_wall 93 71 57 +mesecons_torch:mesecon_torch_on 104 72 58 +mesecons_torch:mesecon_torch_on_wall 104 72 58 +mesecons_torch:mesecon_torch_overheated 93 71 57 +mesecons_torch:mesecon_torch_overheated_wall 93 71 57 +mesecons_torch:redstoneblock 131 12 14 + +# mesecons_walllever +mesecons_walllever:wall_lever_off 110 100 95 +mesecons_walllever:wall_lever_on 110 100 95 + +# xpanes +xpanes:bar 157 148 148 64 16 +xpanes:bar_flat 157 148 148 64 16 +xpanes:pane_black 25 25 25 64 16 +xpanes:pane_black_flat 25 25 25 64 16 +xpanes:pane_blue 51 76 178 64 16 +xpanes:pane_blue_flat 51 76 178 64 16 +xpanes:pane_brown 102 76 51 64 16 +xpanes:pane_brown_flat 102 76 51 64 16 +xpanes:pane_cyan 76 127 153 64 16 +xpanes:pane_cyan_flat 76 127 153 64 16 +xpanes:pane_gray 76 76 76 64 16 +xpanes:pane_gray_flat 76 76 76 64 16 +xpanes:pane_green 102 127 51 64 16 +xpanes:pane_green_flat 102 127 51 64 16 +xpanes:pane_light_blue 102 153 216 64 16 +xpanes:pane_light_blue_flat 102 153 216 64 16 +xpanes:pane_lime 127 204 25 64 16 +xpanes:pane_lime_flat 127 204 25 64 16 +xpanes:pane_magenta 0 0 0 64 16 +xpanes:pane_magenta_flat 0 0 0 64 16 +xpanes:pane_natural 222 222 239 64 16 +xpanes:pane_natural_flat 222 222 239 64 16 +xpanes:pane_orange 216 127 51 64 16 +xpanes:pane_orange_flat 216 127 51 64 16 +xpanes:pane_pink 0 0 0 64 16 +xpanes:pane_pink_flat 0 0 0 64 16 +xpanes:pane_purple 127 63 178 64 16 +xpanes:pane_purple_flat 127 63 178 64 16 +xpanes:pane_red 153 51 51 64 16 +xpanes:pane_red_flat 153 51 51 64 16 +xpanes:pane_silver 153 153 153 64 16 +xpanes:pane_silver_flat 153 153 153 64 16 +xpanes:pane_white 255 255 255 64 16 +xpanes:pane_white_flat 255 255 255 64 16 +xpanes:pane_yellow 229 229 51 64 16 +xpanes:pane_yellow_flat 229 229 51 64 16 + diff --git a/tools/create_luacheck.py b/tools/create_luacheck.py index 8b55c1376..d3ee5d038 100755 --- a/tools/create_luacheck.py +++ b/tools/create_luacheck.py @@ -19,7 +19,7 @@ pathlist = Path(path).rglob('*.lua') for path in pathlist: path_in_str = str(path) # print(path_in_str) - trouve = False + found = False with open(path_in_str) as f: local_vars = [] for i, line in enumerate(f.readlines()): @@ -38,7 +38,7 @@ for path in pathlist: local_vars.append(n.group('local_var')) if not found: - nb_varloc = len(variables_locales) + nb_varloc = len(local_vars) #print(path_in_str, ": -", "({} variables locales)".format(nb_varloc) if nb_varloc > 0 else '') print(', '.join(['"{}"'.format(v) for v in global_vars])) diff --git a/tools/remove_end.py b/tools/remove_end.py deleted file mode 100644 index 3b73e5575..000000000 --- a/tools/remove_end.py +++ /dev/null @@ -1,46 +0,0 @@ -world_name = "world" -path_to_map_sqlite = "../../../worlds/" + world_name + "/map.sqlite" - -import sqlite3, sys - -try: - conn = sqlite3.connect(path_to_map_sqlite) -except Error as e: - print(e) - sys.exit() - -def unsignedToSigned(i, max_positive): - if i < max_positive: - return i - else: - return i - 2*max_positive - -cursor = conn.cursor() -cursor.execute("SELECT pos FROM blocks") -poses = cursor.fetchall() -end_blocks = [] -for i0 in (poses): - i = int(i0[0]) - blockpos = i - x = unsignedToSigned(i % 4096, 2048) - i = int((i - x) / 4096) - y = unsignedToSigned(i % 4096, 2048) - i = int((i - y) / 4096) - z = unsignedToSigned(i % 4096, 2048) - - node_pos_y = y * 16 - if node_pos_y > -28811 and node_pos_y + 15 < -67: - end_blocks.append(blockpos) - -if len(end_blocks) < 1: - print ("End blocks not found") - sys.exit() - -counter = 0 -for blockpos in end_blocks: - print("Deleting ", blockpos) - cursor.execute("DELETE FROM blocks WHERE pos=" + str(blockpos)) - counter += 1 -conn.commit() - -print(counter, " block(s) deleted")