Compare commits

..

55 Commits

Author SHA1 Message Date
AFCMS 2c82629cf6 Merge branch 'master' into chat-command-builder 2021-04-12 16:04:38 +02:00
AFCMS b891a13787 try to fix pattern 2021-04-12 15:48:13 +02:00
AFCMS 0c32c94f73 add basic command 2021-04-07 23:38:44 +02:00
AFCMS e463d16298 Merge branch 'master' into chat-command-builder 2021-04-07 19:34:54 +02:00
AFCMS 0a35714019 Merge branch 'master' into chat-command-builder 2021-04-07 10:40:33 +02:00
AFCMS 0a802a2cc1 Merge branch 'master' into chat-command-builder 2021-04-07 09:31:40 +02:00
AFCMS 5ade58f919 Merge branch 'master' into chat-command-builder 2021-04-07 09:23:14 +02:00
AFCMS 25495d2dcd attemp to fix pattern for quoted text 2021-04-06 23:02:04 +02:00
AFCMS e0fcfc1888 improve bossbar command (WIP) 2021-04-06 18:54:03 +02:00
AFCMS 698b107cb3 Merge branch 'master' into chat-command-builder 2021-04-06 17:25:22 +02:00
AFCMS b9c0dc80f3 Merge branch 'master' into chat-command-builder 2021-04-06 16:11:44 +02:00
AFCMS 43d398b0b2 setup not working bossbar command 2021-04-06 16:11:30 +02:00
AFCMS 163aa720c2 Merge branch 'master' into chat-command-builder 2021-04-06 16:01:38 +02:00
AFCMS e7d3939e28 Merge branch 'master' into chat-command-builder 2021-04-06 15:56:18 +02:00
AFCMS 6f0777d36d Merge branch 'master' into chat-command-builder 2021-04-06 14:51:00 +02:00
AFCMS 9b0f2c4cbf fix errors msg not beeing colored 2021-04-06 13:11:32 +02:00
AFCMS c307b5304f Merge branch 'master' into chat-command-builder 2021-04-06 13:02:17 +02:00
AFCMS 16529330dd fix /list command not beeing mc like 2021-04-06 13:02:04 +02:00
AFCMS 8eebdd3461 Merge branch 'master' into chat-command-builder 2021-04-06 11:18:01 +02:00
AFCMS 073707f53c Merge branch 'master' into chat-command-builder 2021-03-31 20:33:07 +02:00
AFCMS d7ac1b7cb5 fix bug 2021-03-31 19:41:37 +02:00
AFCMS d00a5c74d2 split commands code into separate files 2021-03-31 19:04:24 +02:00
AFCMS f9a03a3c98 add basic target selector 2021-03-31 17:16:59 +02:00
AFCMS 0c96ff672d remove unused code 2021-03-31 16:42:15 +02:00
AFCMS 46677a38ae Merge branch 'master' into chat-command-builder 2021-03-31 16:15:08 +02:00
AFCMS f8804c5e56 Merge branch 'master' into chat-command-builder 2021-03-30 22:28:16 +02:00
AFCMS 3137c86f67 Merge branch 'master' into chat-command-builder 2021-03-30 20:33:32 +02:00
AFCMS 2a28bf215d Merge branch 'master' into chat-command-builder 2021-03-16 10:28:03 +00:00
AFCMS 86f01eed75 try to fix a bug 2021-03-11 19:12:28 +01:00
AFCMS a51bbb6974 fix nodename pattern 2021-03-10 20:41:41 +01:00
AFCMS 11384bd73c fix nodename pattern and add debug command (do not work) 2021-03-10 19:35:23 +01:00
AFCMS 669a9ff0a4 remove (for now) unused params
temporary removed params need an engine change
https://github.com/minetest/minetest/pull/11022
2021-03-09 19:04:37 +01:00
AFCMS 783146f32e FIX THE STUPIDIEST BUG EVER 2021-03-09 18:42:53 +01:00
AFCMS 31e256e1e2 cleanup and fixes 2021-03-09 12:47:57 +01:00
AFCMS 5f00d47ec2 cleanup and fixes (WIP) 2021-03-09 10:15:27 +01:00
AFCMS 0d3147b13d add 2 more patterns types (WIP) 2021-03-09 00:57:13 +01:00
AFCMS a22188ccf4 refine some commands to match last changes 2021-03-09 00:47:01 +01:00
AFCMS f90243f6e5 add public API to properly (take care of mcl_builtin_commands_overide) rename and alias chat command 2021-03-09 00:34:33 +01:00
AFCMS 884097a8e5 add API documentation for mcl_commands 2021-03-09 00:00:21 +01:00
AFCMS 72ddaf33f6 move mcl_commands to core and add mcl_basic_commands 2021-03-08 23:35:34 +01:00
AFCMS 19e83fc2fb fixes 2021-03-08 23:27:39 +01:00
AFCMS 43c641f84f improve chat command definition 2021-03-08 22:48:44 +01:00
AFCMS 155548f384 refactor chat message then you haven't the required privs 2021-03-08 20:34:36 +01:00
AFCMS f7b832508f cleanup 2021-03-08 18:53:01 +01:00
AFCMS 9e7ec24c0e add log 2021-03-08 17:45:25 +01:00
AFCMS 5b5b525d32 fix title command 2021-03-08 17:05:17 +01:00
AFCMS e334665365 fix somethings 2021-03-08 17:01:11 +01:00
AFCMS 88a971fe6f fix stupid code duplication 2021-03-08 16:54:57 +01:00
AFCMS 5425a01097 fix message 2021-03-08 16:53:21 +01:00
AFCMS 1f5076cfd0 Add ability for sub commands to have special privs 2021-03-08 16:48:59 +01:00
AFCMS 7139ca1395 fix 2021-03-08 16:19:43 +01:00
AFCMS 84de4ea728 cleanup 2021-03-08 16:18:37 +01:00
AFCMS 59ab7e6ae6 add /title command 2021-03-08 16:15:52 +01:00
AFCMS d5874b4062 add credits 2021-03-08 16:05:26 +01:00
AFCMS d72fa76757 add basic API (basicaly chat command builder) 2021-03-08 14:47:49 +01:00
111 changed files with 1909 additions and 1756 deletions

View File

@ -7,11 +7,13 @@ But first, some things to note:
MineClone 2's development target is to make a free software clone of Minecraft, MineClone 2's development target is to make a free software clone of Minecraft,
***version 1.12***, ***PC edition***, *** + Optifine features supported by the Minetest Engine ***. ***version 1.12***, ***PC edition***, *** + Optifine features supported by the Minetest Engine ***.
MineClone 2 is maintained by three persons. Namely, kay27, EliasFleckenstein and jordan4ibanez. You can find us MineClone 2 is maintained by two persons. Namely, kay27 and EliasFleckenstein. You can find us
in the Minetest forums (forums.minetest.net), in IRC in the #mineclone2 in the Minetest forums (forums.minetest.net), in IRC in the #minetest
channel on irc.freenode.net. And finally, you can send e-mails to channel on irc.freenode.net. And finally, you can send e-mails to
<eliasfleckenstein@web.de> or <kay27@bk.ru>. <eliasfleckenstein@web.de> or <kay27@bk.ru>.
There is **no** guarantee we will accept anything from anybody.
By sending us patches or asking us to include your changes in this game, By sending us patches or asking us to include your changes in this game,
you agree that they fall under the terms of the LGPLv2.1, which basically you agree that they fall under the terms of the LGPLv2.1, which basically
means they will become part of a free software. means they will become part of a free software.
@ -24,7 +26,8 @@ For small and medium changes:
* Fork the repository * Fork the repository
* Do your change in a new branch * Do your change in a new branch
* Create a pull request to get your changes merged into master * Upload the repository somewhere where it can be accessed from the Internet and
notify us
For small changes, sending us a patch is also good. For small changes, sending us a patch is also good.
@ -38,30 +41,40 @@ reserve the right to revert everything that we don't like.
For bigger changes, we strongly recommend to use feature branches and For bigger changes, we strongly recommend to use feature branches and
discuss with me first. discuss with me first.
If your code causes bugs and crashes, it is your responsibility to fix them as soon as possible. Contributors will be credited in `README.md`.
We mostly use plain merging rather than rebasing or squash merging. ## Quality remarks
Again: There is ***no*** guarantee we will accept anything from anybody.
But we will gladly take in code from others when we feel it saves us work
in the long run.
Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue. ### Inclusion criteria
Depending on what you add, the chances for inclusion vary:
Contributors will be credited in `CREDITS.md`. ### High chance for inclusion
* Gameplay features in Minecraft which are missing in MineClone 2
## Features > 1.12 ### Medium chance for inclusion (discuss first)
* Features which don't a impact on gameplay
* GUI improvement
* Features from pocket or console edition
If you want to make a feature that was added in a Minecraft version later than 1.12, you should fork MineClone5 (mineclone5 branch in the repository) and add your changes to this. ### Low chance for inclusion (discuss/optimize first)
* Overhaul of architecture / mod structure
* Mass-itemstring changes all over the place
* Added files have a unusual high file size
* Indentation looks like crazy
* Single commits which add several unrelated things
* Gameplay features which don't exist in Minecraft
## What we accept ### Instant rejection
* Proprietary **anything**
* Code contains `minetest.env` anywhere
* Every MC features up to version 1.12 JE. ## Coding style guide
* Every already finished and working good features from versions above (only when making a MineClone5 PR / Contribution). * Indentations should reflect the code flow
* Except features which couldn't be done easily and bugfree because of Minetest engine limitations. Eg. we CAN extend world boundaries by playing with map chunks, just teleporting player onto next layer after 31000 , but it would cost too much (time, code, bugs, performance, stability, etc). * Use tabs, not spaces for indentation (tab size = 8)
* Some features, approved by the rest of the community, I mean maybe some voting and really missing any negative feedback. * Never use `minetest.env`
## What we reject
* Any features which cause critical bugs, sending them to rework/fix or trying to fix immediately.
* Some small portions of big entirely missing features which just definitely break gamplay balance give nothing useful
* Controversial features, which some people support while others do not should be discussed well, with publishing forum announcements, at least during the week. In case if there are still doubts - send them into the mod.
## Reporting bugs ## Reporting bugs
Report all bugs and missing Minecraft features here: Report all bugs and missing Minecraft features here:

View File

@ -1,117 +0,0 @@
# Credits
## Creator of MineClone
* davedevils
## Creator of MineClone2
* Wuzzy
## Maintainers
* Fleckenstein
* kay27
* oilboi
## Developers
* bzoss
* AFCMS
* epCode
* ryvnf
* iliekprogrammar
* MysticTempest
* Rootyjr
* Nicu
* aligator
* Code-Sploit
## Contributors
* Laurent Rocher
* HimbeerserverDE
* TechDudie
* Alexander Minges
* ArTee3
* ZeDique la Ruleta
* pitchum
* wuniversales
* Bu-Gee
* David McMackins II
* Nicholas Niro
* Wouters Dorian
* Blue Blancmange
* Jared Moody
* Li0n
* Midgard
* NO11
* Saku Laesvuori
* Yukitty
* ZedekThePD
* aldum
* dBeans
* nickolas360
* yutyo
* ztianyang
* j45
## MineClone5
* kay27
* Debiankaios
* epCode
* NO11
* j45
## Original Mod Authors
* Wuzzy
* Fleckenstein
* BlockMen
* TenPlus1
* PilzAdam
* ryvnf
* stujones11
* Arcelmi
* celeron55
* maikerumine
* GunshipPenguin
* Qwertymine3
* Rochambeau
* rubenwardy
* stu
* oilboi
* 4aiman
* Kahrl
* Krock
* UgnilJoZ
* lordfingle
* 22i
* bzoss
* kilbith
* xeranas
* kddekadenz
* sofar
* 4Evergreen4
* jordan4ibanez
* paramat
## 3D Models
* 22i
* tobyplowy
* epCode
## Textures
* XSSheep
* Wuzzy
* kingoscargames
* leorockway
* xMrVizzy
* yutyo
## Translations
* Wuzzy
* Rocher Laurent
* wuniversales
* kay27
* pitchum
## Special thanks
* celeron55 for creating Minetest
* Jordach for the jukebox music compilation from Big Freaking Dig
* The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game
* Notch and Jeb for being the major forces behind Minecraft

View File

@ -1,52 +0,0 @@
# Legal information
This is a fan game, not developed or endorsed by Mojang AB.
Copying is an act of love. Please copy and share! <3
Here's the detailed legalese for those who need it:
## License of source code
MineClone 2 (by kay27, EliasFleckenstein, Wuzzy, davedevils and countless others)
is an imitation of Minecraft.
MineClone 2 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License (in the LICENSE.txt file) for more
details.
In the mods you might find in the read-me or license
text files a different license. This counts as dual-licensing.
You can choose which license applies to you: Either the
license of MineClone 2 (GNU GPLv3) or the mod's license.
MineClone 2 is a direct continuation of the discontinued MineClone
project by davedevils.
Mod credits:
See `README.txt` or `README.md` in each mod directory for information about other authors.
For mods that do not have such a file, the license is the source code license
of MineClone 2 and the author is Wuzzy.
## License of media (textures and sounds)
No non-free licenses are used anywhere.
The textures, unless otherwise noted, are based on the Pixel Perfection resource pack for Minecraft 1.11,
authored by XSSheep. Most textures are verbatim copies, while some textures have been changed or redone
from scratch.
The glazed terracotta textures have been created by (MysticTempest)[https://github.com/MysticTempest].
Source: <https://www.planetminecraft.com/texture_pack/131pixel-perfection/>
License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)
The main menu images are release under: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
All other files, unless mentioned otherwise, fall under:
Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
http://creativecommons.org/licenses/by-sa/3.0/
See README.txt in each mod directory for detailed information about other authors.

View File

@ -0,0 +1,40 @@
# Missing features in Minetest to recreate Minecraft features
A side goal of the MineClone 2 project is to find any shortcomings of Minetest which make it impossible to recreate a Minecraft feature exactly.
This file lists some of the missing features in Minetest which MineClone 2 would require.
## No workaround possible
For these features, no easy Lua workaround could be found.
### Lua API
#### Tools/wielded item
- “Lock” hotbar for a brief time after using an item, making it impossible to switch item or to attach/mine/build until the delay is over (For eating with delay)
- Tool charging: Holding down the mouse and releasing it, applying a “power level” (For bow and arrows, more charge = higher arrow range) ([issue 5212](https://github.com/minetest/minetest/issues/5212))
- [Dual Wielding](http://minecraft.gamepedia.com/Dual_wield)
- Eating/drinking animation ([issue 2811](https://github.com/minetest/minetest/issues/2811))
#### Nodes
- Light level 15 for nodes (not sunlight)
- Nodes makes light level drop by 2 or or more per node ([issue 5209](https://github.com/minetest/minetest/issues/5209))
## Interface
- Inventory: Hold down right mouse button while holding an item stack to drop items into the slots as you move the mouse. Makes crafting MUCH faster
- Sneak+Leftclick on crafting output crafts as many items as possible and immediately puts it into the player inventory ([issue 5211](https://github.com/minetest/minetest/issues/5211))
- Sneak+click puts items in different inventories depending on the item type (maybe group-based)? Required for sneak-clicking to armor slots
## Workaround theoretically possible
For these features, a workaround (or hack ;-)) by using Lua is theoretically possible. But engine support would be clearly better, more performant, more reliable, etc.
### Lua API
#### Nodes
- Change walking speed on block (soul sand)
- Change jumping height on block (soul sand),
- Change object movement speed *through* a block, but for non-liquids (for cobweb)
- Add `on_walk_over` event
- Set frequency in which players lose breath. 2 seconds are hardcoded in Minetest, in Minecraft it's 1 second
- Set damage frequency of `damage_per_second`. In Minecraft many things damage players every half-second rather than every second
- Possible to damage players directly when they are with the head inside. This allows to add Minecraft-like suffocation
- Sneak+click on inventory slot should be able to put items into additional “fallback inventories” if the first inventory is full. Useful for large chests
#### Nice-to-haye
- Utility function to rotate pillar-like nodes, requiring only 3 possible orientations (X, Y, Z). Basically this is `minetest.rotate_node` but with less orientations; the purpur pillar would mess up if a mirrored rotation would be possible. This is already implemented in MCL2, See `mcl_util` for more infos

194
README.md
View File

@ -2,7 +2,7 @@
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
Developed by many people. Not developed or endorsed by Mojang AB. Developed by many people. Not developed or endorsed by Mojang AB.
Version: 0.72.0 (in development) Version: 0.71.0
### Gameplay ### Gameplay
You start in a randomly-generated world made entirely of cubes. You can explore You start in a randomly-generated world made entirely of cubes. You can explore
@ -65,8 +65,16 @@ map builders. They can not be obtained in-game or in the creative inventory.
Use the `/giveme` chat command to obtain them. See the in-game help for Use the `/giveme` chat command to obtain them. See the in-game help for
an explanation. an explanation.
#### Incomplete items
These items do not work yet, but you can get them with `/giveme` for testing:
* Minecart with Chest: `mcl_minecarts:chest_minecart`
* Minecart with Furnace: `mcl_minecarts:furnace_minecart`
* Minecart with Hopper: `mcl_minecarts:hopper_minecart`
* Minecart with Command Block: `mcl_minecarts:command_block_minecart`
## Installation ## Installation
This game requires [Minetest](http://minetest.net) to run (version 5.3.0 or This game requires [Minetest](http://minetest.net) to run (version 5.0.0 or
later). So you need to install Minetest first. Only stable versions of Minetest later). So you need to install Minetest first. Only stable versions of Minetest
are officially supported. are officially supported.
There is no support for running MineClone 2 in development versions of Minetest. There is no support for running MineClone 2 in development versions of Minetest.
@ -75,37 +83,23 @@ To install MineClone 2 (if you haven't already), move this directory into the
“games” directory of your Minetest data directory. Consult the help of “games” directory of your Minetest data directory. Consult the help of
Minetest to learn more. Minetest to learn more.
## Reporting bugs
Please report all bugs and missing Minecraft features here:
<https://git.minetest.land/MineClone2/MineClone2/issues>
## Chating with the community
Join our discord server at:
<https://discord.gg/84GKcxczG3>
## Project description ## Project description
The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software. The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software.
* **Target of development: Minecraft, PC Edition, version 1.12** (later known as “Java Edition”) * **Target of development: Minecraft, PC Edition, version 1.12** (later known as “Java Edition”)
* MineClone2 also includes Optifine features supported by the Minetest * MineClone2 also includes Optifine features supported by the Minetest
* In general, Minecraft is aimed to be cloned as good as possible * Features of later Minecraft versions might sneak in, but they have a low priority
* In general, Minecraft is aimed to be cloned as good as Minetest currently permits (no hacks)
* Cloning the gameplay has highest priority * Cloning the gameplay has highest priority
* MineClone 2 will use different assets, but with a similar style * MineClone 2 will use different graphics and sounds, but with a similar style
* Limitations found in Minetest will be documented in the course of development * Cloning the interface has no priority. It will only be roughly imitated
* Features of later Minecraft versions are collected in the mineclone5 branch * Limitations found in Minetest will be written down and reported in the course of development
## Using features from newer versions of Minecraft
For > 1.12 features, checkout MineClone5. It includes features from newer Minecraft versions.
Download it here: https://git.minetest.land/MineClone2/MineClone2/src/branch/mineclone5
## Completion status ## Completion status
This game is currently in **beta** stage. This game is currently in **alpha** stage.
It is playable, but not yet feature-complete. It is playable, but unfinished, many bugs are to be expected.
Backwards-compability is not entirely guaranteed, updating your world might cause small bugs. Backwards-compability is *not* guaranteed, updating your world might cause small and
If you want to use the git version of MineClone2 in production, consider using the production branch. big bugs (such as “missing node” errors or even crashes).
It is updated weekly and contains relatively stable code for servers.
The following main features are available: The following main features are available:
@ -134,7 +128,7 @@ The following main features are available:
* Clock * Clock
* Compass * Compass
* Sponge * Sponge
* Slime block * Slime block (does not interact with redstone)
* Small plants and saplings * Small plants and saplings
* Dyes * Dyes
* Banners * Banners
@ -146,19 +140,19 @@ The following main features are available:
* Creative inventory * Creative inventory
* Farming * Farming
* Writable books * Writable books
* Commands * A few server commands
* Villages
* The End
* And more! * And more!
The following features are incomplete: The following features are incomplete:
* Generated structures (especially villages)
* Some monsters and animals * Some monsters and animals
* Redstone-related things * Redstone-related things
* The End
* Special minecarts * Special minecarts
* A couple of non-trivial blocks and items * A couple of non-trivial blocks and items
Bonus features (not found in Minecraft 1.12): Bonus features (not found in Minecraft 1.11):
* Built-in crafting guide which shows you crafting and smelting recipes * Built-in crafting guide which shows you crafting and smelting recipes
* In-game help system containing extensive help about gameplay basics, blocks, items and more * In-game help system containing extensive help about gameplay basics, blocks, items and more
@ -183,14 +177,148 @@ Technical differences from Minecraft:
* Different textures (Pixel Perfection) * Different textures (Pixel Perfection)
* Different sounds (various sources) * Different sounds (various sources)
* Different engine (Minetest) * Different engine (Minetest)
* Different easter eggs
… and finally, MineClone 2 is free software (“free” as in “freedom”)! … and finally, MineClone 2 is free software (“free” as in “freedom”)!
## Reporting bugs
Please report all bugs and missing Minecraft features here:
<https://git.minetest.land/MineClone2/MineClone2/issues>
## Chating with the community
Join our discord server at:
<https://discord.gg/84GKcxczG3>
## Other readme files ## Other readme files
* `LICENSE.txt`: The GPLv3 license text * `LICENSE.txt`: The GPLv3 license text
* `CONTRIBUTING.md`: Information for those who want to contribute * `CONTRIBUTING.md`: Information for those who want to contribute
* `MISSING_ENGINE_FEATURES.md`: List of missing features in Minetest which MineClone 2 would need for improvement
* `API.md`: For Minetest modders who want to mod this game * `API.md`: For Minetest modders who want to mod this game
* `LEGAL.md`: Legal information
* `CREDITS.md`: List of everyone who contributed ## Credits
There are so many people to list (sorry). Check out the respective mod directories for details. This section is only a rough overview of the core authors of this game.
### Coding
* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082): Main programmer of most mods (retired)
* davedevils: Creator of MineClone on which MineClone 2 is based on
* [ex-bart](https://github.com/ex-bart): Redstone comparators
* [Rootyjr](https://github.com/Rootyjr): Fishing rod and bugfixes
* [aligator](https://github.com/aligator): Improvement of doors
* [ryvnf](https://github.com/ryvnf): Explosion mechanics
* MysticTempest: Bugfixes
* [bzoss](https://github.com/bzoss): Status effects, potions, brewing stand
* kay27 <kay27@bk.ru>: Experience system, bugfixes, optimizations (Current maintainer)
* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes (Current maintainer)
* epCode: Better player animations, new logo
* 2mac: Fix bug with powered rail
* Lots of other people: TO BE WRITTEN (see mod directories for details)
#### Mod credits (summary)
* `controls`: Arcelmi
* `flowlib`: Qwertymine13
* `walkover`: lordfingle
* `drippingwater`: kddekadenz
* `mobs_mc`: maikerumine, 22i and others
* `awards`: rubenwardy
* `screwdriver`: RealBadAngel, Maciej Kastakin, Minetest contributors
* `xpanes`: Minetest contributors
* `mesecons` mods: Jeija and contributors
* `wieldview`: Stuart Jones
* `mcl_meshhand`: Based on `newhand` by jordan4ibanez
* `mcl_mobs`: Based on Mobs Redo [`mobs`] by TenPlus1 and contributors
* Most other mods: Wuzzy
Detailed credits for each mod can be found in the individual mod directories.
### Graphics
* [XSSheep](http://www.minecraftforum.net/members/XSSheep): Main author; creator of the Pixel Perfection resource pack of Minecraft 1.11
* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082): Main menu imagery and various edits and additions of texture pack
* [kingoscargames](https://github.com/kingoscargames): Various edits and additions of existing textures
* [leorockway](https://github.com/leorockway): Some edits of mob textures
* [xMrVizzy](https://minecraft.curseforge.com/members/xMrVizzy): Glazed terracotta (textures are subject to be replaced later)
* yutyo <tanakinci2002@gmail.com>: MineClone 2 logo
* Other authors: GUI images
### Translations
* Wuzzy: German
* Rocher Laurent <rocherl@club-internet.fr>: French
* wuniversales: Spanish
* kay27 <kay27@bk.ru>: Russian
### Models
* [22i](https://github.com/22i): Creator of all models
* [tobyplowy](https://github.com/tobyplowy): UV-mapping fixes to said models
### Sounds and music
Various sources. See the respective mod directories for details.
### Special thanks
* davedevils for starting MineClone, the original version of this game
* Wuzzy for starting and maintaining MineClone2 for several years
* celeron55 for creating Minetest
* Minetest's modding community for providing a huge selection of mods, some of which ended up in MineClone 2
* Jordach for the jukebox music compilation from Big Freaking Dig
* The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game
* Notch and Jeb for being the major forces behind Minecraft
* XSSheep for creating the Pixel Perfection resource pack
* [22i](https://github.com/22i) for providing great models and support
* [maikerumine](http://github.com/maikerumine) for kicking off mobs and biomes
## Info for programmers
You find interesting and useful infos in `API.md`.
## Legal information
This is a fan game, not developed or endorsed by Mojang AB.
Copying is an act of love. Please copy and share! <3
Here's the detailed legalese for those who need it:
### License of source code
MineClone 2 (by kay27, EliasFleckenstein, Wuzzy, davedevils and countless others)
is an imitation of Minecraft.
MineClone 2 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License (in the LICENSE.txt file) for more
details.
In the mods you might find in the read-me or license
text files a different license. This counts as dual-licensing.
You can choose which license applies to you: Either the
license of MineClone 2 (GNU GPLv3) or the mod's license.
MineClone 2 is a direct continuation of the discontinued MineClone
project by davedevils.
Mod credits:
See `README.txt` or `README.md` in each mod directory for information about other authors.
For mods that do not have such a file, the license is the source code license
of MineClone 2 and the author is Wuzzy.
### License of media (textures and sounds)
No non-free licenses are used anywhere.
The textures, unless otherwise noted, are based on the Pixel Perfection resource pack for Minecraft 1.11,
authored by XSSheep. Most textures are verbatim copies, while some textures have been changed or redone
from scratch.
The glazed terracotta textures have been created by (MysticTempest)[https://github.com/MysticTempest].
Source: <https://www.planetminecraft.com/texture_pack/131pixel-perfection/>
License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)
The main menu images are release under: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
All other files, unless mentioned otherwise, fall under:
Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
http://creativecommons.org/licenses/by-sa/3.0/
See README.txt in each mod directory for detailed information about other authors.

View File

@ -0,0 +1,74 @@
# API documentation of mcl_commands
The mcl_commands API allows you to register and overide complex commands.
This mod is derivated from ChatCommandBuilder by rubenwardy
Some public functions are not documented here but they are for internal use only.
## Technical differences from ChatCommandBuilder
* subcommand aditional specific privs
* new types: `json`, `color`, `nodename` an maybe more in the future
## Public Functions
### `mcl_commands.register_command("exemple", def)`
This is a function which is called when an item is dispensed by the dispenser.
These are the parameters:
```
mcl_commands.register_command("exemple", {
func = function(cmd) --function executed on registration
cmd:sub(":name:username title :params:json", { --create a new subcommand called "title" with defined patterns
func = function(name, target, json)
return a_cool_function(target, json) --function executed if the params match the patterns
end,
privs = {settime = true}, --subcommand aditional specific privs
})
end,
description = "Controls text displayed on the screen.", --the description of the command
params = "<target> command <params>", --very basic explaination of the syntax of the command (will be semi-automatic in the future)
privs = {server = true}, --global privs
})
```
Register a complex chatcommand. If a chat command with the same name is already registered, the program will fail.
### `mcl_commands.overide_command("exemple", def)`
Same as above but will overide existing command.
### `mcl_commands.register_chatcommand_alias(alias, cmd, [bypass])`
Register an alias called `alias` of the `cmd` command.
If the setting `mcl_builtin_commands_overide` is set to `false`, the function will silently fail.
If `bypass` is set to `true` the function will not take care of the above setting.
Will warn if trying to alias to already existing command.
### `mcl_commands.rename_chatcommand(newname, cmd, [bypass])`
Rename `cmd` command to `newname`.
If the setting `mcl_builtin_commands_overide` is set to `false`, the function will silently fail.
If `bypass` is set to `true` the function will not take care of the above setting.
Will warn if trying to rename to already existing command.
### paterns
mcl_commands adds many types for patterns
If not specified, a value will be by default with the word pattern.
* pos value must be pos
* text value must be text WARNING: this pattern must be the last pattern of the subcommand!!
* number value must be number
* int value must be integer
* word value must be word
* alpha value must be alphanumeric
* modname value must be a valid modname
* alphascore
* alphanumeric
* username: value must be a valid username
* json: value must be a json string (will be parsed automaticaly)
* color value must be a color string or a valid named color
* nodename value must be a valid (existing) node or item name

View File

@ -0,0 +1,374 @@
local S = minetest.get_translator("mcl_commands")
local C = minetest.colorize
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
local parse_json = minetest.parse_json
local get_modpath = minetest.get_modpath
mcl_commands.types = {
pos = {"%(? *(%-?[%d.]+) *,? *(%-?[%d.]+) *,? *(%-?[%d.]+) *%)?",
function(res, pointer)
local pos = {
x = tonumber(res[pointer]),
y = tonumber(res[pointer + 1]),
z = tonumber(res[pointer + 2])
}
if pos.x and pos.y and pos.z then
return nil, pos, pointer+3
else
return S("Pos is invalid!")
end
end},
text = {"(.+)",
function(res, pointer)
if res[pointer] == tostring(res[pointer]) then
return nil, res[pointer], pointer+1
else
return S("Text is invalid!")
end
end},
number = {"(%-?[%d.]+)}",
function(res, pointer)
if res[pointer] == tonumber(res[pointer]) then
return nil, tonumber(res[pointer]), pointer+1
else
return S("Number is invalid!")
end
end},
int = {"(%-?[%d]+)}",
function(res, pointer)
if res[pointer] == math.floor(tonumber(res[pointer])) then
return nil, tonumber(res[pointer]), pointer+1
else
return S("Int is invalid!")
end
end},
word = {"([^ ]+)",
function(res, pointer)
if res[pointer] == tostring(res[pointer]) then
return nil, tostring(res[pointer]), pointer+1
else
return S("Word is invalid!")
end
end},
quotestring = {'"+(.-)"+',
function(res, pointer)
if res[pointer] == tostring(res[pointer]) then
return nil, string.sub(tostring(res[pointer]), 2, #res[pointer]-1), pointer+1
else
return S("String is invalid!")
end
end},
alpha = {"([A-Za-z]+)}",
function(res, pointer)
if res[pointer] then
return nil, res[pointer], pointer+1
else
return S("Alpha is invalid!")
end
end},
modname = {"([a-z0-9_]+)}",
function(res, pointer)
if get_modpath(res[pointer]) then
return nil, res[pointer], pointer+1
else
return S("Modname is invalid!")
end
end},
alphascore = {"([A-Za-z_]+)",
function(res, pointer)
if res[pointer] then --What is alphascore?
return nil, res[pointer], pointer+1
else
return S("Alphascore is invalid!")
end
end},
alphanumeric = {"([A-Za-z0-9]+)}",
function(res, pointer)
if res[pointer] then --What is alphanumerical?
return nil, res[pointer], pointer+1
else
return S("Alphanumerical is invalid!")
end
end},
username = {"([A-Za-z0-9-_]+)",
function(res, pointer)
--if minetest.player_exists(res[pointer]) then
if res[pointer] then
return nil, res[pointer], pointer+1
else
return S("Player doesn't exist.")
end
end},
target = {"([A-Za-z0-9-_]+)",
function(res, pointer)
--if minetest.player_exists(res[pointer]) then
if res[pointer] then
return nil, res[pointer], pointer+1
else
return S("Player doesn't exist.")
end
end},
json = {"(.+)", --FIXME
function(res, pointer)
local parsed = parse_json(res[pointer])
if parsed then
return nil, parsed, pointer+1
else
return S("Json failed to parse!")
end
end},
color = {"([^ ]+)", --FIXME
function(res, pointer)
local color = mcl_util.get_color(res[pointer])
if color then
return nil, color, pointer+1
else
return S("Color is not a valid color name or hexadecimal!")
end
end},
nodename = {"(%l+[%w_]+%:?[_%l]+[%w_]*)",
function(res, pointer)
if minetest.registered_items[res[pointer]] then
return nil, res[pointer], pointer+1
else
return S("Nodename is invalid")
end
end},
}
function mcl_commands.register_command(name, def)
def = def or {}
local cmd = mcl_commands.build(name, def)
if minetest.registered_chatcommands[name] then
error("[mcl_commands] Failed to register command: ["..name.."] command already existing! Use mcl_commands.overide_command() if you want to overide existing command")
end
minetest.register_chatcommand(name, cmd)
minetest.log("action", "[mcl_commands] ["..name.."] command registered successfully")
return cmd
end
function mcl_commands.override_command(name, def)
def = def or {}
local cmd = mcl_commands.build(name, def)
if minetest.registered_chatcommands[name] then
minetest.unregister_chatcommand(name)
end
minetest.register_chatcommand(name, cmd)
minetest.log("action", "[mcl_commands] ["..name.."] command overridden successfully")
return cmd
end
local STATE_READY = 1
local STATE_PARAM = 2
local STATE_PARAM_TYPE = 3
local bad_chars = {"(", ")", ".", "%", "+", "-", "*", "?", "[", "^", "$"}
local function escape(char)
if bad_chars[char] then
return "%" .. char
else
return char
end
end
local dprint = function() end
function mcl_commands.build(name, chat_def)
local cmd = {
_subs = {}
}
function cmd:sub(route, def)
dprint("Parsing " .. route)
if string.trim then
route = string.trim(route)
end
local sub = {
pattern = "^",
params = {},
func = def.func,
privs = def.privs or {},
desc = def.desc,
params_desc = def.params or "",
}
-- End of param reached: add it to the pattern
local param = ""
local param_type = ""
local should_be_eos = false
local function finishParam()
if param ~= "" and param_type ~= "" then
dprint(" - Found param " .. param .. " type " .. param_type)
local pattern = mcl_commands.types[param_type][1]
if not pattern then
error("Unrecognised param_type=" .. param_type)
end
sub.pattern = sub.pattern .. pattern
table.insert(sub.params, param_type)
param = ""
param_type = ""
end
end
-- Iterate through the route to find params
local state = STATE_READY
local catching_space = false
local match_space = " " -- change to "%s" to also catch tabs and newlines
local catch_space = match_space.."+"
for i = 1, #route do
local c = route:sub(i, i)
if should_be_eos then
error("Should be end of string. Nothing is allowed after a param of type text.")
end
if state == STATE_READY then
if c == ":" then
dprint(" - Found :, entering param")
state = STATE_PARAM
param_type = "word"
catching_space = false
elseif c:match(match_space) then
print(" - Found space")
if not catching_space then
catching_space = true
sub.pattern = sub.pattern .. catch_space
end
else
catching_space = false
sub.pattern = sub.pattern .. escape(c)
end
elseif state == STATE_PARAM then
if c == ":" then
dprint(" - Found :, entering param type")
state = STATE_PARAM_TYPE
param_type = ""
elseif c:match(match_space) then
print(" - Found whitespace, leaving param")
state = STATE_READY
finishParam()
catching_space = true
sub.pattern = sub.pattern .. catch_space
elseif c:match("%W") then
dprint(" - Found nonalphanum, leaving param")
state = STATE_READY
finishParam()
sub.pattern = sub.pattern .. escape(c)
else
param = param .. c
end
elseif state == STATE_PARAM_TYPE then
if c:match(match_space) then
print(" - Found space, leaving param type")
state = STATE_READY
finishParam()
catching_space = true
sub.pattern = sub.pattern .. catch_space
elseif c:match("%W") then
dprint(" - Found nonalphanum, leaving param type")
state = STATE_READY
finishParam()
sub.pattern = sub.pattern .. escape(c)
else
param_type = param_type .. c
end
end
end
dprint(" - End of route")
finishParam()
sub.pattern = sub.pattern .. "$"
dprint("Pattern: " .. sub.pattern)
table.insert(self._subs, sub)
end
if chat_def.func then
chat_def.func(cmd)
end
cmd.func = function(name, param)
local msg
for i = 1, #cmd._subs do
local sub = cmd._subs[i]
local res = { string.match(param, sub.pattern) }
if #res > 0 then
local pointer = 1
local params = { name }
for j = 1, #sub.params do
local param = sub.params[j]
local value
if mcl_commands.types[param] then
msg, value, pointer = mcl_commands.check_type(param, res, pointer)
table.insert(params, value)
else
table.insert(params, res[pointer])
pointer = pointer + 1
end
end
local can_execute, missing_privs = minetest.check_player_privs(name, sub.privs)
if can_execute then
if table.unpack then
-- lua 5.2 or later
return sub.func(table.unpack(params))
else
-- lua 5.1 or earlier
return sub.func(unpack(params))
end
else
local missing_privs_str = ""
for i = 1, #missing_privs do
if not i == #missing_privs then
missing_privs_str = missing_privs_str..missing_privs[i].." "
else
missing_privs_str = missing_privs_str..missing_privs[i]
end
end
return false, C(mcl_colors.RED, S("You don't have permission to run this command (missing privilege: "..missing_privs_str..")"))
end
end
end
return false, C(mcl_colors.RED, msg)
end
if chat_def.params then
cmd.params = chat_def.params
else
cmd.params = ""
end
cmd.privs = chat_def.privs
cmd.description = chat_def.description
return cmd
end
function mcl_commands.check_type(type, res, pointer)
return mcl_commands.types[type][2](res, pointer)
end
function mcl_commands.register_chatcommand_alias(alias, cmd, bypass)
if not bypass then bypass = false end
if minetest.registered_chatcommands[alias] then
minetest.log("warning", "[mcl_commands] trying to alias ["..cmd.."] to already existing ["..alias.."] command")
elseif minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass then
minetest.register_chatcommand(alias, minetest.chatcommands[cmd])
minetest.log("action", "[mcl_commands] ["..cmd.."] command aliased successfully to ["..alias.."]")
else
minetest.log("action", "[mcl_commands] ["..cmd.."] command not aliased to ["..alias.."]")
end
end
function mcl_commands.rename_chatcommand(newname, cmd, bypass)
if not bypass then bypass = false end
if minetest.registered_chatcommands[newname] then
minetest.log("warning", "[mcl_commands] trying to rename ["..cmd.."] to already existing ["..alias.."] command")
elseif minetest.settings:get_bool("mcl_builtin_commands_overide", true) or bypass then
minetest.register_chatcommand(newname, minetest.chatcommands[cmd])
minetest.unregister_chatcommand(cmd)
minetest.log("action", "[mcl_commands] ["..cmd.."] command renamed successfully to ["..newname.."]")
else
minetest.log("action", "[mcl_commands] ["..cmd.."] command not renamed to ["..newname.."]")
end
end

View File

@ -0,0 +1,13 @@
--mcl_commands
--derivated from ChatCommandBuilder by @rubenwardy
local S = minetest.get_translator("mcl_commands")
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
local modpath = minetest.get_modpath(minetest.get_current_modname())
mcl_commands = {}
dofile(modpath.."/api.lua")
dofile(modpath.."/utils.lua")

View File

@ -0,0 +1,6 @@
name = mcl_commands
author = AFCMS
description = MCL2 commands API
depends = mcl_colors, mcl_util
optional_depends =

View File

@ -0,0 +1,38 @@
local S = minetest.get_translator("mcl_commands")
function mcl_commands.get_target_selector(target, pos, name)
if minetest.player_exists(target) then
return nil, minetest.get_player_by_name(target)
elseif target == "@a" then
return nil, minetest.get_connected_players()
elseif target == "@r" then
local connected = minetest.get_connected_players()
return nil, connected[math.random(1, #connected)]
elseif target == "@s" then
if name then
local player = minetest.get_player_by_name(name)
end
if player then
return nil, player
else
return S("Not a valid player")
end
elseif target == "@p" then
local smallest = math.huge
local nearest
for _,player in pairs(minetest.get_connected_players()) do
local distance = vector.distance(pos, player:get_pos())
if distance < min_distance then
min_distance = distance
nearest = player
end
end
if nearest then
return nil, nearest
else
return S("No player online")
end
elseif target == "@e" then
return minetest.luaentities --TODO: add filtering of not valid entities.
end
end

View File

@ -66,58 +66,3 @@ function mcl_particles.delete_node_particlespawners(pos)
end end
return false return false
end end
-- 3 exptime variants because the animation is not tied to particle expiration time.
-- 3 colorized variants to imitate minecraft's
local smoke_pdef_cached = {}
function mcl_particles.spawn_smoke(pos, name, smoke_pdef_base)
local min = math.min
local new_minpos = vector.add(pos, smoke_pdef_base.minrelpos)
local new_maxpos = vector.add(pos, smoke_pdef_base.maxrelpos)
-- populate the cache
if smoke_pdef_cached[name] then
for i, smoke_pdef in ipairs(smoke_pdef_cached[name]) do
smoke_pdef.minpos = new_minpos
smoke_pdef.maxpos = new_maxpos
mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high")
end
-- cache already populated
else
smoke_pdef_cached[name] = {}
local smoke_pdef = table.copy(smoke_pdef_base)
smoke_pdef.amount = smoke_pdef_base.amount / 9
smoke_pdef.time = 0
smoke_pdef.animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
-- length = 3 exptime variants
}
smoke_pdef.collisiondetection = true
smoke_pdef.minpos = new_minpos
smoke_pdef.maxpos = new_maxpos
-- the last frame plays for 1/8 * N seconds, so we can take advantage of it
-- to have varying exptime for each variant.
local exptimes = { 0.175, 0.375, 1.0 }
local colorizes = { "199", "209", "243" } -- round(78%, 82%, 90% of 256) - 1
for _,exptime in ipairs(exptimes) do
for _,colorize in ipairs(colorizes) do
smoke_pdef.maxexptime = exptime * smoke_pdef_base.maxexptime
smoke_pdef.animation.length = exptime + 0.1
-- minexptime must be set such that the last frame is actully rendered,
-- even if its very short. Larger exptime -> larger range
smoke_pdef.minexptime = min(exptime, (7.0/8.0 * (exptime + 0.1) + 0.1))
smoke_pdef.texture = "mcl_particles_smoke_anim.png^[colorize:#000000:" ..colorize
mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high")
table.insert(smoke_pdef_cached[name], table.copy(smoke_pdef))
end
end
end
end

View File

@ -0,0 +1,11 @@
mcl_util.registered_blacklisted_entities = {}
function mcl_util.register_blacklisted_entities(type)
mcl_util.registered_blacklisted_entities[type] = true
end
function mcl_util.get_real_entities()
for key, val in pairs(minetest.luaentities) do
local def = minetest.registered_entities[minetest.luaentities[key].name]
if not mcl_util.registered_blacklisted_entities[def.type] then
end
end
end

View File

@ -1,3 +1,5 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
mcl_util = {} mcl_util = {}
-- Based on minetest.rotate_and_place -- Based on minetest.rotate_and_place
@ -418,3 +420,5 @@ function mcl_util.get_color(colorstr)
return colorstr, hex return colorstr, hex
end end
end end
dofile(modpath.."/entities.lua")

View File

@ -323,7 +323,7 @@ mobs:register_mob("mobs_mc:enderman", {
-- self:teleport(nil) -- self:teleport(nil)
-- self.state = "" -- self.state = ""
--else --else
if self.attack ~= nil and not minetest.settings:get_bool("creative_mode") then if self.attack ~= nil then
self.state = 'attack' self.state = 'attack'
end end
--end --end

View File

@ -30,14 +30,13 @@ local skeleton = {
"mcl_bows_bow_0.png", -- bow "mcl_bows_bow_0.png", -- bow
"mobs_mc_skeleton.png", -- skeleton "mobs_mc_skeleton.png", -- skeleton
} }, } },
visual_size = {x=1, y=1}, visual_size = {x=3, y=3},
makes_footstep_sound = true, makes_footstep_sound = true,
textures = { sounds = {
{ random = "mobs_mc_skeleton_random",
"mobs_mc_empty.png", -- armor death = "mobs_mc_skeleton_death",
"mobs_mc_skeleton.png", -- texture damage = "mobs_mc_skeleton_hurt",
"mcl_bows_bow_0.png", -- wielded_item distance = 16,
}
}, },
walk_velocity = 1.2, walk_velocity = 1.2,
run_velocity = 2.4, run_velocity = 2.4,
@ -112,9 +111,9 @@ local stray = table.copy(skeleton)
stray.mesh = "mobs_mc_stray.b3d" stray.mesh = "mobs_mc_stray.b3d"
stray.textures = { stray.textures = {
{ {
"mobs_mc_stray_overlay.png",
"mobs_mc_stray.png",
"mcl_bows_bow_0.png", "mcl_bows_bow_0.png",
"mobs_mc_stray.png",
"mobs_mc_stray_overlay.png",
}, },
} }
-- TODO: different sound (w/ echo) -- TODO: different sound (w/ echo)
@ -141,8 +140,8 @@ mobs:register_mob("mobs_mc:stray", stray)
-- Overworld spawn -- Overworld spawn
mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:skeleton", "mobs_mc:skeleton",
"overworld", "overworld",
"ground", "ground",
{ {
"Mesa", "Mesa",
@ -285,36 +284,36 @@ mobs:spawn_specific(
"ExtremeHillsM_underground", "ExtremeHillsM_underground",
"JungleEdgeM_underground", "JungleEdgeM_underground",
}, },
0, 0,
7, 7,
20, 20,
17000, 17000,
2, 2,
mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max) mobs_mc.spawn_height.overworld_max)
-- Nether spawn -- Nether spawn
mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:skeleton", "mobs_mc:skeleton",
"nether", "nether",
"ground", "ground",
{ {
"Nether" "Nether"
}, },
0, 0,
7, 7,
30, 30,
10000, 10000,
3, 3,
mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max) mobs_mc.spawn_height.nether_max)
-- Stray spawn -- Stray spawn
-- TODO: Spawn directly under the sky -- TODO: Spawn directly under the sky
mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:stray", "mobs_mc:stray",
"overworld", "overworld",
"ground", "ground",
{ {
"ColdTaiga", "ColdTaiga",
@ -322,12 +321,12 @@ mobs:spawn_specific(
"IcePlains", "IcePlains",
"ExtremeHills+_snowtop", "ExtremeHills+_snowtop",
}, },
0, 0,
7, 7,
20, 20,
19000, 19000,
2, 2,
mobs_mc.spawn_height.water, mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max) mobs_mc.spawn_height.overworld_max)

View File

@ -25,12 +25,11 @@ mobs:register_mob("mobs_mc:witherskeleton", {
mesh = "mobs_mc_witherskeleton.b3d", mesh = "mobs_mc_witherskeleton.b3d",
textures = { textures = {
{ {
"mobs_mc_empty.png", -- armor
"mobs_mc_wither_skeleton.png", -- wither skeleton
"default_tool_stonesword.png", -- sword "default_tool_stonesword.png", -- sword
"mobs_mc_wither_skeleton.png", -- wither skeleton
} }
}, },
visual_size = {x=1.2, y=1.2}, visual_size = {x=3.6, y=3.6},
makes_footstep_sound = true, makes_footstep_sound = true,
sounds = { sounds = {
random = "mobs_mc_skeleton_random", random = "mobs_mc_skeleton_random",
@ -111,4 +110,4 @@ mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max) mobs_mc.spawn_height.nether_max)
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)

View File

@ -58,11 +58,7 @@ local zombie = {
visual = "mesh", visual = "mesh",
mesh = "mobs_mc_zombie.b3d", mesh = "mobs_mc_zombie.b3d",
textures = { textures = {
{ {"mobs_mc_zombie.png"},
"mobs_mc_empty.png", -- armor
"mobs_mc_zombie.png", -- texture
"mobs_mc_empty.png", -- wielded_item
}
}, },
visual_size = {x=3, y=3}, visual_size = {x=3, y=3},
makes_footstep_sound = true, makes_footstep_sound = true,
@ -115,13 +111,7 @@ mobs:register_mob("mobs_mc:baby_zombie", baby_zombie)
-- Husk. -- Husk.
-- Desert variant of the zombie -- Desert variant of the zombie
local husk = table.copy(zombie) local husk = table.copy(zombie)
husk.textures = { husk.textures = {{"mobs_mc_husk.png"}}
{
"mobs_mc_empty.png", -- armor
"mobs_mc_husk.png", -- texture
"mobs_mc_empty.png", -- wielded_item
}
}
husk.ignited_by_sunlight = false husk.ignited_by_sunlight = false
husk.sunlight_damage = 0 husk.sunlight_damage = 0
husk.drops = drops_common husk.drops = drops_common
@ -146,8 +136,8 @@ mobs:register_mob("mobs_mc:baby_husk", baby_husk)
-- Spawning -- Spawning
mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:zombie", "mobs_mc:zombie",
"overworld", "overworld",
"ground", "ground",
{ {
"FlowerForest_underground", "FlowerForest_underground",
@ -230,17 +220,17 @@ mobs:spawn_specific(
"MesaBryce_sandlevel", "MesaBryce_sandlevel",
"Mesa_sandlevel", "Mesa_sandlevel",
}, },
0, 0,
7, 7,
30, 30,
6000, 6000,
4, 4,
mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max) mobs_mc.spawn_height.overworld_max)
-- Baby zombie is 20 times less likely than regular zombies -- Baby zombie is 20 times less likely than regular zombies
mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:baby_zombie", "mobs_mc:baby_zombie",
"overworld", "overworld",
"ground", "ground",
{ {
"FlowerForest_underground", "FlowerForest_underground",
@ -323,18 +313,18 @@ mobs:spawn_specific(
"MesaBryce_sandlevel", "MesaBryce_sandlevel",
"Mesa_sandlevel", "Mesa_sandlevel",
}, },
0, 0,
7, 7,
30, 30,
60000, 60000,
4, 4,
mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max) mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:husk", "mobs_mc:husk",
"overworld", "overworld",
"ground", "ground",
{ {
"Desert", "Desert",
@ -342,29 +332,29 @@ mobs:spawn_specific(
"Savanna", "Savanna",
"Savanna_beach", "Savanna_beach",
}, },
0, 0,
7, 7,
30, 30,
6500, 6500,
4, 4,
mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max) mobs_mc.spawn_height.overworld_max)
mobs:spawn_specific( mobs:spawn_specific(
"mobs_mc:baby_husk", "mobs_mc:baby_husk",
"overworld", "overworld",
"ground", "ground",
{ {
"Desert", "Desert",
"SavannaM", "SavannaM",
"Savanna", "Savanna",
"Savanna_beach", "Savanna_beach",
}, },
0, 0,
7, 7,
30, 30,
65000, 65000,
4, 4,
mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max) mobs_mc.spawn_height.overworld_max)
-- Spawn eggs -- Spawn eggs

View File

@ -39,7 +39,7 @@ local last_id = 0
function mcl_bossbars.add_bar(player, def, dynamic, priority) function mcl_bossbars.add_bar(player, def, dynamic, priority)
local name = player:get_player_name() local name = player:get_player_name()
local bars = mcl_bossbars.bars[name] local bars = mcl_bossbars.bars[name]
local bar = {text = def.text, priority = priority or 0, timeout = def.timeout} local bar = {text = def.text, priority = priority or 0}
bar.color, bar.image = get_color_info(def.color, def.percentage) bar.color, bar.image = get_color_info(def.color, def.percentage)
if dynamic then if dynamic then
for _, other in pairs(bars) do for _, other in pairs(bars) do
@ -65,7 +65,7 @@ function mcl_bossbars.add_bar(player, def, dynamic, priority)
end end
function mcl_bossbars.remove_bar(id) function mcl_bossbars.remove_bar(id)
mcl_bossbars.static[id].id = nil mcl_bossbars.static[id].bar.id = nil
mcl_bossbars.static[id] = nil mcl_bossbars.static[id] = nil
end end
@ -119,7 +119,7 @@ minetest.register_on_leaveplayer(function(player)
mcl_bossbars.bars[name] = nil mcl_bossbars.bars[name] = nil
end) end)
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function()
for _, player in pairs(minetest.get_connected_players()) do for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name() local name = player:get_player_name()
local bars = mcl_bossbars.bars[name] local bars = mcl_bossbars.bars[name]
@ -134,12 +134,7 @@ minetest.register_globalstep(function(dtime)
local hud = table.remove(huds, 1) local hud = table.remove(huds, 1)
if bar and bar.id then if bar and bar.id then
if bar.timeout then table.insert(bars_new, bar)
bar.timeout = bar.timeout - dtime
end
if not bar.timeout or bar.timeout > 0 then
table.insert(bars_new, bar)
end
end end
if bar and not hud then if bar and not hud then

View File

@ -27,9 +27,9 @@ mcl_credits.people = {
"Rootyjr", "Rootyjr",
"Nicu", "Nicu",
"aligator", "aligator",
"Code-Sploit",
}}, }},
{"Contributors", 0x52FF00, { {"Contributors", 0x52FF00, {
"Code-Sploit",
"Laurent Rocher", "Laurent Rocher",
"HimbeerserverDE", "HimbeerserverDE",
"TechDudie", "TechDudie",
@ -55,7 +55,6 @@ mcl_credits.people = {
"nickolas360", "nickolas360",
"yutyo", "yutyo",
"ztianyang", "ztianyang",
"j45",
}}, }},
{"MineClone5", 0xA60014, { {"MineClone5", 0xA60014, {
"kay27", "kay27",
@ -64,38 +63,6 @@ mcl_credits.people = {
"NO11", "NO11",
"j45", "j45",
}}, }},
{"Original Mod Authors", 0x343434, {
"Wuzzy",
"Fleckenstein",
"BlockMen",
"TenPlus1",
"PilzAdam",
"ryvnf",
"stujones11",
"Arcelmi",
"celeron55",
"maikerumine",
"GunshipPenguin",
"Qwertymine3",
"Rochambeau",
"rubenwardy",
"stu",
"oilboi",
"4aiman",
"Kahrl",
"Krock",
"UgnilJoZ",
"lordfingle",
"22i",
"bzoss",
"kilbith",
"xeranas",
"kddekadenz",
"sofar",
"4Evergreen4",
"jordan4ibanez",
"paramat",
}},
{"3D Models", 0x0019FF, { {"3D Models", 0x0019FF, {
"22i", "22i",
"tobyplowy", "tobyplowy",

View File

@ -117,90 +117,83 @@ minetest.register_craft({
{"mcl_core:stick"},} {"mcl_core:stick"},}
}) })
local off_def = { mcl_torches.register_torch("mesecon_torch_off", S("Redstone Torch (off)"),
name = "mesecon_torch_off", nil,
description = S("Redstone Torch (off)"), nil,
doc_items_create_entry = false, "jeija_torches_off.png",
icon = "jeija_torches_off.png", "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj",
tiles = {"jeija_torches_off.png"}, {"jeija_torches_off.png"},
light = 0, 0,
groups = {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1},
sounds = mcl_sounds.node_sound_wood_defaults(), mcl_sounds.node_sound_wood_defaults(),
drop = "mesecons_torch:mesecon_torch_on", {
} mesecons = {
receptor = {
mcl_torches.register_torch(off_def) state = mesecon.state.off,
rules = torch_get_output_rules,
local off_override = { },
mesecons = { effector = {
receptor = { state = mesecon.state.on,
state = mesecon.state.off, rules = torch_get_input_rules,
rules = torch_get_output_rules, action_off = torch_action_off,
}, },
effector = {
state = mesecon.state.on,
rules = torch_get_input_rules,
action_off = torch_action_off,
}, },
drop = "mesecons_torch:mesecon_torch_on",
_doc_items_create_entry = false,
} }
} )
minetest.override_item("mesecons_torch:mesecon_torch_off", off_override) mcl_torches.register_torch("mesecon_torch_overheated", S("Redstone Torch (overheated)"),
minetest.override_item("mesecons_torch:mesecon_torch_off_wall", off_override) nil,
nil,
"jeija_torches_off.png",
"mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj",
{"jeija_torches_off.png"},
0,
{dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1},
mcl_sounds.node_sound_wood_defaults(),
{
drop = "mesecons_torch:mesecon_torch_on",
_doc_items_create_entry = false,
on_timer = function(pos, elapsed)
if not mesecon.is_powered(pos) then
local node = minetest.get_node(pos)
torch_action_off(pos, node)
end
end,
}
)
local overheated_def = table.copy(off_def)
overheated_def.name = "mesecon_torch_overheated"
overheated_def.description = S("Redstone Torch (overheated)")
mcl_torches.register_torch(overheated_def)
local overheated_override = { mcl_torches.register_torch("mesecon_torch_on", S("Redstone Torch"),
on_timer = function(pos, elapsed) S("A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything."),
if not mesecon.is_powered(pos) then S("Redstone torches can be placed at the side and on the top of full solid opaque blocks."),
"jeija_torches_on.png",
"mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj",
{"jeija_torches_on.png"},
7,
{dig_immediate=3, dig_by_water=1, redstone_torch=1, mesecon_ignore_opaque_dig=1},
mcl_sounds.node_sound_wood_defaults(),
{
on_destruct = function(pos, oldnode)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
torch_action_off(pos, node) torch_action_on(pos, node)
end end,
end mesecons = {
} receptor = {
state = mesecon.state.on,
minetest.override_item("mesecons_torch:mesecon_torch_overheated", overheated_override) rules = torch_get_output_rules
minetest.override_item("mesecons_torch:mesecon_torch_overheated_wall", overheated_override) },
effector = {
local on_def = { state = mesecon.state.off,
name = "mesecon_torch_on", rules = torch_get_input_rules,
description = S("Redstone Torch"), action_on = torch_action_on,
doc_items_longdesc = S("A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything."), },
doc_items_usagehelp = S("Redstone torches can be placed at the side and on the top of full solid opaque blocks."),
icon = "jeija_torches_on.png",
tiles = {"jeija_torches_on.png"},
light = 7,
groups = {dig_immediate=3, dig_by_water=1, redstone_torch=1, mesecon_ignore_opaque_dig=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
}
mcl_torches.register_torch(on_def)
local on_override = {
on_destruct = function(pos, oldnode)
local node = minetest.get_node(pos)
torch_action_on(pos, node)
end,
mesecons = {
receptor = {
state = mesecon.state.on,
rules = torch_get_output_rules
}, },
effector = { _tt_help = S("Provides redstone power when it's not powered itself"),
state = mesecon.state.off, }
rules = torch_get_input_rules, )
action_on = torch_action_on,
},
},
_tt_help = S("Provides redstone power when it's not powered itself"),
}
minetest.override_item("mesecons_torch:mesecon_torch_on", on_override)
minetest.override_item("mesecons_torch:mesecon_torch_on_wall", on_override)
minetest.register_node("mesecons_torch:redstoneblock", { minetest.register_node("mesecons_torch:redstoneblock", {
description = S("Block of Redstone"), description = S("Block of Redstone"),

View File

@ -368,7 +368,6 @@ mcl_player.player_register_model("mcl_armor_character.b3d", {
run_walk_mine = {x=461, y=480}, run_walk_mine = {x=461, y=480},
sit_mount = {x=484, y=484}, sit_mount = {x=484, y=484},
die = {x=498, y=498}, die = {x=498, y=498},
fly = {x=502, y=581},
}, },
}) })
@ -397,8 +396,6 @@ mcl_player.player_register_model("mcl_armor_character_female.b3d", {
run_walk = {x=440, y=459}, run_walk = {x=440, y=459},
run_walk_mine = {x=461, y=480}, run_walk_mine = {x=461, y=480},
sit_mount = {x=484, y=484}, sit_mount = {x=484, y=484},
die = {x=498, y=498},
fly = {x=502, y=581},
}, },
}) })

View File

@ -8,20 +8,6 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/alias.lua")
local longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive.") local longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive.")
local usage = S("To equip it, put it on the corresponding armor slot in your inventory menu.") local usage = S("To equip it, put it on the corresponding armor slot in your inventory menu.")
minetest.register_tool("mcl_armor:elytra", {
description = S("Elytra"),
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = usage,
inventory_image = "mcl_armor_inv_elytra.png",
groups = {armor_torso=1, mcl_armor_points=0, mcl_armor_uses=10, enchantability=0},
sounds = {
_mcl_armor_equip = "mcl_armor_equip_leather",
_mcl_armor_unequip = "mcl_armor_unequip_leather",
},
on_place = armor.on_armor_use,
on_secondary_use = armor.on_armor_use,
})
minetest.register_tool("mcl_armor:helmet_leather", { minetest.register_tool("mcl_armor:helmet_leather", {
description = S("Leather Cap"), description = S("Leather Cap"),
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
@ -336,7 +322,7 @@ local craft_ingreds = {
gold = { "mcl_core:gold_ingot", "mcl_core:gold_nugget" }, gold = { "mcl_core:gold_ingot", "mcl_core:gold_nugget" },
diamond = { "mcl_core:diamond" }, diamond = { "mcl_core:diamond" },
chain = { nil, "mcl_core:iron_nugget"} , chain = { nil, "mcl_core:iron_nugget"} ,
} }
for k, v in pairs(craft_ingreds) do for k, v in pairs(craft_ingreds) do
-- material -- material
@ -403,3 +389,4 @@ for k, v in pairs(craft_ingreds) do
}) })
end end
end end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 B

View File

@ -35,49 +35,6 @@ mcl_banners.colors = {
["unicolor_light_blue"] = {"light_blue", S("Light Blue Banner"), "mcl_wool:light_blue", "#4040CF", "mcl_dye:lightblue", N("Light Blue") }, ["unicolor_light_blue"] = {"light_blue", S("Light Blue Banner"), "mcl_wool:light_blue", "#4040CF", "mcl_dye:lightblue", N("Light Blue") },
} }
local pattern_names = {
"",
"border",
"bricks",
"circle",
"creeper",
"cross",
"curly_border",
"diagonal_up_left",
"diagonal_up_right",
"diagonal_right",
"diagonal_left",
"flower",
"gradient",
"gradient_up",
"half_horizontal_bottom",
"half_horizontal",
"half_vertical",
"half_vertical_right",
"thing",
"rhombus",
"skull",
"small_stripes",
"square_bottom_left",
"square_bottom_right",
"square_top_left",
"square_top_right",
"straight_cross",
"stripe_bottom",
"stripe_center",
"stripe_downleft",
"stripe_downright",
"stripe_left",
"stripe_middle",
"stripe_right",
"stripe_top",
"triangle_bottom",
"triangle_top",
"triangles_bottom",
"triangles_top",
}
local colors_reverse = {} local colors_reverse = {}
for k,v in pairs(mcl_banners.colors) do for k,v in pairs(mcl_banners.colors) do
colors_reverse["mcl_banners:banner_item_"..v[1]] = k colors_reverse["mcl_banners:banner_item_"..v[1]] = k
@ -343,72 +300,24 @@ minetest.register_node("mcl_banners:hanging_banner", {
end, end,
}) })
-- for pattern_name, pattern in pairs(patterns) do
for colorid, colortab in pairs(mcl_banners.colors) do for colorid, colortab in pairs(mcl_banners.colors) do
for i, pattern_name in ipairs(pattern_names) do
local itemid = colortab[1] local itemid = colortab[1]
local desc = colortab[2] local desc = colortab[2]
local wool = colortab[3] local wool = colortab[3]
local colorize = colortab[4] local colorize = colortab[4]
local itemstring local itemstring = "mcl_banners:banner_item_"..itemid
if pattern_name == "" then
itemstring = "mcl_banners:banner_item_" .. itemid
else
itemstring = "mcl_banners:banner_preview" .. "_" .. pattern_name .. "_" .. itemid
end
local inv local inv
local base if colorize then
local finished_banner inv = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:"..colorize..")"
if pattern_name == "" then
if colorize then
-- Base texture with base color
base = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:"..colorize..")^[resize:32x32"
else
base = "mcl_banners_item_base.png^mcl_banners_item_overlay.png^[resize:32x32"
end
finished_banner = base
else else
-- Banner item preview background inv = "mcl_banners_item_base.png^mcl_banners_item_overlay.png"
base = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:#CCCCCC)^[resize:32x32"
desc = S("Preview Banner")
local pattern = "mcl_banners_" .. pattern_name .. ".png"
local color = colorize
-- Generate layer texture
-- TODO: The layer texture in the icon is squished
-- weirdly because the width/height aspect ratio of
-- the banner icon is 1:1.5, whereas the aspect ratio
-- of the banner entity is 1:2. A solution would be to
-- redraw the pattern textures as low-resolution pixel
-- art and use that instead.
local layer = "(([combine:20x40:-2,-2="..pattern.."^[resize:16x24^[colorize:"..color..":"..layer_ratio.."))"
function escape(text)
return text:gsub("%^", "\\%^"):gsub(":", "\\:") -- :gsub("%(", "\\%("):gsub("%)", "\\%)")
end
finished_banner = "[combine:32x32:0,0=" .. escape(base) .. ":8,4=" .. escape(layer)
end end
inv = finished_banner
-- Banner items. -- Banner items.
-- This is the player-visible banner item. It comes in 16 base colors with a lot of patterns. -- This is the player-visible banner item. It comes in 16 base colors.
-- The multiple items are really only needed for the different item images. -- The multiple items are really only needed for the different item images.
-- TODO: Combine the items into only 1 item. -- TODO: Combine the items into only 1 item.
local groups
if pattern_name == "" then
groups = { banner = 1, deco_block = 1, flammable = -1 }
else
groups = { not_in_creative_inventory = 1 }
end
minetest.register_craftitem(itemstring, { minetest.register_craftitem(itemstring, {
description = desc, description = desc,
_tt_help = S("Paintable decoration"), _tt_help = S("Paintable decoration"),
@ -417,7 +326,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do
wield_image = inv, wield_image = inv,
-- Banner group groups together the banner items, but not the nodes. -- Banner group groups together the banner items, but not the nodes.
-- Used for crafting. -- Used for crafting.
groups = groups, groups = { banner = 1, deco_block = 1, flammable = -1 },
stack_max = 16, stack_max = 16,
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
@ -583,7 +492,6 @@ for colorid, colortab in pairs(mcl_banners.colors) do
-- Add item to node alias -- Add item to node alias
doc.add_entry_alias("nodes", "mcl_banners:standing_banner", "craftitems", itemstring) doc.add_entry_alias("nodes", "mcl_banners:standing_banner", "craftitems", itemstring)
end end
end
end end
if minetest.get_modpath("doc") then if minetest.get_modpath("doc") then

View File

@ -253,11 +253,6 @@ for colorid, colortab in pairs(mcl_banners.colors) do
dye_to_colorid_mapping[colortab[5]] = colorid dye_to_colorid_mapping[colortab[5]] = colorid
end end
local dye_to_itemid_mapping = {}
for colorid, colortab in pairs(mcl_banners.colors) do
dye_to_itemid_mapping[colortab[5]] = colortab[1]
end
-- Create a banner description containing all the layer names -- Create a banner description containing all the layer names
mcl_banners.make_advanced_banner_description = function(description, layers) mcl_banners.make_advanced_banner_description = function(description, layers)
if layers == nil or #layers == 0 then if layers == nil or #layers == 0 then
@ -496,14 +491,7 @@ local banner_pattern_craft = function(itemstack, player, old_craft_grid, craft_i
imeta:set_string("description", ometa:get_string("description")) imeta:set_string("description", ometa:get_string("description"))
imeta:set_string("name", mname) imeta:set_string("name", mname)
end end
return itemstack
if craft_predict then
local itemid_prefix = "mcl_banners:banner_preview"
local coloritemid = dye_to_itemid_mapping[dye]
return ItemStack(itemid_prefix .. "_" .. matching_pattern .. "_" .. coloritemid)
else
return itemstack
end
end end
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv) minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)

View File

@ -1,4 +1,4 @@
# textdomain: mcl_compass # textdomain: mcl_compass
Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder zum Einstiegspunkt der Welt zeigen. Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder den Einstiegspunkt der Welt zeigen.
Compass=Kompass Compass=Kompass
Points to the world origin=Zeigt zum Startpunkt der Welt Points to the world origin=Zeigt zum Startpunkt der Welt

View File

@ -46,56 +46,6 @@ minetest.register_craft({
} }
}) })
-- Stripped Bark
minetest.register_craft({
output = "mcl_core:stripped_oak_bark 3",
recipe = {
{ "mcl_core:stripped_oak", "mcl_core:stripped_oak" },
{ "mcl_core:stripped_oak", "mcl_core:stripped_oak" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_acacia_bark 3",
recipe = {
{ "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" },
{ "mcl_core:stripped_acacia", "mcl_core:stripped_acacia" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_dark_oak_bark 3",
recipe = {
{ "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" },
{ "mcl_core:stripped_dark_oak", "mcl_core:stripped_dark_oak" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_birch_bark 3",
recipe = {
{ "mcl_core:stripped_birch", "mcl_core:stripped_birch" },
{ "mcl_core:stripped_birch", "mcl_core:stripped_birch" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_spruce_bark 3",
recipe = {
{ "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" },
{ "mcl_core:stripped_spruce", "mcl_core:stripped_spruce" },
}
})
minetest.register_craft({
output = "mcl_core:stripped_jungle_bark 3",
recipe = {
{ "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" },
{ "mcl_core:stripped_jungle", "mcl_core:stripped_jungle" },
}
})
minetest.register_craft({ minetest.register_craft({
type = 'shapeless', type = 'shapeless',
output = 'mcl_core:mossycobble', output = 'mcl_core:mossycobble',

View File

@ -190,22 +190,6 @@ minetest.register_abm({
end, end,
}) })
-- Make cactus destroy items
minetest.register_abm({
label = "Cactus destroy items",
nodenames = {"mcl_core:cactus"},
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
for _,object in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
object:remove()
end
end
end,
})
minetest.register_abm({ minetest.register_abm({
label = "Sugar canes growth", label = "Sugar canes growth",
nodenames = {"mcl_core:reeds"}, nodenames = {"mcl_core:reeds"},

View File

@ -14,7 +14,6 @@ mcl_autogroup.register_diggroup("shearsy_wool")
mcl_autogroup.register_diggroup("shearsy_cobweb") mcl_autogroup.register_diggroup("shearsy_cobweb")
mcl_autogroup.register_diggroup("swordy") mcl_autogroup.register_diggroup("swordy")
mcl_autogroup.register_diggroup("swordy_cobweb") mcl_autogroup.register_diggroup("swordy_cobweb")
mcl_autogroup.register_diggroup("hoey")
-- Load files -- Load files
local modpath = minetest.get_modpath("mcl_core") local modpath = minetest.get_modpath("mcl_core")

View File

@ -1,4 +1,4 @@
-- Tree nodes: Wood, Wooden Planks, Sapling, Leaves, Stripped Wood -- Tree nodes: Wood, Wooden Planks, Sapling, Leaves
local S = minetest.get_translator("mcl_core") local S = minetest.get_translator("mcl_core")
local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil
@ -48,166 +48,6 @@ local register_tree_trunk = function(subname, description_trunk, description_bar
}) })
end end
-- Register stripped trunk
minetest.register_node("mcl_core:stripped_oak", {
description = "Stripped Oak Log",
_doc_items_longdesc = "Stripped Oak Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_acacia", {
description = "Stripped Acacia Log",
_doc_items_longdesc = "Stripped Acacia Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_dark_oak", {
description = "Stripped Dark Oak Log",
_doc_items_longdesc = "Stripped Dark Oak Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_birch", {
description = "Stripped Birch Log",
_doc_items_longdesc = "Stripped Birch Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_spruce", {
description = "Stripped Spruce Log",
_doc_items_longdesc = "Stripped Spruce Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_jungle", {
description = "Stripped Jungle Log",
_doc_items_longdesc = "Stripped Jungle Log is a log that has been stripped of it's bark.",
tiles = {"mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5, tree=1},
sounds = mcl_sounds.node_sound_wood_defaults(),
_mcl_blast_resistance = 10,
_mcl_hardness = 2,
})
-- Register stripped bark
minetest.register_node("mcl_core:stripped_oak_bark", {
description = "Stripped Oak Bark",
_doc_items_longdesc = "Stripped Oak Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=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 = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_acacia_bark", {
description = "Stripped Acacia Bark",
_doc_items_longdesc = "Stripped Acacia Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_acacia_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=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 = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_dark_oak_bark", {
description = "Stripped Dark Oak Bark",
_doc_items_longdesc = "Stripped Dark Oak Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_dark_oak_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=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 = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_birch_bark", {
description = "Stripped Birch Bark",
_doc_items_longdesc = "Stripped Birch Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_birch_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=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 = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_spruce_bark", {
description = "Stripped Spruce Bark",
_doc_items_longdesc = "Stripped Spruce Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_spruce_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=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 = 10,
_mcl_hardness = 2,
})
minetest.register_node("mcl_core:stripped_jungle_bark", {
description = "Stripped Jungle Bark",
_doc_items_longdesc = "Stripped Jungles Bark is a bark that has been stripped.",
tiles = {"mcl_core_stripped_jungle_side.png"},
is_ground_content = false,
paramtype2 = "facedir",
on_place = mcl_util.rotate_axis,
groups = {handy=1,axey=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 = 10,
_mcl_hardness = 2,
})
local register_wooden_planks = function(subname, description, tiles) local register_wooden_planks = function(subname, description, tiles)
minetest.register_node("mcl_core:"..subname, { minetest.register_node("mcl_core:"..subname, {
description = description, description = description,
@ -268,19 +108,7 @@ local register_leaves = function(subname, description, longdesc, tiles, sapling,
tiles = tiles, tiles = tiles,
paramtype = "light", paramtype = "light",
stack_max = 64, stack_max = 64,
groups = { groups = {handy=1,shearsy=1,swordy=1, leafdecay=leafdecay_distance, flammable=2, leaves=1, deco_block=1, dig_by_piston=1, fire_encouragement=30, fire_flammability=60},
handy=1,
hoey=1,
shearsy=1,
swordy=1,
leafdecay=leafdecay_distance,
flammable=2,
leaves=1,
deco_block=1,
dig_by_piston=1,
fire_encouragement=30,
fire_flammability=60
},
drop = get_drops(0), drop = get_drops(0),
_mcl_shears_drop = true, _mcl_shears_drop = true,
sounds = mcl_sounds.node_sound_leaves_defaults(), sounds = mcl_sounds.node_sound_leaves_defaults(),
@ -386,4 +214,4 @@ register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from
-- Node aliases -- Node aliases
minetest.register_alias("default:acacia_tree", "mcl_core:acaciatree") minetest.register_alias("default:acacia_tree", "mcl_core:acaciatree")
minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves") minetest.register_alias("default:acacia_leaves", "mcl_core:acacialeaves")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 B

View File

@ -1,5 +1,4 @@
local S = minetest.get_translator("mcl_doors") local S = minetest.get_translator("mcl_doors")
local minetest_get_meta = minetest.get_meta
-- This helper function calls on_place_node callbacks. -- This helper function calls on_place_node callbacks.
local function on_place_node(place_to, newnode, local function on_place_node(place_to, newnode,
@ -165,14 +164,14 @@ function mcl_doors:register_door(name, def)
end end
if def.only_placer_can_open then if def.only_placer_can_open then
local meta = minetest_get_meta(pt) local meta = minetest.get_meta(pt)
meta:set_string("doors_owner", "") meta:set_string("doors_owner", "")
meta = minetest_get_meta(pt2) meta = minetest.get_meta(pt2)
meta:set_string("doors_owner", "") meta:set_string("doors_owner", "")
end end
local meta1 = minetest_get_meta(pt) local meta1 = minetest.get_meta(pt)
local meta2 = minetest_get_meta(pt2) local meta2 = minetest.get_meta(pt2)
-- save mirror state for the correct door -- save mirror state for the correct door
if left_node.name:sub(1, #name) == name then if left_node.name:sub(1, #name) == name then
meta1:set_int("is_mirrored", 1) meta1:set_int("is_mirrored", 1)
@ -199,9 +198,9 @@ function mcl_doors:register_door(name, def)
local tb = def.tiles_bottom local tb = def.tiles_bottom
local function on_open_close(pos, dir, check_name, replace, replace_dir) local function on_open_close(pos, dir, check_name, replace, replace_dir)
local meta1 = minetest_get_meta(pos) local meta1 = minetest.get_meta(pos)
pos.y = pos.y+dir pos.y = pos.y+dir
local meta2 = minetest_get_meta(pos) local meta2 = minetest.get_meta(pos)
-- if name of other door is not the same as check_name -> return -- if name of other door is not the same as check_name -> return
if not minetest.get_node(pos).name == check_name then if not minetest.get_node(pos).name == check_name then
@ -255,7 +254,7 @@ function mcl_doors:register_door(name, def)
if not def.only_placer_can_open then if not def.only_placer_can_open then
return true return true
end end
local meta = minetest_get_meta(pos) local meta = minetest.get_meta(pos)
local pn = player:get_player_name() local pn = player:get_player_name()
return meta:get_string("doors_owner") == pn return meta:get_string("doors_owner") == pn
end end
@ -293,15 +292,10 @@ function mcl_doors:register_door(name, def)
sounds = def.sounds, sounds = def.sounds,
after_destruct = function(bottom, oldnode) after_destruct = function(bottom, oldnode)
local meta_bottom = minetest_get_meta(bottom) minetest.add_item(bottom, name)
if meta_bottom:get_int("rotation") == 1 then local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z }
meta_bottom:set_int("rotation", 0) if minetest.get_node(bottom).name ~= name.."_b_2" and minetest.get_node(top).name == name.."_t_1" then
else minetest.remove_node(top)
minetest.add_item(bottom, name)
local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z }
if minetest.get_node(bottom).name ~= name.."_b_2" and minetest.get_node(top).name == name.."_t_1" then
minetest.remove_node(top)
end
end end
end, end,
@ -311,19 +305,13 @@ function mcl_doors:register_door(name, def)
action_on = on_mesecons_signal_open, action_on = on_mesecons_signal_open,
}}, }},
on_rotate = function(bottom, node, user, mode, param2) on_rotate = function(pos, node, user, mode, param2)
if mode == screwdriver.ROTATE_FACE then if mode == screwdriver.ROTATE_FACE then
local meta_bottom = minetest_get_meta(bottom) minetest.remove_node(pos)
meta_bottom:set_int("rotation", 1) node.param2 = screwdriver.rotate.facedir(pos, node, mode)
node.param2 = screwdriver.rotate.facedir(bottom, node, mode) minetest.set_node(pos, node)
minetest.swap_node(bottom, node)
local top = {x=bottom.x,y=bottom.y+1,z=bottom.z}
local meta_top = minetest_get_meta(top)
meta_top:set_int("rotation", 1)
node.name = name .."_t_1" node.name = name .."_t_1"
minetest.swap_node(top, node) minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, node)
return true return true
end end
return false return false
@ -365,14 +353,9 @@ function mcl_doors:register_door(name, def)
sounds = def.sounds, sounds = def.sounds,
after_destruct = function(top, oldnode) after_destruct = function(top, oldnode)
local meta_top = minetest_get_meta(top) local bottom = { x = top.x, y = top.y - 1, z = top.z }
if meta_top:get_int("rotation") == 1 then if minetest.get_node(top).name ~= name.."_t_2" and minetest.get_node(bottom).name == name.."_b_1" and oldnode.name == name.."_t_1" then
meta_top:set_int("rotation", 0) minetest.dig_node(bottom)
else
local bottom = { x = top.x, y = top.y - 1, z = top.z }
if minetest.get_node(top).name ~= name.."_t_2" and minetest.get_node(bottom).name == name.."_b_1" and oldnode.name == name.."_t_1" then
minetest.dig_node(bottom)
end
end end
end, end,
@ -383,19 +366,13 @@ function mcl_doors:register_door(name, def)
rules = mesecon.rules.flat, rules = mesecon.rules.flat,
}}, }},
on_rotate = function(top, node, user, mode, param2) on_rotate = function(pos, node, user, mode, param2)
if mode == screwdriver.ROTATE_FACE then if mode == screwdriver.ROTATE_FACE then
local meta_top = minetest_get_meta(top) minetest.remove_node(pos)
meta_top:set_int("rotation", 1) node.param2 = screwdriver.rotate.facedir(pos, node, mode)
node.param2 = screwdriver.rotate.facedir(top, node, mode) minetest.set_node(pos, node)
minetest.swap_node(top, node)
local bottom = {x=top.x,y=top.y-1,z=top.z}
local meta_bottom = minetest_get_meta(bottom)
meta_bottom:set_int("rotation", 1)
node.name = name .."_b_1" node.name = name .."_b_1"
minetest.swap_node(bottom, node) minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z}, node)
return true return true
end end
return false return false
@ -437,15 +414,10 @@ function mcl_doors:register_door(name, def)
sounds = def.sounds, sounds = def.sounds,
after_destruct = function(bottom, oldnode) after_destruct = function(bottom, oldnode)
local meta_bottom = minetest_get_meta(bottom) minetest.add_item(bottom, name)
if meta_bottom:get_int("rotation") == 1 then local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z }
meta_bottom:set_int("rotation", 0) if minetest.get_node(bottom).name ~= name.."_b_1" and minetest.get_node(top).name == name.."_t_2" then
else minetest.remove_node(top)
local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z }
minetest.add_item(bottom, name)
if minetest.get_node(bottom).name ~= name.."_b_1" and minetest.get_node(top).name == name.."_t_2" then
minetest.remove_node(top)
end
end end
end, end,
@ -455,19 +427,13 @@ function mcl_doors:register_door(name, def)
action_off = on_mesecons_signal_close, action_off = on_mesecons_signal_close,
}}, }},
on_rotate = function(bottom, node, user, mode, param2) on_rotate = function(pos, node, user, mode, param2)
if mode == screwdriver.ROTATE_FACE then if mode == screwdriver.ROTATE_FACE then
local meta_bottom = minetest_get_meta(bottom) minetest.remove_node(pos)
meta_bottom:set_int("rotation", 1) node.param2 = screwdriver.rotate.facedir(pos, node, mode)
node.param2 = screwdriver.rotate.facedir(bottom, node, mode) minetest.set_node(pos, node)
minetest.swap_node(bottom, node)
local top = {x=bottom.x,y=bottom.y+1,z=bottom.z}
local meta_top = minetest_get_meta(top)
meta_top:set_int("rotation", 1)
node.name = name .."_t_2" node.name = name .."_t_2"
minetest.swap_node(top, node) minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, node)
return true return true
end end
return false return false
@ -509,14 +475,9 @@ function mcl_doors:register_door(name, def)
sounds = def.sounds, sounds = def.sounds,
after_destruct = function(top, oldnode) after_destruct = function(top, oldnode)
local meta_top = minetest_get_meta(top) local bottom = { x = top.x, y = top.y - 1, z = top.z }
if meta_top:get_int("rotation") == 1 then if minetest.get_node(top).name ~= name.."_t_1" and minetest.get_node(bottom).name == name.."_b_2" and oldnode.name == name.."_t_2" then
meta_top:set_int("rotation", 0) minetest.dig_node(bottom)
else
local bottom = { x = top.x, y = top.y - 1, z = top.z }
if minetest.get_node(top).name ~= name.."_t_1" and minetest.get_node(bottom).name == name.."_b_2" and oldnode.name == name.."_t_2" then
minetest.dig_node(bottom)
end
end end
end, end,
@ -527,19 +488,13 @@ function mcl_doors:register_door(name, def)
rules = mesecon.rules.flat, rules = mesecon.rules.flat,
}}, }},
on_rotate = function(top, node, user, mode, param2) on_rotate = function(pos, node, user, mode, param2)
if mode == screwdriver.ROTATE_FACE then if mode == screwdriver.ROTATE_FACE then
local meta_top = minetest_get_meta(top) minetest.remove_node(pos)
meta_top:set_int("rotation", 1) node.param2 = screwdriver.rotate.facedir(pos, node, mode)
node.param2 = screwdriver.rotate.facedir(top, node, mode) minetest.set_node(pos, node)
minetest.swap_node(top, node)
local bottom = {x=top.x,y=top.y-1,z=top.z}
local meta_bottom = minetest_get_meta(bottom)
meta_bottom:set_int("rotation", 1)
node.name = name .."_b_2" node.name = name .."_b_2"
minetest.swap_node(bottom, node) minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z}, node)
return true return true
end end
return false return false

View File

@ -16,9 +16,9 @@ Birch Trapdoor=Birkenfalltür
Spruce Trapdoor=Fichtenfalltür Spruce Trapdoor=Fichtenfalltür
Dark Oak Trapdoor=Schwarzeichenfalltür Dark Oak Trapdoor=Schwarzeichenfalltür
Jungle Trapdoor=Dschungelfalltür Jungle Trapdoor=Dschungelfalltür
Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Holzfalltüren sind horizontale Barrieren, die von Hand oder mit einem Redstone-Signal geöffnet oder geschlossen werden können. Sie belegen den oberen oder unteren Teil eines Blocks, je nachdem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden. Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Holzfalltüren sind horizontale Barrieren, die von Hand oder mit einem Redstone-Signal geöffnet oder geschlossen werden können. Sie belegen den oberen oder unteren Teil eines Blocks, je nach dem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden.
To open or close the trapdoor, rightclick it or send a redstone signal to it.=Um die Falltür zu öffnen oder zu schließen, rechtsklicken Sie sie oder schicken Sie ein Redstone-Signal zu ihr. To open or close the trapdoor, rightclick it or send a redstone signal to it.=Um die Falltür zu öffnen oder zu schließen, rechtsklicken Sie sie oder schicken Sie ein Redstone-Signal zu ihr.
Iron Trapdoor=Eisenfalltür Iron Trapdoor=Eisenfalltür
Iron trapdoors are horizontal barriers which can only be opened and closed by redstone signals, but not by hand. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Eisenfalltüren sind horizontale Barrieren, die nur mit einem Redstone-Signal geöffnet oder geschlossen werden können, nicht von Hand. Sie belegen den oberen oder unteren Teil eines Blocks, je nachdem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden. Iron trapdoors are horizontal barriers which can only be opened and closed by redstone signals, but not by hand. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=Eisenfalltüren sind horizontale Barrieren, die nur mit einem Redstone-Signal geöffnet oder geschlossen werden können, nicht von Hand. Sie belegen den oberen oder unteren Teil eines Blocks, je nach dem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden.
Openable by players and redstone power=Zu öffnen von Spielern und Redstoneenergie Openable by players and redstone power=Zu öffnen von Spielern und Redstoneenergie
Openable by redstone power=Zu öffnen von Redstoneenergie Openable by redstone power=Zu öffnen von Redstoneenergie

View File

@ -17,8 +17,8 @@ Efficiency=Effizienz
Increases mining speed.=Erhöht Grabegeschwindigkeit. Increases mining speed.=Erhöht Grabegeschwindigkeit.
Feather Falling=Federfall Feather Falling=Federfall
Reduces fall damage.=Reduziert Fallschaden. Reduces fall damage.=Reduziert Fallschaden.
Fire Aspect=Feueraspekt Fire Aspect=Feieraspekt
Sets target on fire.=Zündet das Ziel an. Sets target on fire.=Zündes das Ziel an.
Fire Protection=Feuerschutz Fire Protection=Feuerschutz
Reduces fire damage.=Reduziert Feuerschaden Reduces fire damage.=Reduziert Feuerschaden
Flame=Flamme Flame=Flamme
@ -31,7 +31,7 @@ Impaling=Aufspießen
Trident deals additional damage to ocean mobs.=Dreizack richtet Zusatzschaden an Ozeanmobs an. Trident deals additional damage to ocean mobs.=Dreizack richtet Zusatzschaden an Ozeanmobs an.
Infinity=Unendlichkeit Infinity=Unendlichkeit
Shooting consumes no regular arrows.=Schüsse verbrauchen keine regulären Pfeile. Shooting consumes no regular arrows.=Schüsse verbrauchen keine regulären Pfeile.
Knockback=Rückschlag Knockback=Rückschlag.
Increases knockback.=Verstärkt Rückschlag. Increases knockback.=Verstärkt Rückschlag.
Looting=Plünderer Looting=Plünderer
Increases mob loot.=Erhöht Abwürfe von Mobs. Increases mob loot.=Erhöht Abwürfe von Mobs.
@ -43,7 +43,7 @@ Lure=Köder
Decreases time until rod catches something.=Reduziert die Zeit, bis die Angel etwas fängt. Decreases time until rod catches something.=Reduziert die Zeit, bis die Angel etwas fängt.
Mending=Ausbessern Mending=Ausbessern
Repair the item while gaining XP orbs.=Gegenstand reparieren, während man Erfahrungskugeln erhält. Repair the item while gaining XP orbs.=Gegenstand reparieren, während man Erfahrungskugeln erhält.
Multishot=Mehrfachschuss Multishot=Mehrschuss
Shoot 3 arrows at the cost of one.=3 Pfeile zum Preis von 1 schießen. Shoot 3 arrows at the cost of one.=3 Pfeile zum Preis von 1 schießen.
Piercing=Durchbohren Piercing=Durchbohren
Arrows passes through multiple objects.=Pfeile durchdringen mehrere Objekte. Arrows passes through multiple objects.=Pfeile durchdringen mehrere Objekte.
@ -74,7 +74,7 @@ Increases sweeping attack damage.=Erhöht Schwungangriffsschaden.
Thorns=Dornen Thorns=Dornen
Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflektiert etwas des Schadens beim Erleiden eines Treffers, auf Kosten der Haltbarkeit. Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflektiert etwas des Schadens beim Erleiden eines Treffers, auf Kosten der Haltbarkeit.
Unbreaking=Haltbarkeit Unbreaking=Haltbarkeit
Increases item durability.=Erhöht Haltbarkeit des Gegenstands. Increases item durability.=Erhöht Haldbarkeit des Gegenstands.
Inventory=Inventar Inventory=Inventar
@1 Lapis Lazuli=@1 Lapislazuli @1 Lapis Lazuli=@1 Lapislazuli
@1 Enchantment Levels=@1 Verzauberungsstufen @1 Enchantment Levels=@1 Verzauberungsstufen

View File

@ -78,9 +78,6 @@ minetest.register_tool("mcl_farming:hoe_wood", {
}, },
_repair_material = "group:wood", _repair_material = "group:wood",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_diggroups = {
hoey = { speed = 2, level = 1, uses = 60 }
},
}) })
minetest.register_craft({ minetest.register_craft({
@ -121,9 +118,6 @@ minetest.register_tool("mcl_farming:hoe_stone", {
}, },
_repair_material = "mcl_core:cobble", _repair_material = "mcl_core:cobble",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_diggroups = {
hoey = { speed = 4, level = 3, uses = 132 }
},
}) })
minetest.register_craft({ minetest.register_craft({
@ -160,9 +154,6 @@ minetest.register_tool("mcl_farming:hoe_iron", {
}, },
_repair_material = "mcl_core:iron_ingot", _repair_material = "mcl_core:iron_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_diggroups = {
hoey = { speed = 6, level = 4, uses = 251 }
},
}) })
minetest.register_craft({ minetest.register_craft({
@ -205,9 +196,6 @@ minetest.register_tool("mcl_farming:hoe_gold", {
}, },
_repair_material = "mcl_core:gold_ingot", _repair_material = "mcl_core:gold_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_diggroups = {
hoey = { speed = 12, level = 2, uses = 33 }
},
}) })
minetest.register_craft({ minetest.register_craft({
@ -252,9 +240,6 @@ minetest.register_tool("mcl_farming:hoe_diamond", {
}, },
_repair_material = "mcl_core:diamond", _repair_material = "mcl_core:diamond",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
_mcl_diggroups = {
hoey = { speed = 8, level = 5, uses = 1562 }
},
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -146,7 +146,7 @@ minetest.register_node("mcl_farming:hay_block", {
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false, is_ground_content = false,
on_place = mcl_util.rotate_axis, on_place = mcl_util.rotate_axis,
groups = {handy=1, hoey=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80}, groups = {handy=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80},
sounds = mcl_sounds.node_sound_leaves_defaults(), sounds = mcl_sounds.node_sound_leaves_defaults(),
on_rotate = on_rotate, on_rotate = on_rotate,
_mcl_blast_resistance = 0.5, _mcl_blast_resistance = 0.5,

View File

@ -1,6 +1,6 @@
# textdomain: mcl_fences # textdomain: mcl_fences
Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=Zäune sind Gebäude, die den Weg blockieren. Sie verbinden sich gegenseitig und anderen festen Blöcken. Man kann sie nicht mit normalen Sprüngen überspringen. Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=Zäune sind Gebäude, die den Weg blockieren. Sie verbinden sich gegenseitig und anderen festen Blöcken. Man kann sie nicht mit normalen Sprüngen überspringen.
Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Zauntore können geöffnet und geschlossen werden und können nicht übersprungen werden. Zäune lassen sich gut mit Zauntoren verbinden. Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Zauntore können geöffnet und geschlossen werden und können nicht übersprungen werden. Zäune werden sich gut mit Zauntoren verbinden.
Right-click the fence gate to open or close it.=Rechtsklicken Sie auf ein Zauntor, um es zu öffnen oder zu schließen. Right-click the fence gate to open or close it.=Rechtsklicken Sie auf ein Zauntor, um es zu öffnen oder zu schließen.
Oak Fence=Eichenzaun Oak Fence=Eichenzaun
Oak Fence Gate=Eichenzauntor Oak Fence Gate=Eichenzauntor

View File

@ -47,16 +47,94 @@ local alldirs=
{ x = 0, y = 0, z = 1} { x = 0, y = 0, z = 1}
} }
local smoke_pdef = { -- 3 exptime variants because the animation is not tied to particle expiration time.
amount = 0.009, -- 3 colorized variants to imitate minecraft's
maxexptime = 4.0, local smoke_pdef_base = {
amount = 0.001,
time = 0,
-- minpos = vector.add(pos, { x = -0.45, y = -0.45, z = -0.45 }),
-- maxpos = vector.add(pos, { x = 0.45, y = 0.45, z = 0.45 }),
minvel = { x = -0.1, y = 0.3, z = -0.1 }, minvel = { x = -0.1, y = 0.3, z = -0.1 },
maxvel = { x = 0.1, y = 1.6, z = 0.1 }, maxvel = { x = 0.1, y = 1.6, z = 0.1 },
-- minexptime = 3 exptime variants,
-- maxexptime = 3 exptime variants
minsize = 4.0, minsize = 4.0,
maxsize = 4.5, maxsize = 4.5,
minrelpos = { x = -0.45, y = -0.45, z = -0.45 }, -- texture = "mcl_particles_smoke_anim.png^[colorize:#000000:(3 colourize variants)",
maxrelpos = { x = 0.45, y = 0.45, z = 0.45 }, animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
-- length = 3 exptime variants
},
collisiondetection = true,
} }
local smoke_pdef_cached = {}
local spawn_smoke = function(pos)
local min = math.min
local new_minpos = vector.add(pos, { x = -0.45, y = -0.45, z = -0.45 })
local new_maxpos = vector.add(pos, { x = 0.45, y = 0.45, z = 0.45 })
-- populate the cache
if not next(smoke_pdef_cached) then
-- the last frame plays for 1/8 * N seconds, so we can take advantage of it
-- to have varying exptime for each variant.
local exptimes = { 0.75, 1.5, 4.0 }
local colorizes = { "199", "209", "243" } -- round(78%, 82%, 90% of 256) - 1
local id = 1
for _,exptime in ipairs(exptimes) do
for _,colorize in ipairs(colorizes) do
smoke_pdef_base.minpos = new_minpos
smoke_pdef_base.maxpos = new_maxpos
smoke_pdef_base.maxexptime = exptime
smoke_pdef_base.animation.length = exptime + 0.1
-- minexptime must be set such that the last frame is actully rendered,
-- even if its very short. Larger exptime -> larger range
smoke_pdef_base.minexptime = min(exptime, (7.0/8.0 * (exptime + 0.1) + 0.1))
smoke_pdef_base.texture = "mcl_particles_smoke_anim.png^[colorize:#000000:" ..colorize
smoke_pdef_cached[id] = table.copy(smoke_pdef_base)
mcl_particles.add_node_particlespawner(pos, smoke_pdef_cached[id], "high")
id = id + 1
end
end
-- cache already populated
else
for i, smoke_pdef in ipairs(smoke_pdef_cached) do
smoke_pdef.minpos = new_minpos
smoke_pdef.maxpos = new_maxpos
mcl_particles.add_node_particlespawner(pos, smoke_pdef, "high")
end
end
--[[ Old smoke pdef
local spawn_smoke = function(pos)
mcl_particles.add_node_particlespawner(pos, {
amount = 0.1,
time = 0,
minpos = vector.add(pos, { x = -0.45, y = -0.45, z = -0.45 }),
maxpos = vector.add(pos, { x = 0.45, y = 0.45, z = 0.45 }),
minvel = { x = 0, y = 0.5, z = 0 },
maxvel = { x = 0, y = 0.6, z = 0 },
minexptime = 2.0,
maxexptime = 2.0,
minsize = 3.0,
maxsize = 4.0,
texture = "mcl_particles_smoke_anim.png^[colorize:#000000:127",
animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
length = 2.1,
},
}, "high")
-- ]]
end
-- --
-- Items -- Items
@ -225,7 +303,7 @@ minetest.register_node("mcl_fire:fire", {
end end
fire_timer(pos) fire_timer(pos)
mcl_particles.spawn_smoke(pos, "fire", smoke_pdef) spawn_smoke(pos)
end, end,
on_destruct = function(pos) on_destruct = function(pos)
mcl_particles.delete_node_particlespawners(pos) mcl_particles.delete_node_particlespawners(pos)
@ -289,7 +367,7 @@ minetest.register_node("mcl_fire:eternal_fire", {
if has_mcl_portals then --Calling directly minetest.get_modpath consumes 4x more compute time if has_mcl_portals then --Calling directly minetest.get_modpath consumes 4x more compute time
mcl_portals.light_nether_portal(pos) mcl_portals.light_nether_portal(pos)
end end
mcl_particles.spawn_smoke(pos, "fire", smoke_pdef) spawn_smoke(pos)
end, end,
on_destruct = function(pos) on_destruct = function(pos)
mcl_particles.delete_node_particlespawners(pos) mcl_particles.delete_node_particlespawners(pos)
@ -549,7 +627,7 @@ minetest.register_lbm({
nodenames = {"group:fire"}, nodenames = {"group:fire"},
run_at_every_load = true, run_at_every_load = true,
action = function(pos, node) action = function(pos, node)
mcl_particles.spawn_smoke(pos, "fire", smoke_pdef) spawn_smoke(pos)
end, end,
}) })

View File

@ -1,7 +0,0 @@
Firework mod for Mineclone 2
by NO11 and and some parts by j45
Sound credits:
* mcl_firework_rocket.ogg (tnt_ignite.ogg): Own derivate work of sound by Ned Bouhalassa (CC0) created in 2005, source: <https://freesound.org/people/Ned Bouhalassa/sounds/8320/>

View File

@ -1,2 +0,0 @@
name = mcl_firework
author = NO11, j45

View File

@ -1,17 +0,0 @@
minetest.register_craft({
type = "shapeless",
output = "mcl_fireworks:rocket_1 3",
recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder"},
})
minetest.register_craft({
type = "shapeless",
output = "mcl_fireworks:rocket_2 3",
recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder"},
})
minetest.register_craft({
type = "shapeless",
output = "mcl_fireworks:rocket_3 3",
recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder"},
})

View File

@ -1,4 +0,0 @@
local path = minetest.get_modpath("mcl_fireworks")
dofile(path .. "/register.lua")
dofile(path .. "/crafting.lua")

View File

@ -1,3 +0,0 @@
# textdomain: mcl_fireworks
Firework Rocket=Feuerwerksrakete
Flight Duration:=Flugdauer:

View File

@ -1,69 +0,0 @@
local S = minetest.get_translator("mcl_fireworks")
player_rocketing = {}
local help = S("Flight Duration:")
local description = S("Firework Rocket")
local rocket_sound = function()
minetest.sound_play("mcl_fireworks_rocket")
end
minetest.register_craftitem("mcl_fireworks:rocket_1", {
description = description,
_tt_help = help.." 1",
inventory_image = "mcl_fireworks_rocket.png",
stack_max = 64,
on_use = function(itemstack, user, pointed_thing)
local torso = user:get_inventory():get_stack("armor", 3)
if torso and torso:get_name() == "mcl_armor:elytra" and player_rocketing[user] ~= true then
player_rocketing[user] = true
minetest.after(2.2, function()
player_rocketing[user] = false
end)
itemstack:take_item()
--user:add_player_velocity(vector.multiply(user:get_look_dir(), 20))
rocket_sound()
end
return itemstack
end,
})
minetest.register_craftitem("mcl_fireworks:rocket_2", {
description = description,
_tt_help = help.." 2",
inventory_image = "mcl_fireworks_rocket.png",
stack_max = 64,
on_use = function(itemstack, user, pointed_thing)
local torso = user:get_inventory():get_stack("armor", 3)
if torso and torso:get_name() == "mcl_armor:elytra" and player_rocketing[user] ~= true then
player_rocketing[user] = true
minetest.after(4.5, function()
player_rocketing[user] = false
end)
itemstack:take_item()
--user:add_player_velocity(vector.multiply(user:get_look_dir(), 20))
rocket_sound()
end
return itemstack
end,
})
minetest.register_craftitem("mcl_fireworks:rocket_3", {
description = description,
_tt_help = help.." 3",
inventory_image = "mcl_fireworks_rocket.png",
stack_max = 64,
on_use = function(itemstack, user, pointed_thing)
local torso = user:get_inventory():get_stack("armor", 3)
if torso and torso:get_name() == "mcl_armor:elytra" and player_rocketing[user] ~= true then
player_rocketing[user] = true
minetest.after(6, function()
player_rocketing[user] = false
end)
itemstack:take_item()
--user:add_player_velocity(vector.multiply(user:get_look_dir(), 20))
rocket_sound()
end
return itemstack
end,
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 B

View File

@ -7,12 +7,12 @@ Raw fish is obtained by fishing and is a food item which can be eaten safely. Co
Cooked Fish=Gekochter Fisch Cooked Fish=Gekochter Fisch
Mmh, fish! This is a healthy food item.=Mhh, Fisch! Ein gesundes Lebensmittel. Mmh, fish! This is a healthy food item.=Mhh, Fisch! Ein gesundes Lebensmittel.
Raw Salmon=Roher Lachs Raw Salmon=Roher Lachs
Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Rohen Lachs erhält man beim Angeln. Er ist ein Lebensmittel, das sicher verzehrt werden kann. Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Lohen Lachs erhält man beim Angeln. Er ist ein Lebensmittel, der sicher verzehrt werden kann.
Cooked Salmon=Gekochter Lachs Cooked Salmon=Gekochter Lachs
This is a healthy food item which can be eaten.=Ein gesundes essbares Lebensmittel. This is a healthy food item which can be eaten.=Ein gesundes essbares Lebensmittel.
Clownfish=Clownfisch Clownfish=Clownfisch
Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Einen Clownfisch kann man beim Angeln mit etwas Glück fangen. Er ist ein Lebensmittel, das sicher verzehrt werden kann. Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Einen Clownfisch kann man beim Angeln mit etwas Glück fangen. Er ist ein Lebensmittel, der sicher verzehrt werden kann.
Pufferfish=Kugelfisch Pufferfish=Kugelfisch
Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=Kugelfische sind eine verbreitete Fischart, die geangelt werden kann. Sie können theoretisch gegessen werden, aber sie sind sehr schlecht für Menschen. Es gibt nur 1 Hungerpunkt und es wird Sie schwer vergiften (was Ihre Gesundheit verringert, aber nicht bis zum Tod) und Ihr Hungerpegel wird aufgrund der schweren Lebensmittelvergiftung stark ansteigen. Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=Kugelfische sind eine verbreitete Fischart, die geangelt werden können. Sie können theoretisch gegessen werden, aber sie sind sehr schlecht für Menschen. Es gibt nur 1 Hungerpunkt und es wird Sie schwer vergiften (was Ihre Gesundheit verringert, aber nicht bis zum Tod) und Ihr Hungerpegel wird aufgrund der schweren Lebensmittelvergiftung stark ansteigen.
Catches fish in water=Fängt Fische im Wasser Catches fish in water=Fängt Fische im Wasser
Very poisonous=Sehr giftig Very poisonous=Sehr giftig

View File

@ -12,9 +12,9 @@ Allium=Sternlauch
Azure Bluet=Porzellansternchen Azure Bluet=Porzellansternchen
Blue Orchid=Blaue Orchidee Blue Orchid=Blaue Orchidee
Tall Grass=Hohes Gras Tall Grass=Hohes Gras
Tall grass is a small plant which often occurs on the surface of grasslands. It can be harvested for wheat seeds. By using bone meal, tall grass can be turned into double tallgrass which is two blocks high.=Hohes Gras ist eine kleine Pflanze, die oft auf Wiesenflächen wächst. Es kann für Weizensamen abgeerntet werden. Mit Knochenmehl lässt sich hohes Gras zu doppelhohem Gras verwandeln. Tall grass is a small plant which often occurs on the surface of grasslands. It can be harvested for wheat seeds. By using bone meal, tall grass can be turned into double tallgrass which is two blocks high.=Hohes Gras ist eine kleine Pflanze, die oft auf Wiesenflächen wächst. Es kann für Weizensamen abgeerntet werden. Mit Knochenmehl wird sich hohes Gras zu doppelhohem Gras verwandeln.
Fern=Farn Fern=Farn
Ferns are small plants which occur naturally in jungles and taigas. They can be harvested for wheat seeds. By using bone meal, a fern can be turned into a large fern which is two blocks high.=Farne sind kleine Pflanzen, die oft in Dschungeln und Taigas vorkommen. Sie können für Weizensamen abgeerntet werden. Mit Knochenmehl lässt sich ein Farn zu einem großen Farn, der zwei Blöcke hoch ist, verwandeln. Ferns are small plants which occur naturally in jungles and taigas. They can be harvested for wheat seeds. By using bone meal, a fern can be turned into a large fern which is two blocks high.=Farne sind kleine Pflanzen, die oft in Dschungeln und Taigas vorkommen. Sie können für Weizensamen abgeerntet werden. Mit Knochenmehl wird sich ein Farn zu einem großen Farn, der zwei Blöcke hoch ist, verwandeln.
(Top Part)=(Oberseite) (Top Part)=(Oberseite)
Peony=Pfingstrose Peony=Pfingstrose
A peony is a large plant which occupies two blocks. It is mainly used in dye production.=Eine Pfingstrose ist eine große Pflanze, die zwei Blöcke hoch ist. Sie wird hauptsächlich für die Farbenproduktion gebraucht. A peony is a large plant which occupies two blocks. It is mainly used in dye production.=Eine Pfingstrose ist eine große Pflanze, die zwei Blöcke hoch ist. Sie wird hauptsächlich für die Farbenproduktion gebraucht.

View File

@ -61,7 +61,7 @@ This item is mainly used for crafting.=Dieser Gegenstand wird hauptsächlich in
Magma Cream=Magmacreme Magma Cream=Magmacreme
Magma cream is a crafting component.=Magmacreme ist eine Fertigungskomponente. Magma cream is a crafting component.=Magmacreme ist eine Fertigungskomponente.
Ghast Tear=Ghast-Träne Ghast Tear=Ghast-Träne
Place this item in an item frame as decoration.=Platzieren Sie diesen Gegenstand in einem Rahmen als Deko. Place this item in an item frame as decoration.=Platzieren Sie diesen Gegenstand in einem Rahmel als Deko.
Nether Star=Nether-Stern Nether Star=Nether-Stern
A nether star is dropped when the Wither dies. Place it in an item frame to show the world how hardcore you are! Or just as decoration.=Ein Netherstern wird abgeworfen, wenn der Wither stirbt. Platzieren Sie ihn in einen Rahmen, um der Welt zu zeigen, wie großartig Sie sind! A nether star is dropped when the Wither dies. Place it in an item frame to show the world how hardcore you are! Or just as decoration.=Ein Netherstern wird abgeworfen, wenn der Wither stirbt. Platzieren Sie ihn in einen Rahmen, um der Welt zu zeigen, wie großartig Sie sind!

View File

@ -176,7 +176,7 @@ minetest.register_node("mcl_nether:nether_wart_block", {
stack_max = 64, stack_max = 64,
tiles = {"mcl_nether_nether_wart_block.png"}, tiles = {"mcl_nether_nether_wart_block.png"},
is_ground_content = false, is_ground_content = false,
groups = {handy=1, hoey=1, building_block=1}, groups = {handy=1, building_block=1},
sounds = mcl_sounds.node_sound_leaves_defaults( sounds = mcl_sounds.node_sound_leaves_defaults(
{ {
footstep={name="default_dirt_footstep", gain=0.7}, footstep={name="default_dirt_footstep", gain=0.7},

View File

@ -779,7 +779,7 @@ minetest.register_node("mcl_ocean:dried_kelp_block", {
description = S("Dried Kelp Block"), description = S("Dried Kelp Block"),
_doc_items_longdesc = S("A decorative block that serves as a great furnace fuel."), _doc_items_longdesc = S("A decorative block that serves as a great furnace fuel."),
tiles = { "mcl_ocean_dried_kelp_top.png", "mcl_ocean_dried_kelp_bottom.png", "mcl_ocean_dried_kelp_side.png" }, tiles = { "mcl_ocean_dried_kelp_top.png", "mcl_ocean_dried_kelp_bottom.png", "mcl_ocean_dried_kelp_side.png" },
groups = { handy = 1, hoey = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 }, groups = { handy = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 },
sounds = mcl_sounds.node_sound_leaves_defaults(), sounds = mcl_sounds.node_sound_leaves_defaults(),
paramtype2 = "facedir", paramtype2 = "facedir",
on_place = mcl_util.rotate_axis, on_place = mcl_util.rotate_axis,

View File

@ -701,10 +701,6 @@ function mcl_potions.healing_func(player, hp)
local obj = player:get_luaentity() local obj = player:get_luaentity()
if player:get_hp() == 0 then
return
end
if obj and obj.harmed_by_heal then hp = -hp end if obj and obj.harmed_by_heal then hp = -hp end
if hp > 0 then if hp > 0 then

View File

@ -48,7 +48,7 @@ minetest.register_node("mcl_sponges:sponge", {
buildable_to = false, buildable_to = false,
stack_max = 64, stack_max = 64,
sounds = mcl_sounds.node_sound_dirt_defaults(), sounds = mcl_sounds.node_sound_dirt_defaults(),
groups = {handy=1, hoey=1, building_block=1}, groups = {handy=1, building_block=1},
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
local pn = placer:get_player_name() local pn = placer:get_player_name()
if pointed_thing.type ~= "node" then if pointed_thing.type ~= "node" then
@ -136,7 +136,7 @@ minetest.register_node("mcl_sponges:sponge_wet", {
buildable_to = false, buildable_to = false,
stack_max = 64, stack_max = 64,
sounds = mcl_sounds.node_sound_dirt_defaults(), sounds = mcl_sounds.node_sound_dirt_defaults(),
groups = {handy=1, hoey=1, building_block=1}, groups = {handy=1, building_block=1},
on_place = place_wet_sponge, on_place = place_wet_sponge,
_mcl_blast_resistance = 0.6, _mcl_blast_resistance = 0.6,
_mcl_hardness = 0.6, _mcl_hardness = 0.6,

View File

@ -51,7 +51,6 @@ minetest.register_tool(":", {
handy = { speed = 1, level = 1, uses = 0 }, handy = { speed = 1, level = 1, uses = 0 },
axey = { speed = 1, level = 1, uses = 0 }, axey = { speed = 1, level = 1, uses = 0 },
shovely = { speed = 1, level = 1, uses = 0 }, shovely = { speed = 1, level = 1, uses = 0 },
hoey = { speed = 1, level = 1, uses = 0 },
pickaxey = { speed = 1, level = 0, uses = 0 }, pickaxey = { speed = 1, level = 0, uses = 0 },
swordy = { speed = 1, level = 0, uses = 0 }, swordy = { speed = 1, level = 0, uses = 0 },
swordy_cobweb = { speed = 1, level = 0, uses = 0 }, swordy_cobweb = { speed = 1, level = 0, uses = 0 },
@ -352,56 +351,6 @@ minetest.register_tool("mcl_tools:shovel_diamond", {
}) })
-- Axes -- Axes
local make_stripped_trunk = function(itemstack, placer, pointed_thing)
if pointed_thing.type == "node" then
local pos = minetest.get_pointed_thing_position(pointed_thing)
local node = minetest.get_node(pos)
local node_name = node.name
if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[node_name] and minetest.registered_nodes[node_name].on_rightclick then
return minetest.registered_nodes[node_name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
end
end
if minetest.is_protected(pointed_thing.under, placer:get_player_name()) then
minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
return itemstack
end
if not minetest.is_creative_enabled(placer:get_player_name()) then
-- Add wear (as if digging a axey node)
local toolname = itemstack:get_name()
local wear = mcl_autogroup.get_wear(toolname, "axey")
itemstack:add_wear(wear)
end
if node_name == "mcl_core:tree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_oak"})
elseif node_name == "mcl_core:darktree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_dark_oak"})
elseif node_name == "mcl_core:acaciatree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_acacia"})
elseif node_name == "mcl_core:birchtree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_birch"})
elseif node_name == "mcl_core:sprucetree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_spruce"})
elseif node_name == "mcl_core:jungletree" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_jungle"})
elseif node_name == "mcl_core:tree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_oak_bark"})
elseif node_name == "mcl_core:darktree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_dark_oak_bark"})
elseif node_name == "mcl_core:acaciatree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_acacia_bark"})
elseif node_name == "mcl_core:birchtree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_birch_bark"})
elseif node_name == "mcl_core:sprucetree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_spruce_bark"})
elseif node_name == "mcl_core:jungletree_bark" then
minetest.swap_node(pointed_thing.under, {name="mcl_core:stripped_jungle_bark"})
end
end
return itemstack
end
minetest.register_tool("mcl_tools:axe_wood", { minetest.register_tool("mcl_tools:axe_wood", {
description = S("Wooden Axe"), description = S("Wooden Axe"),
_doc_items_longdesc = axe_longdesc, _doc_items_longdesc = axe_longdesc,
@ -415,7 +364,6 @@ minetest.register_tool("mcl_tools:axe_wood", {
damage_groups = {fleshy=7}, damage_groups = {fleshy=7},
punch_attack_uses = 30, punch_attack_uses = 30,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "group:wood", _repair_material = "group:wood",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
@ -435,7 +383,6 @@ minetest.register_tool("mcl_tools:axe_stone", {
damage_groups = {fleshy=9}, damage_groups = {fleshy=9},
punch_attack_uses = 66, punch_attack_uses = 66,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:cobble", _repair_material = "mcl_core:cobble",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
@ -456,7 +403,6 @@ minetest.register_tool("mcl_tools:axe_iron", {
damage_groups = {fleshy=9}, damage_groups = {fleshy=9},
punch_attack_uses = 126, punch_attack_uses = 126,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:iron_ingot", _repair_material = "mcl_core:iron_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
@ -476,7 +422,6 @@ minetest.register_tool("mcl_tools:axe_gold", {
damage_groups = {fleshy=7}, damage_groups = {fleshy=7},
punch_attack_uses = 17, punch_attack_uses = 17,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:gold_ingot", _repair_material = "mcl_core:gold_ingot",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,
@ -496,7 +441,6 @@ minetest.register_tool("mcl_tools:axe_diamond", {
damage_groups = {fleshy=9}, damage_groups = {fleshy=9},
punch_attack_uses = 781, punch_attack_uses = 781,
}, },
on_place = make_stripped_trunk,
sound = { breaks = "default_tool_breaks" }, sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:diamond", _repair_material = "mcl_core:diamond",
_mcl_toollike_wield = true, _mcl_toollike_wield = true,

View File

@ -1,267 +0,0 @@
local smoke_pdef = {
amount = 0.5,
maxexptime = 2.0,
minvel = { x = 0.0, y = 0.5, z = 0.0 },
maxvel = { x = 0.0, y = 0.6, z = 0.0 },
minsize = 1.5,
maxsize = 1.5,
minrelpos = { x = -1/16, y = 0.04, z = -1/16 },
maxrelpos = { x = 1/16, y = 0.06, z = 1/16 },
}
local spawn_flames_floor = function(pos)
-- Flames
mcl_particles.add_node_particlespawner(pos, {
amount = 8,
time = 0,
minpos = vector.add(pos, { x = -0.1, y = 0.05, z = -0.1 }),
maxpos = vector.add(pos, { x = 0.1, y = 0.15, z = 0.1 }),
minvel = { x = -0.01, y = 0, z = -0.01 },
maxvel = { x = 0.01, y = 0.1, z = 0.01 },
minexptime = 0.3,
maxexptime = 0.6,
minsize = 0.7,
maxsize = 2,
texture = "mcl_particles_flame.png",
glow = minetest.registered_nodes[minetest.get_node(pos).name].light_source,
}, "low")
-- Smoke
mcl_particles.spawn_smoke(pos, "torch", smoke_pdef)
end
local spawn_flames_wall = function(pos)
local minrelpos, maxrelpos
local node = minetest.get_node(pos)
local dir = minetest.wallmounted_to_dir(node.param2)
local smoke_pdef = table.copy(smoke_pdef)
if dir.x < 0 then
smoke_pdef.minrelpos = { x = -0.38, y = 0.04, z = -0.1 }
smoke_pdef.maxrelpos = { x = -0.2, y = 0.14, 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 }
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 }
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 }
else
return
end
-- Flames
mcl_particles.add_node_particlespawner(pos, {
amount = 8,
time = 0,
minpos = vector.add(pos, smoke_pdef.minrelpos),
maxpos = vector.add(pos, smoke_pdef.maxrelpos),
minvel = { x = -0.01, y = 0, z = -0.01 },
maxvel = { x = 0.01, y = 0.1, z = 0.01 },
minexptime = 0.3,
maxexptime = 0.6,
minsize = 0.7,
maxsize = 2,
texture = "mcl_particles_flame.png",
glow = minetest.registered_nodes[node.name].light_source,
}, "low")
-- Smoke
mcl_particles.spawn_smoke(pos, "torch", smoke_pdef)
end
local remove_flames = function(pos)
mcl_particles.delete_node_particlespawners(pos)
end
--
-- 3d torch part
--
-- Check if placement at given node is allowed
local function check_placement_allowed(node, wdir)
-- Torch placement rules: Disallow placement on some nodes. General rule: Solid, opaque, full cube collision box nodes are allowed.
-- Special allowed nodes:
-- * soul sand
-- * mob spawner
-- * chorus flower
-- * glass, barrier, ice
-- * Fence, wall, end portal frame with ender eye: Only on top
-- * Slab, stairs: Only on top if upside down
-- Special forbidden nodes:
-- * Piston, sticky piston
local def = minetest.registered_nodes[node.name]
if not def then
return false
-- No ceiling torches
elseif wdir == 0 then
return false
elseif not def.buildable_to then
if node.name ~= "mcl_core:ice" and node.name ~= "mcl_nether:soul_sand" and node.name ~= "mcl_mobspawners:spawner" and node.name ~= "mcl_core:barrier" and node.name ~= "mcl_end:chorus_flower" and node.name ~= "mcl_end:chorus_flower_dead" and (not def.groups.glass) and
((not def.groups.solid) or (not def.groups.opaque)) then
-- Only allow top placement on these nodes
if node.name == "mcl_end:dragon_egg" or node.name == "mcl_portals:end_portal_frame_eye" or def.groups.fence == 1 or def.groups.wall or def.groups.slab_top == 1 or def.groups.anvil or def.groups.pane or (def.groups.stair == 1 and minetest.facedir_to_dir(node.param2).y ~= 0) then
if wdir ~= 1 then
return false
end
else
return false
end
elseif minetest.get_item_group(node.name, "piston") >= 1 then
return false
end
end
return true
end
function mcl_torches.register_torch(def)
local itemstring = minetest.get_current_modname() .. ":" .. def.name
local itemstring_wall = itemstring .. "_wall"
def.light = def.light or minetest.LIGHT_MAX
def.mesh_floor = def.mesh_floor or "mcl_torches_torch_floor.obj"
def.mesh_wall = def.mesh_wall or "mcl_torches_torch_wall.obj"
local groups = def.groups or {}
groups.attached_node = 1
groups.torch = 1
groups.torch_particles = def.particles and 1
groups.dig_by_water = 1
groups.destroy_by_lava_flow = 1
groups.dig_by_piston = 1
local floordef = {
description = def.description,
_doc_items_longdesc = def.doc_items_longdesc,
_doc_items_usagehelp = def.doc_items_usagehelp,
_doc_items_hidden = def.doc_items_hidden,
_doc_items_create_entry = def._doc_items_create_entry,
drawtype = "mesh",
mesh = def.mesh_floor,
inventory_image = def.icon,
wield_image = def.icon,
tiles = def.tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
is_ground_content = false,
walkable = false,
liquids_pointable = false,
light_source = def.light,
groups = groups,
drop = def.drop or itemstring,
selection_box = {
type = "wallmounted",
wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16},
wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16},
},
sounds = def.sounds,
node_placement_prediction = "",
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
-- no interaction possible with entities, for now.
return itemstack
end
local under = pointed_thing.under
local node = minetest.get_node(under)
local def = minetest.registered_nodes[node.name]
if not def then return itemstack end
-- Call on_rightclick if the pointed node defines it
if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack
end
end
local above = pointed_thing.above
local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z})
if check_placement_allowed(node, wdir) == false then
return itemstack
end
local itemstring = itemstack:get_name()
local fakestack = ItemStack(itemstack)
local idef = fakestack:get_definition()
local retval
if wdir == 1 then
retval = fakestack:set_name(itemstring)
else
retval = fakestack:set_name(itemstring_wall)
end
if not retval then
return itemstack
end
local success
itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir)
itemstack:set_name(itemstring)
if success and idef.sounds and idef.sounds.place then
minetest.sound_play(idef.sounds.place, {pos=under, gain=1}, true)
end
return itemstack
end,
on_rotate = false,
on_construct = def.particles and spawn_flames_floor,
on_destruct = def.particles and remove_flames,
}
minetest.register_node(itemstring, floordef)
local groups_wall = table.copy(groups)
groups_wall.torch = 2
local walldef = {
drawtype = "mesh",
mesh = def.mesh_wall,
tiles = def.tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
is_ground_content = false,
walkable = false,
light_source = def.light,
groups = groups_wall,
drop = def.drop or itemstring,
selection_box = {
type = "wallmounted",
wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1},
wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1},
wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1},
},
sounds = def.sounds,
on_rotate = false,
on_construct = def.particles and spawn_flames_wall,
on_destruct = def.particles and remove_flames,
}
minetest.register_node(itemstring_wall, walldef)
-- Add entry alias for the Help
if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", itemstring, "nodes", itemstring_wall)
end
end
minetest.register_lbm({
label = "Torch flame particles",
name = "mcl_torches:flames",
nodenames = {"group:torch_particles"},
run_at_every_load = true,
action = function(pos, node)
local torch_group = minetest.get_node_group(node.name, "torch")
if torch_group == 1 then
spawn_flames_floor(pos)
elseif torch_group == 2 then
spawn_flames_wall(pos)
end
end,
})

View File

@ -1,6 +1,338 @@
local S = minetest.get_translator("mcl_torches")
local LIGHT_TORCH = minetest.LIGHT_MAX
local spawn_flames_floor = function(pos)
-- Flames
mcl_particles.add_node_particlespawner(pos, {
amount = 8,
time = 0,
minpos = vector.add(pos, { x = -0.1, y = 0.05, z = -0.1 }),
maxpos = vector.add(pos, { x = 0.1, y = 0.15, z = 0.1 }),
minvel = { x = -0.01, y = 0, z = -0.01 },
maxvel = { x = 0.01, y = 0.1, z = 0.01 },
minexptime = 0.3,
maxexptime = 0.6,
minsize = 0.7,
maxsize = 2,
texture = "mcl_particles_flame.png",
glow = LIGHT_TORCH,
}, "low")
-- Smoke
mcl_particles.add_node_particlespawner(pos, {
amount = 0.5,
time = 0,
minpos = vector.add(pos, { x = -1/16, y = 0.04, z = -1/16 }),
maxpos = vector.add(pos, { x = -1/16, y = 0.06, z = -1/16 }),
minvel = { x = 0, y = 0.5, z = 0 },
maxvel = { x = 0, y = 0.6, z = 0 },
minexptime = 2.0,
maxexptime = 2.0,
minsize = 1.5,
maxsize = 1.5,
texture = "mcl_particles_smoke_anim.png",
animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
length = 2.05,
},
}, "medium")
end
local spawn_flames_wall = function(pos, param2)
local minrelpos, maxrelpos
local dir = minetest.wallmounted_to_dir(param2)
if dir.x < 0 then
minrelpos = { x = -0.38, y = 0.04, z = -0.1 }
maxrelpos = { x = -0.2, y = 0.14, z = 0.1 }
elseif dir.x > 0 then
minrelpos = { x = 0.2, y = 0.04, z = -0.1 }
maxrelpos = { x = 0.38, y = 0.14, z = 0.1 }
elseif dir.z < 0 then
minrelpos = { x = -0.1, y = 0.04, z = -0.38 }
maxrelpos = { x = 0.1, y = 0.14, z = -0.2 }
elseif dir.z > 0 then
minrelpos = { x = -0.1, y = 0.04, z = 0.2 }
maxrelpos = { x = 0.1, y = 0.14, z = 0.38 }
else
return
end
-- Flames
mcl_particles.add_node_particlespawner(pos, {
amount = 8,
time = 0,
minpos = vector.add(pos, minrelpos),
maxpos = vector.add(pos, maxrelpos),
minvel = { x = -0.01, y = 0, z = -0.01 },
maxvel = { x = 0.01, y = 0.1, z = 0.01 },
minexptime = 0.3,
maxexptime = 0.6,
minsize = 0.7,
maxsize = 2,
texture = "mcl_particles_flame.png",
glow = LIGHT_TORCH,
}, "low")
-- Smoke
mcl_particles.add_node_particlespawner(pos, {
amount = 0.5,
time = 0,
minpos = vector.add(pos, minrelpos),
maxpos = vector.add(pos, maxrelpos),
minvel = { x = 0, y = 0.5, z = 0 },
maxvel = { x = 0, y = 0.6, z = 0 },
minexptime = 2.0,
maxexptime = 2.0,
minsize = 1.5,
maxsize = 1.5,
texture = "mcl_particles_smoke_anim.png",
animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
length = 2.05,
},
}, "medium")
end
local remove_flames = function(pos)
mcl_particles.delete_node_particlespawners(pos)
end
--
-- 3d torch part
--
-- Check if placement at given node is allowed
local function check_placement_allowed(node, wdir)
-- Torch placement rules: Disallow placement on some nodes. General rule: Solid, opaque, full cube collision box nodes are allowed.
-- Special allowed nodes:
-- * soul sand
-- * mob spawner
-- * chorus flower
-- * glass, barrier, ice
-- * Fence, wall, end portal frame with ender eye: Only on top
-- * Slab, stairs: Only on top if upside down
-- Special forbidden nodes:
-- * Piston, sticky piston
local def = minetest.registered_nodes[node.name]
if not def then
return false
-- No ceiling torches
elseif wdir == 0 then
return false
elseif not def.buildable_to then
if node.name ~= "mcl_core:ice" and node.name ~= "mcl_nether:soul_sand" and node.name ~= "mcl_mobspawners:spawner" and node.name ~= "mcl_core:barrier" and node.name ~= "mcl_end:chorus_flower" and node.name ~= "mcl_end:chorus_flower_dead" and (not def.groups.glass) and
((not def.groups.solid) or (not def.groups.opaque)) then
-- Only allow top placement on these nodes
if node.name == "mcl_end:dragon_egg" or node.name == "mcl_portals:end_portal_frame_eye" or def.groups.fence == 1 or def.groups.wall or def.groups.slab_top == 1 or def.groups.anvil or def.groups.pane or (def.groups.stair == 1 and minetest.facedir_to_dir(node.param2).y ~= 0) then
if wdir ~= 1 then
return false
end
else
return false
end
elseif minetest.get_item_group(node.name, "piston") >= 1 then
return false
end
end
return true
end
mcl_torches = {} mcl_torches = {}
local modpath = minetest.get_modpath("mcl_torches") mcl_torches.register_torch = function(substring, description, doc_items_longdesc, doc_items_usagehelp, icon, mesh_floor, mesh_wall, tiles, light, groups, sounds, moredef, moredef_floor, moredef_wall)
local itemstring = minetest.get_current_modname()..":"..substring
local itemstring_wall = minetest.get_current_modname()..":"..substring.."_wall"
if light == nil then light = minetest.LIGHT_MAX end
if mesh_floor == nil then mesh_floor = "mcl_torches_torch_floor.obj" end
if mesh_wall == nil then mesh_wall = "mcl_torches_torch_wall.obj" end
if groups == nil then groups = {} end
groups.attached_node = 1
groups.torch = 1
groups.dig_by_water = 1
groups.destroy_by_lava_flow = 1
groups.dig_by_piston = 1
local floordef = {
description = description,
_doc_items_longdesc = doc_items_longdesc,
_doc_items_usagehelp = doc_items_usagehelp,
drawtype = "mesh",
mesh = mesh_floor,
inventory_image = icon,
wield_image = icon,
tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
is_ground_content = false,
walkable = false,
liquids_pointable = false,
light_source = light,
groups = groups,
drop = itemstring,
selection_box = {
type = "wallmounted",
wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16},
wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16},
},
sounds = sounds,
node_placement_prediction = "",
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
-- no interaction possible with entities, for now.
return itemstack
end
local under = pointed_thing.under
local node = minetest.get_node(under)
local def = minetest.registered_nodes[node.name]
if not def then return itemstack end
-- Call on_rightclick if the pointed node defines it
if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(under, node, placer, itemstack) or itemstack
end
end
local above = pointed_thing.above
local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z})
if check_placement_allowed(node, wdir) == false then
return itemstack
end
local itemstring = itemstack:get_name()
local fakestack = ItemStack(itemstack)
local idef = fakestack:get_definition()
local retval
if wdir == 1 then
retval = fakestack:set_name(itemstring)
else
retval = fakestack:set_name(itemstring_wall)
end
if not retval then
return itemstack
end
local success
itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir)
itemstack:set_name(itemstring)
if success and idef.sounds and idef.sounds.place then
minetest.sound_play(idef.sounds.place, {pos=under, gain=1}, true)
end
return itemstack
end,
on_rotate = false,
}
if moredef ~= nil then
for k,v in pairs(moredef) do
floordef[k] = v
end
end
if moredef_floor ~= nil then
for k,v in pairs(moredef_floor) do
floordef[k] = v
end
end
minetest.register_node(itemstring, floordef)
local groups_wall = table.copy(groups)
groups_wall.torch = 2
local walldef = {
drawtype = "mesh",
mesh = mesh_wall,
tiles = tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
is_ground_content = false,
walkable = false,
light_source = light,
groups = groups_wall,
drop = itemstring,
selection_box = {
type = "wallmounted",
wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1},
wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1},
wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1},
},
sounds = sounds,
on_rotate = false,
}
if moredef ~= nil then
for k,v in pairs(moredef) do
walldef[k] = v
end
end
if moredef_wall ~= nil then
for k,v in pairs(moredef_wall) do
walldef[k] = v
end
end
minetest.register_node(itemstring_wall, walldef)
-- Add entry alias for the Help
if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", itemstring, "nodes", itemstring_wall)
end
end
mcl_torches.register_torch("torch",
S("Torch"),
S("Torches are light sources which can be placed at the side or on the top of most blocks."),
nil,
"default_torch_on_floor.png",
"mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj",
{{
name = "default_torch_on_floor_animated.png",
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3}
}},
LIGHT_TORCH,
{dig_immediate=3, torch=1, deco_block=1},
mcl_sounds.node_sound_wood_defaults(),
{_doc_items_hidden = false,
on_destruct = function(pos)
remove_flames(pos)
end},
{on_construct = function(pos)
spawn_flames_floor(pos)
end},
{on_construct = function(pos)
local node = minetest.get_node(pos)
spawn_flames_wall(pos, node.param2)
end})
minetest.register_craft({
output = "mcl_torches:torch 4",
recipe = {
{ "group:coal" },
{ "mcl_core:stick" },
}
})
minetest.register_lbm({
label = "Torch flame particles",
name = "mcl_torches:flames",
nodenames = {"mcl_torches:torch", "mcl_torches:torch_wall"},
run_at_every_load = true,
action = function(pos, node)
if node.name == "mcl_torches:torch" then
spawn_flames_floor(pos)
elseif node.name == "mcl_torches:torch_wall" then
spawn_flames_wall(pos, node.param2)
end
end,
})
dofile(modpath .. "/api.lua")
dofile(modpath .. "/register.lua")

View File

@ -1,27 +0,0 @@
local S = minetest.get_translator("mcl_torches")
mcl_torches.register_torch({
name = "torch",
description = S("Torch"),
doc_items_longdesc = S("Torches are light sources which can be placed at the side or on the top of most blocks."),
doc_items_hidden = false,
icon = "default_torch_on_floor.png",
tiles = {{
name = "default_torch_on_floor_animated.png",
animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3}
}},
-- this is 15 in minecraft
light = 14,
groups = {dig_immediate = 3, deco_block = 1},
sounds = mcl_sounds.node_sound_wood_defaults(),
particles = true,
})
minetest.register_craft({
output = "mcl_torches:torch 4",
recipe = {
{"group:coal"},
{"mcl_core:stick"},
}
})

View File

@ -22,7 +22,7 @@ Blue Carpet=Blauer Teppich
Magenta Wool=Magenta Wolle Magenta Wool=Magenta Wolle
Magenta Carpet=Magenta Teppich Magenta Carpet=Magenta Teppich
Orange Wool=Orange Wolle Orange Wool=Orange Wolle
Orange Carpet=Oranger Teppich Orange Carpet=Orange Teppich
Purple Wool=Violette Wolle Purple Wool=Violette Wolle
Purple Carpet=Violetter Teppich Purple Carpet=Violetter Teppich
Brown Wool=Braune Wolle Brown Wool=Braune Wolle

View File

@ -1,2 +1,2 @@
# textdomain: screwdriver # textdomain: screwdriver
Screwdriver=Schraubenzieher Screwdriver=Schraubendreher

View File

@ -9,38 +9,15 @@ if mcl_vars.mg_dungeons == false or mg_name == "singlenode" then
return return
end end
--lua locals local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1
--minetest local max_y = mcl_vars.mg_overworld_max - 1
local registered_nodes = minetest.registered_nodes
local swap_node = minetest.swap_node
local set_node = minetest.set_node
local dir_to_facedir = minetest.dir_to_facedir
local get_meta = minetest.get_meta
local emerge_area = minetest.emerge_area
--vector
local vector_add = vector.add
local vector_subtract = vector.subtract
--table
local table_insert = table.insert
local table_sort = table.sort
--math
local math_min = math.min
local math_max = math.max
local math_ceil = math.ceil
--custom mcl_vars
local get_node = mcl_vars.get_node local get_node = mcl_vars.get_node
local min_y = math_max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1
local max_y = mcl_vars.mg_overworld_max - 1
-- Calculate the number of dungeon spawn attempts -- Calculate the number of dungeon spawn attempts
-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks). -- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks).
-- Minetest chunks don't have this size, so scale the number accordingly. -- Minetest chunks don't have this size, so scale the number accordingly.
local attempts = math_ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192 local attempts = math.ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192
local dungeonsizes = { local dungeonsizes = {
{ x=5, y=4, z=5}, { x=5, y=4, z=5},
@ -74,8 +51,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
local y_floor = y local y_floor = y
local y_ceiling = y + dim.y + 1 local y_ceiling = y + dim.y + 1
if check then for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do if check then for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do
if not registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable if not minetest.registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable
or not registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end or not minetest.registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
end end end end end end
-- Check for air openings (2 stacked air at ground level) in wall positions -- Check for air openings (2 stacked air at ground level) in wall positions
@ -92,25 +69,25 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
openings_counter = openings_counter + 1 openings_counter = openings_counter + 1
if not openings[x] then openings[x]={} end if not openings[x] then openings[x]={} end
openings[x][z] = true openings[x][z] = true
table_insert(corners, {x=x, z=z}) table.insert(corners, {x=x, z=z})
end end
if get_node({x=x2, y=y+1, z=z}).name == "air" and get_node({x=x2, y=y+2, z=z}).name == "air" then if get_node({x=x2, y=y+1, z=z}).name == "air" and get_node({x=x2, y=y+2, z=z}).name == "air" then
openings_counter = openings_counter + 1 openings_counter = openings_counter + 1
if not openings[x2] then openings[x2]={} end if not openings[x2] then openings[x2]={} end
openings[x2][z] = true openings[x2][z] = true
table_insert(corners, {x=x2, z=z}) table.insert(corners, {x=x2, z=z})
end end
if get_node({x=x, y=y+1, z=z2}).name == "air" and get_node({x=x, y=y+2, z=z2}).name == "air" then if get_node({x=x, y=y+1, z=z2}).name == "air" and get_node({x=x, y=y+2, z=z2}).name == "air" then
openings_counter = openings_counter + 1 openings_counter = openings_counter + 1
if not openings[x] then openings[x]={} end if not openings[x] then openings[x]={} end
openings[x][z2] = true openings[x][z2] = true
table_insert(corners, {x=x, z=z2}) table.insert(corners, {x=x, z=z2})
end end
if get_node({x=x2, y=y+1, z=z2}).name == "air" and get_node({x=x2, y=y+2, z=z2}).name == "air" then if get_node({x=x2, y=y+1, z=z2}).name == "air" and get_node({x=x2, y=y+2, z=z2}).name == "air" then
openings_counter = openings_counter + 1 openings_counter = openings_counter + 1
if not openings[x2] then openings[x2]={} end if not openings[x2] then openings[x2]={} end
openings[x2][z2] = true openings[x2][z2] = true
table_insert(corners, {x=x2, z=z2}) table.insert(corners, {x=x2, z=z2})
end end
for wx = x+1, x+dim.x do for wx = x+1, x+dim.x do
@ -203,16 +180,16 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
secondChance = false secondChance = false
end end
lastRandom = r lastRandom = r
table_insert(chestSlots, r) table.insert(chestSlots, r)
end end
table_sort(chestSlots) table.sort(chestSlots)
local currentChest = 1 local currentChest = 1
-- Calculate the mob spawner position, to be re-used for later -- Calculate the mob spawner position, to be re-used for later
local sp = {x = x + math_ceil(dim.x/2), y = y+1, z = z + math_ceil(dim.z/2)} local sp = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)}
local rn = registered_nodes[get_node(sp).name] local rn = minetest.registered_nodes[get_node(sp).name]
if rn and rn.is_ground_content then if rn and rn.is_ground_content then
table_insert(spawner_posses, sp) table.insert(spawner_posses, sp)
end end
-- Generate walls and floor -- Generate walls and floor
@ -226,13 +203,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
-- Do not overwrite nodes with is_ground_content == false (e.g. bedrock) -- Do not overwrite nodes with is_ground_content == false (e.g. bedrock)
-- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other -- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other
local name = get_node(p).name local name = get_node(p).name
if registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then if minetest.registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then
-- Floor -- Floor
if ty == y then if ty == y then
if pr:next(1,4) == 1 then if pr:next(1,4) == 1 then
swap_node(p, {name = "mcl_core:cobble"}) minetest.swap_node(p, {name = "mcl_core:cobble"})
else else
swap_node(p, {name = "mcl_core:mossycobble"}) minetest.swap_node(p, {name = "mcl_core:mossycobble"})
end end
-- Generate walls -- Generate walls
@ -244,14 +221,14 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
-- Check if it's an opening first -- Check if it's an opening first
if (ty == maxy) or (not (openings[tx] and openings[tx][tz])) then if (ty == maxy) or (not (openings[tx] and openings[tx][tz])) then
-- Place wall or ceiling -- Place wall or ceiling
swap_node(p, {name = "mcl_core:cobble"}) minetest.swap_node(p, {name = "mcl_core:cobble"})
elseif ty < maxy - 1 then elseif ty < maxy - 1 then
-- Normally the openings are already clear, but not if it is a corner -- Normally the openings are already clear, but not if it is a corner
-- widening. Make sure to clear at least the bottom 2 nodes of an opening. -- widening. Make sure to clear at least the bottom 2 nodes of an opening.
if name ~= "air" then swap_node(p, {name = "air"}) end if name ~= "air" then minetest.swap_node(p, {name = "air"}) end
elseif name ~= "air" then elseif name ~= "air" then
-- This allows for variation between 2-node and 3-node high openings. -- This allows for variation between 2-node and 3-node high openings.
swap_node(p, {name = "mcl_core:cobble"}) minetest.swap_node(p, {name = "mcl_core:cobble"})
end end
-- If it was an opening, the lower 3 blocks are not touched at all -- If it was an opening, the lower 3 blocks are not touched at all
@ -259,9 +236,9 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
else else
if (ty==y+1) and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then if (ty==y+1) and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then
currentChest = currentChest + 1 currentChest = currentChest + 1
table_insert(chests, {x=tx, y=ty, z=tz}) table.insert(chests, {x=tx, y=ty, z=tz})
else else
swap_node(p, {name = "air"}) minetest.swap_node(p, {name = "air"})
end end
local forChest = ty==y+1 and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) local forChest = ty==y+1 and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1)
@ -269,9 +246,9 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
-- Place next chest at the wall (if it was its chosen wall slot) -- Place next chest at the wall (if it was its chosen wall slot)
if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then
currentChest = currentChest + 1 currentChest = currentChest + 1
table_insert(chests, {x=tx, y=ty, z=tz}) table.insert(chests, {x=tx, y=ty, z=tz})
-- else -- else
--swap_node(p, {name = "air"}) --minetest.swap_node(p, {name = "air"})
end end
if forChest then if forChest then
chestSlotCounter = chestSlotCounter + 1 chestSlotCounter = chestSlotCounter + 1
@ -286,15 +263,15 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
local surroundings = {} local surroundings = {}
for s=1, #surround_vectors do for s=1, #surround_vectors do
-- Detect the 4 horizontal neighbors -- Detect the 4 horizontal neighbors
local spos = vector_add(pos, surround_vectors[s]) local spos = vector.add(pos, surround_vectors[s])
local wpos = vector_subtract(pos, surround_vectors[s]) local wpos = vector.subtract(pos, surround_vectors[s])
local nodename = get_node(spos).name local nodename = get_node(spos).name
local nodename2 = get_node(wpos).name local nodename2 = get_node(wpos).name
local nodedef = registered_nodes[nodename] local nodedef = minetest.registered_nodes[nodename]
local nodedef2 = registered_nodes[nodename2] local nodedef2 = minetest.registered_nodes[nodename2]
-- The chest needs an open space in front of it and a walkable node (except chest) behind it -- The chest needs an open space in front of it and a walkable node (except chest) behind it
if nodedef and nodedef.walkable == false and nodedef2 and nodedef2.walkable == true and nodename2 ~= "mcl_chests:chest" then if nodedef and nodedef.walkable == false and nodedef2 and nodedef2.walkable == true and nodename2 ~= "mcl_chests:chest" then
table_insert(surroundings, spos) table.insert(surroundings, spos)
end end
end end
-- Set param2 (=facedir) of this chest -- Set param2 (=facedir) of this chest
@ -305,11 +282,11 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
else else
-- 1 or multiple possible open directions: Choose random facedir -- 1 or multiple possible open directions: Choose random facedir
local face_to = surroundings[pr:next(1, #surroundings)] local face_to = surroundings[pr:next(1, #surroundings)]
facedir = dir_to_facedir(vector_subtract(pos, face_to)) facedir = minetest.dir_to_facedir(vector.subtract(pos, face_to))
end end
set_node(pos, {name="mcl_chests:chest", param2=facedir}) minetest.set_node(pos, {name="mcl_chests:chest", param2=facedir})
local meta = get_meta(pos) local meta = minetest.get_meta(pos)
local loottable = local loottable =
{ {
@ -359,7 +336,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
-- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. -- Bonus loot for v6 mapgen: Otherwise unobtainable saplings.
if mg_name == "v6" then if mg_name == "v6" then
table_insert(loottable, { table.insert(loottable, {
stacks_min = 1, stacks_min = 1,
stacks_max = 3, stacks_max = 3,
items = { items = {
@ -379,7 +356,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
for s=#spawner_posses, 1, -1 do for s=#spawner_posses, 1, -1 do
local sp = spawner_posses[s] local sp = spawner_posses[s]
-- ... and place it and select a random mob -- ... and place it and select a random mob
set_node(sp, {name = "mcl_mobspawners:spawner"}) minetest.set_node(sp, {name = "mcl_mobspawners:spawner"})
local mobs = { local mobs = {
"mobs_mc:zombie", "mobs_mc:zombie",
"mobs_mc:zombie", "mobs_mc:zombie",
@ -393,7 +370,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
end end
local function dungeons_nodes(minp, maxp, blockseed) local function dungeons_nodes(minp, maxp, blockseed)
local ymin, ymax = math_max(min_y, minp.y), math_min(max_y, maxp.y) local ymin, ymax = math.max(min_y, minp.y), math.min(max_y, maxp.y)
if ymax < ymin then return false end if ymax < ymin then return false end
local pr = PseudoRandom(blockseed) local pr = PseudoRandom(blockseed)
for a=1, attempts do for a=1, attempts do
@ -405,7 +382,7 @@ local function dungeons_nodes(minp, maxp, blockseed)
local p2 = {x = x+dim.x+1, y = y+dim.y+1, z = z+dim.z+1} local p2 = {x = x+dim.x+1, y = y+dim.y+1, z = z+dim.z+1}
minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2))
local param = {p1=p1, p2=p2, dim=dim, pr=pr} local param = {p1=p1, p2=p2, dim=dim, pr=pr}
emerge_area(p1, p2, ecb_spawn_dungeon, param) minetest.emerge_area(p1, p2, ecb_spawn_dungeon, param)
end end
end end
@ -415,7 +392,7 @@ function mcl_dungeons.spawn_dungeon(p1, _, pr)
local p2 = {x = p1.x+dim.x+1, y = p1.y+dim.y+1, z = p1.z+dim.z+1} local p2 = {x = p1.x+dim.x+1, y = p1.y+dim.y+1, z = p1.z+dim.z+1}
minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2))
local param = {p1=p1, p2=p2, dim=dim, pr=pr, dontcheck=true} local param = {p1=p1, p2=p2, dim=dim, pr=pr, dontcheck=true}
emerge_area(p1, p2, ecb_spawn_dungeon, param) minetest.emerge_area(p1, p2, ecb_spawn_dungeon, param)
end end
mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999) mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999)

View File

@ -0,0 +1,23 @@
local S = minetest.get_translator("mcl_commands")
mcl_commands.register_chatcommand_alias("?", "help", false)
mcl_commands.register_chatcommand_alias("pardon", "unban", false)
mcl_commands.rename_chatcommand("stop", "shutdown", false)
mcl_commands.register_chatcommand_alias("tell", "msg", false)
mcl_commands.register_chatcommand_alias("w", "msg", false)
mcl_commands.register_chatcommand_alias("tp", "teleport", false)
mcl_commands.rename_chatcommand("clear", "clearinv", false)
mcl_commands.register_command("banlist", {
func = function(cmd)
cmd:sub("", {
func = function(name)
return true, S("Ban list: @1", minetest.get_ban_list())
end,
privs = {},
})
end,
description = S("List bans"),
params = "",
privs = minetest.chatcommands["ban"].privs,
})

View File

@ -0,0 +1,45 @@
local S = minetest.get_translator("mcl_commands")
mcl_commands.bossbar = {}
mcl_commands.bossbar.registered_dynamic = {}
local players_ids = {}
function mcl_commands.bossbar.update_by_id(id)
local def = mcl_commands.bossbar.registered_dynamic[id]
mcl_bossbars.add_bar(minetest.get_player_by_name(def.players), {text=def.text, color=def.color, percentage=def.percentage})
end
--1.13 feature
--TODO: toggle it with setting/mod
mcl_commands.register_command("bossbar", {
func = function(cmd)
cmd:sub("add :id: :string:quotestring", {
func = function(name, id, string)
mcl_commands.bossbar.registered_dynamic[id] = {text=string, color="white", percentage=100, players=nil} --set percentage to 0
return true, "Super"
end,
})
cmd:sub("set :id: players :value:word", {
func = function(name, id, value)
mcl_commands.bossbar.registered_dynamic[id].players=value
mcl_commands.bossbar.update_by_id(id)
return true
end,
})
cmd:sub("remove", {
func = function(name, target)
mcl_commands.bossbar.registered_dynamic[id] = nil
return true
end,
})
cmd:sub("get", {
func = function(name, target)
return true
end,
})
end,
description = "Can add, configure or remove a custom bossbar.",
params = S("[<target>]"),
privs = {server = true},
})

View File

@ -0,0 +1,9 @@
--Basic commands for mcl2
local modpath = minetest.get_modpath(minetest.get_current_modname())
for _,filename in pairs({"kill", "setblock", "seed", "summon", "say", "list", "sound", "title", "bossbar"}) do
dofile(modpath.."/"..filename..".lua")
end
dofile(modpath.."/alias.lua")

View File

@ -41,19 +41,20 @@ local function handle_kill_command(suspect, victim)
return true return true
end end
if minetest.registered_chatcommands["kill"] then mcl_commands.override_command("kill", {
minetest.unregister_chatcommand("kill") func = function(cmd)
end cmd:sub("", {
minetest.register_chatcommand("kill", { func = function(name)
params = S("[<name>]"), return handle_kill_command(name, name)
description = S("Kill player or yourself"), end,
privs = {server=true}, })
func = function(name, param) cmd:sub(":target:username", {
if(param == "") then func = function(name, target)
-- Selfkill return handle_kill_command(name, target)
return handle_kill_command(name, name) end,
else })
return handle_kill_command(name, param)
end
end, end,
description = "Kill player or yourself.",
params = S("[<target>]"),
privs = {server = true},
}) })

View File

@ -0,0 +1,21 @@
local S = minetest.get_translator("mcl_commands")
mcl_commands.register_command("list", {
func = function(cmd)
cmd:sub("", {
func = function(name)
local player_list = minetest.get_connected_players()
local header = S("There are @1/@2 players online:", #player_list, minetest.settings:get("max_users") or "unknown").."\n"
local players = {}
for _, player in ipairs(player_list) do
table.insert(players, player:get_player_name())
end
return true, header..table.concat(players, ", ")
end,
privs = {},
})
end,
description = S("Show who is logged on"),
params = "",
privs = {},
})

View File

@ -0,0 +1,24 @@
# textdomain: mcl_commands
Players can't be killed right now, damage has been disabled.=Spieler können jetzt nicht getötet werden, der Schaden wurde deaktiviert.
Player @1 does not exist.=Spieler @1 existiert nicht.
You are already dead=Sie sind schon tot
@1 is already dead=@1 ist schon tot
@1 committed suicide.=@1 beging Selbstmord.
@1 was killed by @2.=@1 wurde von @2 getötet.
[<name>]=[<Name>]
Kill player or yourself=Spieler oder sich selbst töten
Can use /say=Kann „/say“ benutzen
<message>=<Nachricht>
Send a message to every player=Nachricht an alle Spieler senden
Invalid usage, see /help say.=Falsche Benutzung, siehe „/help say“.
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <Node-Bezeichner>
Set node at given position=Node (Block) an der gegebenen Position platzieren
Invalid node=Unültiger Node
@1 spawned.=@1 gespawnt.
Invalid parameters (see /help setblock)=Ungültige Parameter (siehe „/help setblock”)
List bans=Bannliste anzeigen
Ban list: @1=Bannliste: @1
There are @1/@2 players online:=
Show who is logged on=Anzeigen, wer eingeloggt ist
Displays the world seed=Den Seed der Welt anzeigen
Only peaceful mobs allowed!=Nur friedliche Mobs erlaubt!

View File

@ -0,0 +1,24 @@
# textdomain: mcl_commands
Players can't be killed right now, damage has been disabled.=Los jugadores no pueden ser asesinados en este momento, el daño ha sido desactivado.
Player @1 does not exist.=El jugador @1 no existe.
You are already dead=Ya estas muerto
@1 is already dead=@1 ya esta muerto
@1 committed suicide.=@1 se suicidó.
@1 was killed by @2.=@1 fue asesinado por @2.
[<name>]=[<Nombre>]
Kill player or yourself=Mata al jugador o a ti mismo
Can use /say=Puedes usar /say
<message>=<Mensaje>
Send a message to every player=Envía un mensaje a todos los jugadores
Invalid usage, see /help=Uso no válido, (Revisa el comando "/help say")
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <ID nodo>
Set node at given position=Establecer nodo en la posición dada
Invalid node=Nodo no válido
@1 spawned.=@1 generado.
Invalid parameters (see /help setblock)=Parámetros no válidos (Revisa el comando "/help setblock")
List bans=Lista de prohibiciones
Ban list: @1=Lista de baneados: @1
There are @1/@2 players online:=
Show who is logged on=Mostrar quién ha iniciado sesión
Displays the world seed=Muestra la semilla del mundo
Only peaceful mobs allowed!=¡Solo se permiten animales pacíficos!

View File

@ -0,0 +1,24 @@
# textdomain: mcl_commands
Players can't be killed right now, damage has been disabled.=Les joueurs ne peuvent pas être tués pour le moment, les dégâts ont été désactivés.
Player @1 does not exist.=Le joueur @1 n'existe pas.
You are already dead=Tu es déjà mort
@1 is already dead=@1 est déjà mort
@1 committed suicide.=@1 s'est suicidé.
@1 was killed by @2.=@1 a été tué par @2.
[<name>]=[<nom>]
Kill player or yourself=Tuez un joueur ou vous-même
Can use /say=Peut utiliser /say
<message>=<message>
Send a message to every player=Envoyez un message à chaque joueur
Invalid usage, see /help say.=Utilisation non valide, voir /help say.
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <NodeString>
Set node at given position=Placer le noeud à une position donnée
Invalid node=Noeud non valide
@1 spawned.=@1 est apparu.
Invalid parameters (see /help setblock)=Paramètres invalides (voir /help setblock)
List bans=Liste des interdictions
Ban list: @1=Liste d'interdiction: @1
There are @1/@2 players online:=Il y a @1/@2 joueurs en ligne:
Show who is logged on=Afficher qui est connecté
Displays the world seed=Affiche la graine du monde
Only peaceful mobs allowed!=Seuls les mobs pacifiques sont autorisées!

View File

@ -0,0 +1,24 @@
# 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.
[<name>]=[<имя>]
Kill player or yourself=Убить игрока или себя
Can use /say=Можно использовать /say
<message>=<сообщение>
Send a message to every player=Отправляет сообщение всем игрокам
Invalid usage, see /help say.=Недопустимое использование, см. /help say.
<X>,<Y>,<Z> <NodeString>=<X>,<Y>,<Z> <СтрокаУзла>
Set node at given position=Устанавливает узел в заданной позиции
Invalid node=Неправильный узел
@1 spawned.=@1 возродился(ась).
Invalid parameters (see /help setblock)=Недопустимые параметры (см. /help setblock)
List bans=Список банов
Ban list: @1=Бан-лист: @1
There are @1/@2 players online:=
Show who is logged on=Показывает, кто подключён
Displays the world seed=Показывает значение зерна мира (seed)
Only peaceful mobs allowed!=Включены только мирные мобы!

View File

@ -0,0 +1,24 @@
# textdomain: mcl_commands
Players can't be killed right now, damage has been disabled.=
Player @1 does not exist.=
You are already dead=
@1 is already dead=
@1 committed suicide.=
@1 was killed by @2.=
[<name>]=
Kill player or yourself=
Can use /say=
<message>=
Send a message to every player=
Invalid usage, see /help say.=
<X>,<Y>,<Z> <NodeString>=
Set node at given position=
Invalid node=
@1 spawned.=
Invalid parameters (see /help setblock)=
List bans=
Ban list: @1=
There are @1/@2 players online:=
Show who is logged on=
Displays the world seed=
Only peaceful mobs allowed!=

View File

@ -0,0 +1,3 @@
name=mcl_basic_commands
depends=mcl_commands
optional_depends=mcl_death_message

View File

@ -0,0 +1,19 @@
local S = minetest.get_translator("mcl_commands")
minetest.register_privilege("announce", {
description = S("Can use /say"),
give_to_singleplayer = false,
})
mcl_commands.register_command("say", {
func = function(cmd)
cmd:sub(":message:text", {
func = function(name, message)
minetest.chat_send_all(("["..name.."] "..message))
return true
end})
end,
description = S("Send a message to every player"),
params = S("<message>"),
privs = {announce = true},
})

View File

@ -0,0 +1,15 @@
local S = minetest.get_translator("mcl_commands")
mcl_commands.register_command("seed", {
func = function(cmd)
cmd:sub("", {
func = function(name)
return true, "Seed: "..minetest.get_mapgen_setting("seed")
end,
privs = {},
})
end,
description = S("Displays the world seed"),
params = "",
privs = {},
})

View File

@ -0,0 +1,35 @@
local S = minetest.get_translator("mcl_commands")
mcl_commands.register_command("setblock", {
func = function(cmd)
cmd:sub(":pos:pos :node:nodename", {
func = function(name, pos, node)
minetest.set_node(pos, {name=node})
return true, S("@1 spawned.", node)
--return false, S("Invalid parameters (see /help setblock)")
end,
privs = {},
})
end,
description = S("Set node at given position"),
params = S("<X>,<Y>,<Z> <NodeString>"),
privs = {give=true, interact=true},
})
--DEBUG: must be removed later
mcl_commands.register_command("setdebug", {
func = function(cmd)
cmd:sub(":node:nodename", {
func = function(name, node)
minetest.set_node({x=0,y=0,z=0}, {name=node})
return true, S("@1 spawned.", node)
--return false, S("Invalid parameters (see /help setblock)")
end,
privs = {},
})
end,
description = S("Set node at given position"),
params = S("<X>,<Y>,<Z> <NodeString>"),
privs = {give=true, interact=true},
})

View File

@ -0,0 +1,19 @@
local S = minetest.get_translator("mcl_commands")
mcl_commands.register_command("playsound", {
func = function(cmd)
cmd:sub(":sound:word :target:username", { --TODO:replace by upcomming types
func = function(name, sound, target)
if minetest.player_exists(target) then
minetest.sound_play({name = sound}, {to_player = target}, true) --TODO:add source, gain, pitch
else
return false, S("Target is invalid!!") --TODO: add mc chat message
end
end,
privs = {},
})
end,
description = S("Play a sound. Arguments: <sound>: name of the sound. <target>: Target."),
params = S("<sound> <target>"),
privs = {server = true},
})

Some files were not shown because too many files have changed in this diff Show More