Compare commits
6 Commits
master
...
doc-refact
Author | SHA1 | Date |
---|---|---|
AFCMS | d4e342313d | |
AFCMS | daa3b8a46c | |
AFCMS | 813f5ff6d4 | |
AFCMS | c383d300e1 | |
AFCMS | 8ef8cdb03a | |
AFCMS | 836570af60 |
|
@ -1,2 +0,0 @@
|
|||
# Text Editor TMP Files
|
||||
*.swp
|
|
@ -1,128 +0,0 @@
|
|||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
eliasfleckenstein@web.de.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
447
CONTRIBUTING.md
|
@ -1,414 +1,105 @@
|
|||
# Contributing to MineClone2
|
||||
So you want to contribute to MineClone2?
|
||||
# Contributing to MineClone 2
|
||||
So you want to contribute to MineClone 2?
|
||||
Wow, thank you! :-)
|
||||
|
||||
MineClone2 is maintained by Nicu and Fleckenstein. If you have any
|
||||
problems or questions, contact us (See Links section below).
|
||||
But first, some things to note:
|
||||
|
||||
You can help with MineClone2's development in many different ways,
|
||||
whether you're a programmer or not.
|
||||
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 ***.
|
||||
|
||||
## MineClone2's development target is to...
|
||||
- Crucially, create a stable, moddable, free/libre clone of Minecraft
|
||||
based on the Minetest engine with polished features, usable in both
|
||||
singleplayer and multiplayer. Currently, most of **Minecraft Java
|
||||
Edition 1.12.2** features are already implemented and polishing existing
|
||||
features are prioritized over new feature requests.
|
||||
- With lessened priority yet strictly, implement features targetting
|
||||
**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported
|
||||
by the Minetest Engine). This means features in parity with the listed
|
||||
Minecraft experiences are prioritized over those that don't fulfill this
|
||||
scope.
|
||||
- Optionally, create a performant experience that will run relatively
|
||||
well on really low spec computers. Unfortunately, due to Minecraft's
|
||||
mechanisms and Minetest engine's limitations along with a very small
|
||||
playerbase on low spec computers, optimizations are hard to investigate.
|
||||
MineClone 2 is maintained by three persons. Namely, kay27, EliasFleckenstein and jordan4ibanez. You can find us
|
||||
in the Minetest forums (forums.minetest.net), in IRC in the #mineclone2
|
||||
channel on irc.freenode.net. And finally, you can send e-mails to
|
||||
<eliasfleckenstein@web.de> or <kay27@bk.ru>.
|
||||
|
||||
## Links
|
||||
* [Mesehub](https://git.minetest.land/MineClone2/MineClone2)
|
||||
* [Discord](https://discord.gg/xE4z8EEpDC)
|
||||
* [YouTube](https://www.youtube.com/channel/UClI_YcsXMF3KNeJtoBfnk9A)
|
||||
* [IRC](https://web.libera.chat/#mineclone2)
|
||||
* [Matrix](https://app.element.io/#/room/#mc2:matrix.org)
|
||||
* [Reddit](https://www.reddit.com/r/MineClone2/)
|
||||
* [Minetest forums](https://forum.minetest.net/viewtopic.php?f=50&t=16407)
|
||||
* [ContentDB](https://content.minetest.net/packages/wuzzy/mineclone2/)
|
||||
* [OpenCollective](https://opencollective.com/mineclone2)
|
||||
By sending us patches or asking us to include your changes in this game,
|
||||
you agree that they fall under the terms of the LGPLv2.1, which basically
|
||||
means they will become part of a free software.
|
||||
|
||||
## Using git
|
||||
MineClone2 is developed using the version control system
|
||||
[git](https://git-scm.com/). If you want to contribute code to the
|
||||
project, it is **highly recommended** that you learn the git basics.
|
||||
For non-programmers and people who do not plan to contribute code to
|
||||
MineClone2, git is not required. However, git is a tool that will be
|
||||
referenced frequently because of its usefulness. As such, it is valuable
|
||||
in learning how git works and its terminology. It can also help you
|
||||
keeping your game updated, and easily test pull requests.
|
||||
## The suggested workflow
|
||||
We don't **dictate** your workflow, but in order to work with us in an efficient
|
||||
way, you can follow these suggestions:
|
||||
|
||||
## How you can help as a non-programmer
|
||||
For small and medium changes:
|
||||
|
||||
As someone who does not know how to write programs in Lua or does not
|
||||
know how to use the Minetest API, you can still help us out a lot. For
|
||||
example, by opening an issue in the
|
||||
[Issue tracker](https://git.minetest.land/MineClone2/MineClone2/issues),
|
||||
you can report a bug or request a feature.
|
||||
|
||||
### Rules about both bugs and feature requests
|
||||
* Stay polite towards the developers and anyone else involved in the
|
||||
discussion.
|
||||
* Choose a descriptive title (e.g. not just "crash", "bug" or "question"
|
||||
).
|
||||
* Please write in plain, understandable English. It will be easier to
|
||||
communicate.
|
||||
* Please start the issue title with a capital letter.
|
||||
* Always check the currently opened issues before creating a new one.
|
||||
Don't report bugs that have already been reported or request features
|
||||
that already have been requested.
|
||||
* If you know about Minetest's inner workings, please think about
|
||||
whether the bug / the feature that you are reporting / requesting is
|
||||
actually an issue with Minetest itself, and if it is, head to the
|
||||
[Minetest issue tracker](https://github.com/minetest/minetest/issues)
|
||||
instead.
|
||||
* If you need any help regarding creating a Mesehub account or opening
|
||||
an issue, feel free to ask on the Discord / Matrix server or the IRC
|
||||
channel.
|
||||
|
||||
### Reporting bugs
|
||||
* A bug is an unintended behavior or, in the worst case, a crash.
|
||||
However, it is not a bug if you believe something is missing in the
|
||||
game. In this case, please read "Requesting features"
|
||||
* If you report a crash, always include the error message. If you play
|
||||
in singleplayer, post a screenshot of the message that Minetest showed
|
||||
when the crash happened (or copy the message into your issue). If you
|
||||
are a server admin, you can find error messages in the log file of the
|
||||
server.
|
||||
* Tell us which MineClone2 and Minetest versions you are using.
|
||||
* Tell us how to reproduce the problem: What you were doing to trigger
|
||||
the bug, e.g. before the crash happened or what causes the faulty
|
||||
behavior.
|
||||
|
||||
### Requesting features
|
||||
* Ensure the requested feature fulfills our development targets and
|
||||
goals.
|
||||
* Begging or excessive attention seeking does not help us in the
|
||||
slightest, and may very well disrupt MineClone2 development. It's better
|
||||
to put that energy into helping or researching the feature in question.
|
||||
After all, we're just volunteers working on our spare time.
|
||||
* Ensure the requested feature has not been implemented in MineClone2
|
||||
latest or development versions.
|
||||
|
||||
### Testing code
|
||||
If you want to help us with speeding up MineClone2 development and
|
||||
making the game more stable, a great way to do that is by testing out
|
||||
new features from contributors. For most new things that get into the
|
||||
game, a pull request is created. A pull request is essentially a
|
||||
programmer saying "Look, I modified the game, please apply my changes
|
||||
to the upstream version of the game". However, every programmer makes
|
||||
mistakes sometimes, some of which are hard to spot. You can help by
|
||||
downloading this modified version of the game and trying it out - then
|
||||
tell us if the code works as expected without any issues. Ideally, you
|
||||
would report issues will pull requests similar to when you were
|
||||
reporting bugs that are the mainline (See Reporting bugs section). You
|
||||
can find currently open pull requests here:
|
||||
<https://git.minetest.land/MineClone2/MineClone2/pulls>. Note that pull
|
||||
requests that start with a `WIP:` are not done yet, and therefore might
|
||||
not work, so it's not very useful to try them out yet.
|
||||
|
||||
### Contributing assets
|
||||
Due to license problems, MineClone2 unfortunately cannot use
|
||||
Minecraft's assets, therefore we are always looking for asset
|
||||
contributions. To contribute assets, it can be useful to learn git
|
||||
basics and read the section for Programmers of this document, however
|
||||
this is not required. It's also a good idea to join the Discord server
|
||||
(or alternatively IRC or Matrix).
|
||||
|
||||
#### Textures
|
||||
For textures we use the Pixel Perfection texture pack. This is mostly
|
||||
enough; however in some cases - e.g. for newer Minecraft features, it's
|
||||
useful to have texture artists around. If you want to make such
|
||||
contributions, join our Discord server. Demands for textures will be
|
||||
communicated there.
|
||||
|
||||
#### Sounds
|
||||
MineClone2 currently does not have a consistent way to handle sounds.
|
||||
The sounds in the game come from different sources, like the SnowZone
|
||||
resource pack or minetest_game. Unfortunately, MineClone2 does not play
|
||||
a sound in every situation you would get one in Minecraft. Any help with
|
||||
sounds is greatly appreciated, however if you add new sounds you should
|
||||
probably work together with a programmer, to write the code to actually
|
||||
play these sounds in game.
|
||||
|
||||
#### 3D Models
|
||||
Most of the 3D Models in MineClone2 come from
|
||||
[22i's repository](https://github.com/22i/minecraft-voxel-blender-models).
|
||||
Similar to the textures, we need people that can make 3D Models with
|
||||
Blender on demand. Many of the models have to be patched, some new
|
||||
animations have to be added etc.
|
||||
|
||||
#### Crediting
|
||||
Asset contributions will be credited in their own respective sections in
|
||||
CREDITS.md. If you have commited the results yourself, you will also be
|
||||
credited in the Contributors section.
|
||||
|
||||
### Contributing Translations
|
||||
|
||||
#### Workflow
|
||||
To add/update support for your language to MineClone2, you should take
|
||||
the steps documented in the section for Programmers, add/update the
|
||||
translation files of the mods that you want to update. You can add
|
||||
support for all mods, just some of them or only one mod; you can update
|
||||
the translation file entirely or only partly; basically any effort is
|
||||
valued. If your changes are small, you can also send them to developers
|
||||
via E-Mail, Discord, IRC or Matrix - they will credit you appropriately.
|
||||
|
||||
#### Things to note
|
||||
You can use the script at `tools/check_translate_files.py` to compare
|
||||
the translation files for the language you are working on with the
|
||||
template files, to see what is missing and what is out of date with
|
||||
the template file. However, template files are often incomplete and/or
|
||||
out of date, sometimes they don't match the code. You can update the
|
||||
translation files if that is required, you can also modify the code in
|
||||
your translation PR if it's related to translation. You can also work on
|
||||
multiple languages at the same time in one PR.
|
||||
|
||||
#### Crediting
|
||||
Translation contributions will be credited in their own in CREDITS.md.
|
||||
If you have commited the results yourself, you will also be credited in
|
||||
the Contributors section.
|
||||
|
||||
### Profiling
|
||||
If you own a server, a great way to help us improve MineClone2's code
|
||||
is by giving us profiler results. Profiler results give us detailed
|
||||
information about the game's performance and let us know places to
|
||||
investigate optimization issues. This way we can make the game faster.
|
||||
|
||||
#### Using Minetest's profiler
|
||||
Minetest has a built in profiler. Simply set `profiler.load = true` in
|
||||
your configuration file and restart the server. After running the server
|
||||
for some time, just run `/profiler save` in chat - then you will find a
|
||||
file in the world directory containing the results. Open a new issue and
|
||||
upload the file. You can name the issue "<Server name> profiler
|
||||
results".
|
||||
|
||||
### Let us know your opinion
|
||||
It is always encouraged to actively contribute to issue discussions on
|
||||
MeseHub, let us know what you think about a topic and help us make
|
||||
decisions. Also, note that a lot of discussion takes place on the
|
||||
Discord server, so it's definitely worth checking it out.
|
||||
|
||||
### Funding
|
||||
You can help pay for our infrastructure (Mesehub) by donating to our
|
||||
OpenCollective link (See Links section).
|
||||
|
||||
### Crediting
|
||||
If you opened or have contributed to an issue, you receive the
|
||||
`Community` role on our Discord (after asking for it).
|
||||
OpenCollective Funders are credited in their own section in
|
||||
`CREDITS.md` and receive a special role "Funder" on our discord (unless
|
||||
they have made their donation Incognito).
|
||||
|
||||
## How you can help as a programmer
|
||||
(Almost) all the MineClone2 development is done using pull requests.
|
||||
|
||||
### Recommended workflow
|
||||
* Fork the repository (in case you have not already)
|
||||
* Fork the repository
|
||||
* Do your change in a new branch
|
||||
* Create a pull request to get your changes merged into master
|
||||
* Keep your pull request up to date by regularly merging upstream. It is
|
||||
imperative that conflicts are resolved prior to merging the pull
|
||||
request.
|
||||
* After the pull request got merged, you can delete the branch
|
||||
|
||||
### Discuss first
|
||||
If you feel like a problem needs to fixed or you want to make a new
|
||||
feature, you could start writing the code right away and notifying us
|
||||
when you're done, but it never hurts to discuss things first. If there
|
||||
is no issue on the topic, open one. If there is an issue, tell us that
|
||||
you'd like to take care of it, to avoid duplicate work.
|
||||
For small changes, sending us a patch is also good.
|
||||
|
||||
### Don't hesitate to ask for help
|
||||
We appreciate any contributing effort to MineClone2. If you are a
|
||||
relatively new programmer, you can reach us on Discord, Matrix or IRC
|
||||
for questions about git, Lua, Minetest API, MineClone2 codebase or
|
||||
anything related to MineClone2. We can help you avoid writing code that
|
||||
would be deemed inadequate, or help you become familiar with MineClone2
|
||||
better, or assist you use development tools.
|
||||
For big changes: Same as above, but consider notifying us first to avoid
|
||||
duplicate work and possible tears of rejection. ;-)
|
||||
|
||||
### Maintain your own code, even if already got merged
|
||||
Sometimes, your code may cause crashes or bugs - we try to avoid such
|
||||
scenarios by testing every time before merging it, but if your merged
|
||||
work causes problems, we ask you fix the issues as soon as possible.
|
||||
For trusted people, we might give them direct commit access to this
|
||||
repository. In this case, you obviously don't need to fork, but you still
|
||||
need to show your contributions align with the project goals. We still
|
||||
reserve the right to revert everything that we don't like.
|
||||
For bigger changes, we strongly recommend to use feature branches and
|
||||
discuss with me first.
|
||||
|
||||
### Changing Gameplay
|
||||
Pull Requests that change gameplay have to be properly researched and
|
||||
need to state their sources. These PRs also need Fleckenstein's approval
|
||||
before they are merged.
|
||||
You can use these sources:
|
||||
If your code causes bugs and crashes, it is your responsibility to fix them as soon as possible.
|
||||
|
||||
* Minecraft code (Name the source file and line, however DONT post any
|
||||
proprietary code). You can use
|
||||
[MCP](https://minecraft.fandom.com/wiki/Programs_and_editors/Mod_Coder_Pack)
|
||||
to decompile Minecraft or look at
|
||||
[Minestorm](https://github.com/Minestom/Minestom) code.
|
||||
* Testing things inside of Minecraft (Attach screenshots / video footage
|
||||
of the results)
|
||||
* [Official Minecraft Wiki](https://minecraft.fandom.com/wiki/Minecraft_Wiki)
|
||||
(Include a link to the specific page you used)
|
||||
We mostly use plain merging rather than rebasing or squash merging.
|
||||
|
||||
### Stick to our guidelines
|
||||
Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue.
|
||||
|
||||
#### Git Guidelines
|
||||
* We use merge rather than rebase or squash merge
|
||||
* We don't use git submodules.
|
||||
* Your commit names should be relatively descriptive, e.g. when saying
|
||||
"Fix #issueid", the commit message should also contain the title of the
|
||||
issue.
|
||||
* Try to keep your commits as atomic as possible (advise, but completely
|
||||
optional)
|
||||
Contributors will be credited in `CREDITS.md`.
|
||||
|
||||
#### Code Guidelines
|
||||
* Each mod must provide `mod.conf`.
|
||||
* Mod names are snake case, and newly added mods start with `mcl_`, e.g.
|
||||
`mcl_core`, `mcl_farming`, `mcl_monster_eggs`. Keep in mind Minetest
|
||||
does not support capital letters in mod names.
|
||||
* To export functions, store them inside a global table named like the
|
||||
mod, e.g.
|
||||
## Code Style
|
||||
|
||||
```lua
|
||||
mcl_example = {}
|
||||
|
||||
function mcl_example.do_something()
|
||||
-- ...
|
||||
end
|
||||
Each mod must provide `mod.conf`.
|
||||
Each mod which add API functions should store functions inside a global table named like the mod.
|
||||
Public functions should not use self references but rather just access the table directly.
|
||||
Functions should be defined in this way:
|
||||
```
|
||||
function mcl_xyz.stuff(param) end
|
||||
```
|
||||
Insteed of this way:
|
||||
```
|
||||
mcl_xyz.stuff = function(param) end
|
||||
```
|
||||
Indentation must be unified, more likely with tabs.
|
||||
|
||||
Time sensitive mods should make a local copy of most used API functions to improve performances.
|
||||
```
|
||||
local vector = vector
|
||||
local get_node = minetest.get_node
|
||||
```
|
||||
|
||||
* Public functions should not use self references but rather just access
|
||||
the table directly, e.g.
|
||||
|
||||
```lua
|
||||
-- bad
|
||||
function mcl_example:do_something()
|
||||
end
|
||||
## Features > 1.12
|
||||
|
||||
-- good
|
||||
function mcl_example.do_something()
|
||||
end
|
||||
```
|
||||
If you want to make a feature that was added in a Minecraft version later than 1.12, you should fork MineClone5 (mineclone5 branch in the repository) and add your changes to this.
|
||||
|
||||
* Use modern Minetest API, e.g. no usage of `minetest.env`
|
||||
* Tabs should be used for indent, spaces for alignment, e.g.
|
||||
## What we accept
|
||||
|
||||
```lua
|
||||
* Every MC features up to version 1.12 JE.
|
||||
* Every already finished and working good features from versions above (only when making a MineClone5 PR / Contribution).
|
||||
* Except features which couldn't be done easily and bugfree because of Minetest engine limitations. Eg. we CAN extend world boundaries by playing with map chunks, just teleporting player onto next layer after 31000 , but it would cost too much (time, code, bugs, performance, stability, etc).
|
||||
* Some features, approved by the rest of the community, I mean maybe some voting and really missing any negative feedback.
|
||||
|
||||
-- use tabs for indent
|
||||
## What we reject
|
||||
|
||||
for i = 1, 10 do
|
||||
if i % 3 == 0 then
|
||||
print(i)
|
||||
end
|
||||
end
|
||||
* 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.
|
||||
|
||||
-- use tabs for indent and spaces to align things
|
||||
## Reporting bugs
|
||||
Report all bugs and missing Minecraft features here:
|
||||
|
||||
some_table = {
|
||||
{"a string", 5},
|
||||
{"a very much longer string", 10},
|
||||
}
|
||||
```
|
||||
<https://git.minetest.land/MineClone2/MineClone2/issues>
|
||||
|
||||
* Use double quotes for strings, e.g. `"asdf"` rather than `'asdf'`
|
||||
* Use snake_case rather than CamelCase, e.g. `my_function` rather than
|
||||
`MyFunction`
|
||||
* Don't declare functions as an assignment, e.g.
|
||||
## Direct discussion
|
||||
We have an IRC channel! Join us on #mineclone2 in freenode.net.
|
||||
|
||||
```lua
|
||||
-- bad
|
||||
local some_local_func = function()
|
||||
-- ...
|
||||
end
|
||||
<ircs://irc.freenode.net:6697/#mineclone2>
|
||||
|
||||
my_mod.some_func = function()
|
||||
-- ...
|
||||
end
|
||||
|
||||
-- good
|
||||
local function some_local_func()
|
||||
-- ...
|
||||
end
|
||||
|
||||
function my_mod.some_func()
|
||||
-- ...
|
||||
end
|
||||
```
|
||||
|
||||
### Developer status
|
||||
Active and trusted contributors are often granted write access to the
|
||||
MineClone2 repository.
|
||||
|
||||
#### Developer responsibilities
|
||||
- You should not push things directly to
|
||||
MineClone2 master - rather, do your work on a branch on your private
|
||||
repository, then create a pull request. This way other people can review
|
||||
your changes and make sure they work before they get merged.
|
||||
- Merge PRs only when they have recieved the necessary feedback and have
|
||||
been tested by at least two different people (including the author of
|
||||
the pull request), to avoid crashes or the introduction of new bugs.
|
||||
- You may also be assigned to issues or pull
|
||||
requests as a developer. In this case it is your responsibility to fix
|
||||
the issue / review and merge the pull request when it is ready. You can
|
||||
also unassign yourself from the issue / PR if you have no time or don't
|
||||
want to take care of it for some other reason. After all, everyone is a
|
||||
volunteer and we can't expect you to do work that you are not interested
|
||||
in. **The important thing is that you make sure to inform us if you
|
||||
won't take care of something that has been assigned to you.**
|
||||
- Please assign yourself to something that you want to work on to avoid
|
||||
duplicate work.
|
||||
- As a developer, it should be easy to reach you about your work. You
|
||||
should be in at least one of the public MineClone2 discussion rooms -
|
||||
preferrably Discord, but if you really don't like Discord, Matrix
|
||||
or IRC are fine too.
|
||||
|
||||
### Maintainer status
|
||||
Maintainers carry the main responsibility for the project.
|
||||
|
||||
#### Maintainer responsibilities
|
||||
- Making sure issues are addressed and pull requests are reviewed and
|
||||
merged, by assigning either themselves or Developers to issues / PRs
|
||||
- Making releases
|
||||
- Making sure guidelines are kept
|
||||
- Making project decisions based on community feedback
|
||||
- Granting/revoking developer access
|
||||
- Enforcing the code of conduct (See CODE_OF_CONDUCT.md)
|
||||
- Moderating official community spaces (See Links section)
|
||||
- Resolving conflicts and problems within the community
|
||||
|
||||
#### Current maintainers
|
||||
* Fleckenstein - responsible for gameplay review, publishing releases,
|
||||
technical guidelines and issue/PR delegation
|
||||
* Nicu - responsible for community related issues
|
||||
|
||||
#### Release process
|
||||
* Run `tools/generate_ingame_credits.lua` to update the ingame credits
|
||||
from `CREDITS.md` and commit the result (if anything changed)
|
||||
## Creating releases
|
||||
* Launch MineClone2 to make sure it still runs
|
||||
* Update the version number in README.md
|
||||
* Use `git tag <version number>` to tag the latest commit with the
|
||||
version number
|
||||
* Push to repository (don't forget `--tags`!)
|
||||
* Update ContentDB
|
||||
(https://content.minetest.net/packages/Wuzzy/mineclone2/)
|
||||
* Update first post in forum thread
|
||||
(https://forum.minetest.net/viewtopic.php?f=50&t=16407)
|
||||
* Use `git tag <version number>` to tag the latest commit with the version number
|
||||
* Push to repo (don't forget `--tags`!)
|
||||
* Update ContentDB (https://content.minetest.net/packages/Wuzzy/mineclone2/)
|
||||
* Update first post in forum thread (https://forum.minetest.net/viewtopic.php?f=50&t=16407)
|
||||
* Post release announcement and changelog in forums
|
||||
|
||||
### Licensing
|
||||
By asking us to include your changes in this game, you agree that they
|
||||
fall under the terms of the GPLv3, which basically means they will
|
||||
become part of a free/libre software.
|
||||
|
||||
### Crediting
|
||||
Contributors, Developers and Maintainers will be credited in
|
||||
`CREDITS.md`. If you make your first time contribution, please add
|
||||
yourself to this file. There are also Discord roles for Contributors,
|
||||
Developers and Maintainers.
|
||||
|
|
31
CREDITS.md
|
@ -8,8 +8,8 @@
|
|||
|
||||
## Maintainers
|
||||
* Fleckenstein
|
||||
* Nicu
|
||||
* kay27
|
||||
* jordan4ibanez
|
||||
|
||||
## Developers
|
||||
* bzoss
|
||||
|
@ -19,11 +19,10 @@
|
|||
* iliekprogrammar
|
||||
* MysticTempest
|
||||
* Rootyjr
|
||||
* Nicu
|
||||
* aligator
|
||||
* Code-Sploit
|
||||
* NO11
|
||||
* cora
|
||||
* jordan4ibanez
|
||||
|
||||
## Contributors
|
||||
* Laurent Rocher
|
||||
|
@ -49,25 +48,8 @@
|
|||
* dBeans
|
||||
* nickolas360
|
||||
* yutyo
|
||||
* Tianyang Zhang
|
||||
* ztianyang
|
||||
* j45
|
||||
* Marcin Serwin
|
||||
* erlehmann
|
||||
* E
|
||||
* Benjamin Schötz
|
||||
* Doloment
|
||||
* Sydney Gems
|
||||
* talamh
|
||||
* Emily2255
|
||||
* Emojigit
|
||||
* FinishedFragment
|
||||
* sfan5
|
||||
* Blue Blancmange
|
||||
* Jared Moody
|
||||
* SmallJoker
|
||||
* Sven792
|
||||
* aldum
|
||||
* Dieter44
|
||||
|
||||
## MineClone5
|
||||
* kay27
|
||||
|
@ -92,6 +74,7 @@
|
|||
* Rochambeau
|
||||
* rubenwardy
|
||||
* stu
|
||||
* jordan4ibanez
|
||||
* 4aiman
|
||||
* Kahrl
|
||||
* Krock
|
||||
|
@ -120,7 +103,6 @@
|
|||
* xMrVizzy
|
||||
* yutyo
|
||||
* NO11
|
||||
* kay27
|
||||
|
||||
## Translations
|
||||
* Wuzzy
|
||||
|
@ -128,11 +110,6 @@
|
|||
* wuniversales
|
||||
* kay27
|
||||
* pitchum
|
||||
* todoporlalibertad
|
||||
* Marcin Serwin
|
||||
|
||||
## Funders
|
||||
* 40W
|
||||
|
||||
## Special thanks
|
||||
* celeron55 for creating Minetest
|
||||
|
|
|
@ -149,7 +149,7 @@ These groups are used mostly for informational purposes
|
|||
* `trapdoor=2`: Open trapdoor
|
||||
* `glass=1`: Glass (full cubes only)
|
||||
* `rail=1`: Rail
|
||||
* `music_record`: Item is Music Disc
|
||||
* `music_record`: Music Disc (rating is track ID)
|
||||
* `tnt=1`: Block is TNT
|
||||
* `boat=1`: Boat
|
||||
* `minecart=1`: Minecart
|
||||
|
|
58
README.md
|
@ -1,4 +1,6 @@
|
|||
# MineClone2
|
||||
# (Currently in feature freeze)
|
||||
|
||||
# MineClone 2
|
||||
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
|
||||
Developed by many people. Not developed or endorsed by Mojang AB.
|
||||
|
||||
|
@ -69,40 +71,36 @@ an explanation.
|
|||
This game requires [Minetest](http://minetest.net) to run (version 5.3.0 or
|
||||
later). So you need to install Minetest first. Only stable versions of Minetest
|
||||
are officially supported.
|
||||
There is no support for running MineClone2 in development versions of Minetest.
|
||||
There is no support for running MineClone 2 in development versions of Minetest.
|
||||
|
||||
To install MineClone2 (if you haven't already), move this directory into the
|
||||
To install MineClone 2 (if you haven't already), move this directory into the
|
||||
“games” directory of your Minetest data directory. Consult the help of
|
||||
Minetest to learn more.
|
||||
|
||||
## Useful links
|
||||
The MineClone2 repository is hosted at Mesehub. To contribute or report issues, head there.
|
||||
## Reporting bugs
|
||||
Please report all bugs and missing Minecraft features here:
|
||||
|
||||
* Mesehub: <https://git.minetest.land/MineClone2/MineClone2>
|
||||
* Discord: <https://discord.gg/xE4z8EEpDC>
|
||||
* YouTube <https://www.youtube.com/channel/UClI_YcsXMF3KNeJtoBfnk9A>
|
||||
* IRC: <https://web.libera.chat/#mineclone2>
|
||||
* Matrix: <https://app.element.io/#/room/#mc2:matrix.org>
|
||||
* Reddit: <https://www.reddit.com/r/MineClone2/>
|
||||
* Minetest forums: <https://forum.minetest.net/viewtopic.php?f=50&t=16407>
|
||||
* ContentDB: <https://content.minetest.net/packages/wuzzy/mineclone2/>
|
||||
* OpenCollective: <https://opencollective.com/mineclone2>
|
||||
<https://git.minetest.land/MineClone2/MineClone2/issues>
|
||||
|
||||
## Target
|
||||
- Crucially, create a stable, moddable, free/libre clone of Minecraft
|
||||
based on the Minetest engine with polished features, usable in both
|
||||
singleplayer and multiplayer. Currently, most of **Minecraft Java
|
||||
Edition 1.12.2** features are already implemented and polishing existing
|
||||
features are prioritized over new feature requests.
|
||||
- With lessened priority yet strictly, implement features targetting
|
||||
**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported
|
||||
by the Minetest Engine). This means features in parity with the listed
|
||||
Minecraft experiences are prioritized over those that don't fulfill this
|
||||
scope.
|
||||
- Optionally, create a performant experience that will run relatively
|
||||
well on really low spec computers. Unfortunately, due to Minecraft's
|
||||
mechanisms and Minetest engine's limitations along with a very small
|
||||
playerbase on low spec computers, optimizations are hard to investigate.
|
||||
## Chating with the community
|
||||
Join our discord server at:
|
||||
|
||||
<https://discord.gg/84GKcxczG3>
|
||||
|
||||
## Project description
|
||||
The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software.
|
||||
|
||||
* **Target of development: Minecraft, PC Edition, version 1.12** (later known as “Java Edition”)
|
||||
* MineClone2 also includes Optifine features supported by the Minetest
|
||||
* In general, Minecraft is aimed to be cloned as good as possible
|
||||
* Cloning the gameplay has highest priority
|
||||
* MineClone 2 will use different assets, but with a similar style
|
||||
* Limitations found in Minetest will be documented in the course of development
|
||||
* Features of later Minecraft versions are collected in the mineclone5 branch
|
||||
|
||||
## Using features from newer versions of Minecraft
|
||||
For > 1.12 features, checkout MineClone5. It includes features from newer Minecraft versions.
|
||||
Download it here: https://git.minetest.land/MineClone2/MineClone2/src/branch/mineclone5
|
||||
|
||||
## Completion status
|
||||
This game is currently in **beta** stage.
|
||||
|
@ -189,7 +187,7 @@ Technical differences from Minecraft:
|
|||
* Different engine (Minetest)
|
||||
* Different easter eggs
|
||||
|
||||
… and finally, MineClone2 is free software (“free” as in “freedom”)!
|
||||
… and finally, MineClone 2 is free software (“free” as in “freedom”)!
|
||||
|
||||
## Other readme files
|
||||
|
||||
|
|
BIN
menu/Logo.blend
BIN
menu/icon.png
Before Width: | Height: | Size: 547 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 419 KiB |
|
@ -83,7 +83,7 @@ local function get_hardness_values_for_groups()
|
|||
|
||||
for _, ndef in pairs(minetest.registered_nodes) do
|
||||
for g, _ in pairs(mcl_autogroup.registered_diggroups) do
|
||||
if ndef.groups[g] then
|
||||
if ndef.groups[g] ~= nil then
|
||||
maps[g][ndef._mcl_hardness or 0] = true
|
||||
end
|
||||
end
|
||||
|
@ -207,10 +207,6 @@ end
|
|||
function mcl_autogroup.can_harvest(nodename, toolname)
|
||||
local ndef = minetest.registered_nodes[nodename]
|
||||
|
||||
if not ndef then
|
||||
return false
|
||||
end
|
||||
|
||||
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
local get_connected_players = minetest.get_connected_players
|
||||
local clock = os.clock
|
||||
|
||||
local pairs = pairs
|
||||
|
||||
controls = {}
|
||||
controls.players = {}
|
||||
|
||||
|
@ -22,15 +20,15 @@ function controls.register_on_hold(func)
|
|||
end
|
||||
|
||||
local known_controls = {
|
||||
jump = true,
|
||||
right = true,
|
||||
left = true,
|
||||
LMB = true,
|
||||
RMB = true,
|
||||
sneak = true,
|
||||
aux1 = true,
|
||||
down = true,
|
||||
up = true,
|
||||
jump=true,
|
||||
right=true,
|
||||
left=true,
|
||||
LMB=true,
|
||||
RMB=true,
|
||||
sneak=true,
|
||||
aux1=true,
|
||||
down=true,
|
||||
up=true,
|
||||
}
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
|
@ -51,27 +49,27 @@ minetest.register_globalstep(function(dtime)
|
|||
local player_name = player:get_player_name()
|
||||
local player_controls = player:get_player_control()
|
||||
if controls.players[player_name] then
|
||||
for cname, cbool in pairs(player_controls) do
|
||||
if known_controls[cname] == true then
|
||||
--Press a key
|
||||
if cbool == true and controls.players[player_name][cname][1] == false then
|
||||
for _, func in pairs(controls.registered_on_press) do
|
||||
func(player, cname)
|
||||
end
|
||||
controls.players[player_name][cname] = {true, clock()}
|
||||
elseif cbool == true and controls.players[player_name][cname][1] == true then
|
||||
for _, func in pairs(controls.registered_on_hold) do
|
||||
func(player, cname, clock()-controls.players[player_name][cname][2])
|
||||
end
|
||||
--Release a key
|
||||
elseif cbool == false and controls.players[player_name][cname][1] == true then
|
||||
for _, func in pairs(controls.registered_on_release) do
|
||||
func(player, cname, clock()-controls.players[player_name][cname][2])
|
||||
end
|
||||
controls.players[player_name][cname] = {false}
|
||||
end
|
||||
for cname, cbool in pairs(player_controls) do
|
||||
if known_controls[cname] == true then
|
||||
--Press a key
|
||||
if cbool==true and controls.players[player_name][cname][1]==false then
|
||||
for _, func in pairs(controls.registered_on_press) do
|
||||
func(player, cname)
|
||||
end
|
||||
controls.players[player_name][cname] = {true, clock()}
|
||||
elseif cbool==true and controls.players[player_name][cname][1]==true then
|
||||
for _, func in pairs(controls.registered_on_hold) do
|
||||
func(player, cname, clock()-controls.players[player_name][cname][2])
|
||||
end
|
||||
--Release a key
|
||||
elseif cbool==false and controls.players[player_name][cname][1]==true then
|
||||
for _, func in pairs(controls.registered_on_release) do
|
||||
func(player, cname, clock()-controls.players[player_name][cname][2])
|
||||
end
|
||||
controls.players[player_name][cname] = {false}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# mcl_damage
|
||||
This mod provide damage handling.
|
||||
|
||||
## mcl_damage.register_modifier(func, priority)
|
||||
Register damage modifier.
|
||||
* func: function, called with (obj, damage, reason)
|
||||
|
||||
This function can modify damage, based on mcl reason.
|
||||
|
||||
* priority: int, define call order of registered functions
|
||||
|
||||
You should make use higher values for important or most used functions.
|
||||
|
||||
## mcl_damage.from_mt(mt_reason)
|
||||
Convert mt damage reason (nil, fall, drown, punch, node_damage) to mc like reason.
|
||||
* mt_reason: table, mt damage reason
|
|
@ -12,13 +12,9 @@ under the LGPLv2.1 license.
|
|||
|
||||
mcl_explosions = {}
|
||||
|
||||
local mod_fire = minetest.get_modpath("mcl_fire")
|
||||
local mod_fire = minetest.get_modpath("mcl_fire") ~= nil
|
||||
--local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
|
||||
|
||||
local math = math
|
||||
local vector = vector
|
||||
local table = table
|
||||
|
||||
local hash_node_position = minetest.hash_node_position
|
||||
local get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||
local get_position_from_hash = minetest.get_position_from_hash
|
||||
|
@ -28,7 +24,6 @@ local get_voxel_manip = minetest.get_voxel_manip
|
|||
local bulk_set_node = minetest.bulk_set_node
|
||||
local check_for_falling = minetest.check_for_falling
|
||||
local add_item = minetest.add_item
|
||||
local pos_to_string = minetest.pos_to_string
|
||||
|
||||
-- Saved sphere explosion shapes for various radiuses
|
||||
local sphere_shapes = {}
|
||||
|
@ -245,7 +240,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
|
|||
local ent = obj:get_luaentity()
|
||||
|
||||
-- Ignore items to lower lag
|
||||
if (obj:is_player() or (ent and ent.name ~= "__builtin.item")) and obj:get_hp() > 0 then
|
||||
if (obj:is_player() or (ent and ent.name ~= '__builtin.item')) and obj:get_hp() > 0 then
|
||||
local opos = obj:get_pos()
|
||||
local collisionbox = nil
|
||||
|
||||
|
@ -361,9 +356,9 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
|
|||
local on_blast = node_on_blast[data[idx]]
|
||||
local remove = true
|
||||
|
||||
if do_drop or on_blast then
|
||||
if do_drop or on_blast ~= nil then
|
||||
local npos = get_position_from_hash(hash)
|
||||
if on_blast then
|
||||
if on_blast ~= nil then
|
||||
on_blast(npos, 1.0, do_drop)
|
||||
remove = false
|
||||
else
|
||||
|
@ -405,7 +400,8 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
|
|||
end
|
||||
|
||||
-- Log explosion
|
||||
minetest.log("action", "Explosion at "..pos_to_string(pos).." with strength "..strength.." and radius "..radius)
|
||||
minetest.log('action', 'Explosion at ' .. minetest.pos_to_string(pos) ..
|
||||
' with strength ' .. strength .. ' and radius ' .. radius)
|
||||
end
|
||||
|
||||
-- Create an explosion with strength at pos.
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:mcl_explosions
|
||||
@1 was caught in an explosion.=@1 została wysadzona.
|
|
@ -32,9 +32,9 @@ local singlenode = mg_name == "singlenode"
|
|||
|
||||
-- Calculate mapgen_edge_min/mapgen_edge_max
|
||||
mcl_vars.chunksize = math.max(1, tonumber(minetest.get_mapgen_setting("chunksize")) or 5)
|
||||
mcl_vars.MAP_BLOCKSIZE = math.max(1, minetest.MAP_BLOCKSIZE or 16)
|
||||
mcl_vars.MAP_BLOCKSIZE = math.max(1, core.MAP_BLOCKSIZE or 16)
|
||||
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
|
||||
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, minetest.MAX_MAP_GENERATION_LIMIT or 31000)
|
||||
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000)
|
||||
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
|
||||
mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
||||
mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
|
||||
|
|
|
@ -58,27 +58,26 @@ function mcl_loot.get_loot(loot_definitions, pr)
|
|||
end
|
||||
if item then
|
||||
local itemstring = item.itemstring
|
||||
|
||||
local itemstack = item.itemstack
|
||||
if itemstring then
|
||||
local stack = ItemStack(itemstring)
|
||||
|
||||
if item.amount_min and item.amount_max then
|
||||
stack:set_count(pr:next(item.amount_min, item.amount_max))
|
||||
itemstring = itemstring .. " " .. pr:next(item.amount_min, item.amount_max)
|
||||
end
|
||||
|
||||
if item.wear_min and item.wear_max then
|
||||
-- Sadly, PseudoRandom only allows very narrow ranges, so we set wear in steps of 10
|
||||
local wear_min = math.floor(item.wear_min / 10)
|
||||
local wear_max = math.floor(item.wear_max / 10)
|
||||
local wear = pr:next(wear_min, wear_max) * 10
|
||||
|
||||
stack:set_wear(pr:next(wear_min, wear_max) * 10)
|
||||
if not item.amount_min and not item.amount_max then
|
||||
itemstring = itemstring .. " 1"
|
||||
end
|
||||
|
||||
itemstring = itemstring .. " " .. tostring(wear)
|
||||
end
|
||||
|
||||
if item.func then
|
||||
item.func(stack, pr)
|
||||
end
|
||||
|
||||
table.insert(items, stack)
|
||||
table.insert(items, itemstring)
|
||||
elseif itemstack then
|
||||
table.insert(items, itemstack)
|
||||
else
|
||||
minetest.log("error", "[mcl_loot] INTERNAL ERROR! Failed to select random loot item!")
|
||||
end
|
||||
|
|
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 154 B |
Before Width: | Height: | Size: 155 B |
Before Width: | Height: | Size: 165 B |
|
@ -1,27 +1,5 @@
|
|||
mcl_util = {}
|
||||
|
||||
-- Updates all values in t using values from to*.
|
||||
function table.update(t, ...)
|
||||
for _, to in ipairs{...} do
|
||||
for k,v in pairs(to) do
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- Updates nil values in t using values from to*.
|
||||
function table.update_nil(t, ...)
|
||||
for _, to in ipairs{...} do
|
||||
for k,v in pairs(to) do
|
||||
if t[k] == nil then
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- Based on minetest.rotate_and_place
|
||||
|
||||
--[[
|
||||
|
@ -478,9 +456,7 @@ function mcl_util.calculate_durability(itemstack)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
local _, groupcap = next(itemstack:get_tool_capabilities().groupcaps)
|
||||
uses = uses or (groupcap or {}).uses
|
||||
uses = uses or (next(itemstack:get_tool_capabilities().groupcaps) or {}).uses
|
||||
end
|
||||
|
||||
return uses or 0
|
||||
|
@ -562,12 +538,3 @@ function mcl_util.get_object_name(object)
|
|||
return luaentity.nametag and luaentity.nametag ~= "" and luaentity.nametag or luaentity.description or luaentity.name
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_util.replace_mob(obj, mob)
|
||||
local rot = obj:get_yaw()
|
||||
local pos = obj:get_pos()
|
||||
obj:remove()
|
||||
obj = minetest.add_entity(pos, mob)
|
||||
obj:set_yaw(rot)
|
||||
return obj
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ Params:
|
|||
|
||||
* pos: position
|
||||
|
||||
## mcl_worlds.y_to_layer(y)
|
||||
## mcl_worlds.y_to_layer(y)
|
||||
This function is used to calculate the minetest y layer and dimension of the given <y> minecraft layer.
|
||||
Mainly used for ore generation.
|
||||
Takes an Y coordinate as input and returns:
|
||||
|
@ -78,4 +78,4 @@ Table containing all function registered with mcl_worlds.register_on_dimension_c
|
|||
Notify this mod of a dimension change of <player> to <dimension>
|
||||
|
||||
* player: player, player who changed the dimension
|
||||
* dimension: string, new dimension ("overworld", "nether", "end", "void")
|
||||
* dimension: string, new dimension ("overworld", "nether", "end", "void")
|
|
@ -1,7 +1,5 @@
|
|||
mcl_worlds = {}
|
||||
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
|
||||
-- For a given position, returns a 2-tuple:
|
||||
-- 1st return value: true if pos is in void
|
||||
-- 2nd return value: true if it is in the deadly part of the void
|
||||
|
@ -46,16 +44,12 @@ function mcl_worlds.y_to_layer(y)
|
|||
end
|
||||
end
|
||||
|
||||
local y_to_layer = mcl_worlds.y_to_layer
|
||||
|
||||
-- Takes a pos and returns the dimension it belongs to (same as above)
|
||||
function mcl_worlds.pos_to_dimension(pos)
|
||||
local _, dim = y_to_layer(pos.y)
|
||||
local _, dim = mcl_worlds.y_to_layer(pos.y)
|
||||
return dim
|
||||
end
|
||||
|
||||
local pos_to_dimension = mcl_worlds.pos_to_dimension
|
||||
|
||||
-- Takes a Minecraft layer and a “dimension” name
|
||||
-- and returns the corresponding Y coordinate for
|
||||
-- MineClone 2.
|
||||
|
@ -125,8 +119,6 @@ function mcl_worlds.dimension_change(player, dimension)
|
|||
last_dimension[playername] = dimension
|
||||
end
|
||||
|
||||
local dimension_change = mcl_worlds.dimension_change
|
||||
|
||||
----------------------- INTERNAL STUFF ----------------------
|
||||
|
||||
-- Update the dimension callbacks every DIM_UPDATE seconds
|
||||
|
@ -134,19 +126,19 @@ local DIM_UPDATE = 1
|
|||
local dimtimer = 0
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
last_dimension[player:get_player_name()] = pos_to_dimension(player:get_pos())
|
||||
last_dimension[player:get_player_name()] = mcl_worlds.pos_to_dimension(player:get_pos())
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
-- regular updates based on iterval
|
||||
dimtimer = dimtimer + dtime;
|
||||
if dimtimer >= DIM_UPDATE then
|
||||
local players = get_connected_players()
|
||||
for p = 1, #players do
|
||||
local dim = pos_to_dimension(players[p]:get_pos())
|
||||
local players = minetest.get_connected_players()
|
||||
for p=1, #players do
|
||||
local dim = mcl_worlds.pos_to_dimension(players[p]:get_pos())
|
||||
local name = players[p]:get_player_name()
|
||||
if dim ~= last_dimension[name] then
|
||||
dimension_change(players[p], dim)
|
||||
mcl_worlds.dimension_change(players[p], dim)
|
||||
end
|
||||
end
|
||||
dimtimer = 0
|
||||
|
|
|
@ -38,32 +38,18 @@ function image:encode_header()
|
|||
self.data = self.data
|
||||
.. string.char(0) -- image id
|
||||
.. string.char(0) -- color map type
|
||||
.. string.char(10) -- image type (RLE RGB = 10)
|
||||
.. string.char(2) -- image type (uncompressed true-color image = 2)
|
||||
self:encode_colormap_spec() -- color map specification
|
||||
self:encode_image_spec() -- image specification
|
||||
end
|
||||
|
||||
function image:encode_data()
|
||||
local current_pixel = ''
|
||||
local previous_pixel = ''
|
||||
local count = 1
|
||||
local packets = {}
|
||||
local rle_packet = ''
|
||||
for _, row in ipairs(self.pixels) do
|
||||
for _, pixel in ipairs(row) do
|
||||
current_pixel = string.char(pixel[3], pixel[2], pixel[1])
|
||||
if current_pixel ~= previous_pixel or count == 128 then
|
||||
packets[#packets +1] = rle_packet
|
||||
count = 1
|
||||
previous_pixel = current_pixel
|
||||
else
|
||||
count = count + 1
|
||||
end
|
||||
rle_packet = string.char(128 + count - 1) .. current_pixel
|
||||
self.data = self.data
|
||||
.. string.char(pixel[3], pixel[2], pixel[1])
|
||||
end
|
||||
end
|
||||
packets[#packets +1] = rle_packet
|
||||
self.data = self.data .. table.concat(packets)
|
||||
end
|
||||
|
||||
function image:encode_footer()
|
||||
|
|
|
@ -4,7 +4,6 @@ local get_connected_players = minetest.get_connected_players
|
|||
local get_node = minetest.get_node
|
||||
local vector_add = vector.add
|
||||
local ceil = math.ceil
|
||||
local pairs = pairs
|
||||
|
||||
walkover = {}
|
||||
walkover.registered_globals = {}
|
||||
|
@ -35,9 +34,9 @@ minetest.register_globalstep(function(dtime)
|
|||
local pp = player:get_pos()
|
||||
pp.y = ceil(pp.y)
|
||||
local loc = vector_add(pp, {x=0,y=-1,z=0})
|
||||
if loc then
|
||||
if loc ~= nil then
|
||||
local nodeiamon = get_node(loc)
|
||||
if nodeiamon then
|
||||
if nodeiamon ~= nil then
|
||||
if on_walk[nodeiamon.name] then
|
||||
on_walk[nodeiamon.name](loc, nodeiamon, player)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
--Dripping Water Mod
|
||||
--by kddekadenz
|
||||
|
||||
local math = math
|
||||
|
||||
-- License of code, textures & sounds: CC0
|
||||
|
||||
--Drop entities
|
||||
|
||||
--water
|
||||
|
||||
local water_tex = "default_water_source_animated.png^[verticalframe:16:0"
|
||||
minetest.register_entity("drippingwater:drop_water", {
|
||||
hp_max = 1,
|
||||
physical = true,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.025,-0.05,-0.025,0.025,-0.01,0.025},
|
||||
pointable = false,
|
||||
visual = "cube",
|
||||
visual_size = {x=0.05, y=0.1},
|
||||
textures = {water_tex, water_tex, water_tex, water_tex, water_tex, water_tex},
|
||||
spritediv = {x=1, y=1},
|
||||
initial_sprite_basepos = {x=0, y=0},
|
||||
static_save = false,
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_sprite({x=0,y=0}, 1, 1, true)
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
local k = math.random(1,222)
|
||||
local ownpos = self.object:get_pos()
|
||||
if k==1 then
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then
|
||||
self.object:remove()
|
||||
minetest.sound_play({name="drippingwater_drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
--lava
|
||||
|
||||
local lava_tex = "default_lava_source_animated.png^[verticalframe:16:0"
|
||||
minetest.register_entity("drippingwater:drop_lava", {
|
||||
hp_max = 1,
|
||||
physical = true,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.025,-0.05,-0.025,0.025,-0.01,0.025},
|
||||
glow = math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3),
|
||||
pointable = false,
|
||||
visual = "cube",
|
||||
visual_size = {x=0.05, y=0.1},
|
||||
textures = {lava_tex, lava_tex, lava_tex, lava_tex, lava_tex, lava_tex},
|
||||
spritediv = {x=1, y=1},
|
||||
initial_sprite_basepos = {x=0, y=0},
|
||||
static_save = false,
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_sprite({x=0,y=0}, 1, 0, true)
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
local k = math.random(1,222)
|
||||
local ownpos = self.object:get_pos()
|
||||
if k == 1 then
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then
|
||||
self.object:remove()
|
||||
minetest.sound_play({name="drippingwater_lavadrip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
|
||||
--Create drop
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Create water drops",
|
||||
nodenames = {"group:opaque", "group:leaves"},
|
||||
neighbors = {"group:water"},
|
||||
interval = 2,
|
||||
chance = 22,
|
||||
action = function(pos)
|
||||
if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "water") ~= 0
|
||||
and minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
|
||||
local i = math.random(-45,45) / 100
|
||||
minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_water")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
--Create lava drop
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Create lava drops",
|
||||
nodenames = {"group:opaque"},
|
||||
neighbors = {"group:lava"},
|
||||
interval = 2,
|
||||
chance = 22,
|
||||
action = function(pos)
|
||||
if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "lava") ~= 0
|
||||
and minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
|
||||
local i = math.random(-45,45) / 100
|
||||
minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_lava")
|
||||
end
|
||||
end,
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
name = mcl_dripping
|
||||
name = drippingwater
|
||||
author = kddekadenz
|
||||
description = Drops are generated rarely under solid nodes
|
||||
depends = mcl_core
|
|
@ -1,12 +1,12 @@
|
|||
Dripping Mod
|
||||
Dripping Water Mod
|
||||
by kddekadenz
|
||||
|
||||
modified for MineClone 2 by Wuzzy and NO11
|
||||
modified for MineClone 2 by Wuzzy
|
||||
|
||||
|
||||
Installing instructions:
|
||||
|
||||
1. Copy the mcl_dripping mod folder into games/gamemode/mods
|
||||
1. Copy the drippingwater mod folder into games/gamemode/mods
|
||||
|
||||
2. Start game and enjoy :)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mcl_boats")
|
||||
|
||||
local boat_visual_size = {x = 1, y = 1, z = 1}
|
||||
local paddling_speed = 22
|
||||
|
@ -84,7 +84,7 @@ local function attach_object(self, obj)
|
|||
end
|
||||
end, name)
|
||||
obj:set_look_horizontal(yaw)
|
||||
mcl_title.set(obj, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60})
|
||||
mcl_tmp_message.message(obj, S("Sneak to dismount"))
|
||||
else
|
||||
obj:get_luaentity()._old_visual_size = visual_size
|
||||
end
|
||||
|
@ -115,7 +115,7 @@ local boat = {
|
|||
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
|
||||
visual = "mesh",
|
||||
mesh = "mcl_boats_boat.b3d",
|
||||
textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"},
|
||||
textures = {"mcl_boats_texture_oak_boat.png"},
|
||||
visual_size = boat_visual_size,
|
||||
hp_max = boat_max_hp,
|
||||
damage_texture_modifier = "^[colorize:white:0",
|
||||
|
@ -148,11 +148,6 @@ function boat.on_activate(self, staticdata, dtime_s)
|
|||
self._v = data.v
|
||||
self._last_v = self._v
|
||||
self._itemstring = data.itemstring
|
||||
|
||||
while #data.textures < 5 do
|
||||
table.insert(data.textures, data.textures[1])
|
||||
end
|
||||
|
||||
self.object:set_properties({textures = data.textures})
|
||||
end
|
||||
end
|
||||
|
@ -342,8 +337,7 @@ function boat.on_step(self, dtime, moveresult)
|
|||
self.object:get_velocity().y)
|
||||
else
|
||||
p.y = p.y + 1
|
||||
local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian"
|
||||
if is_water(p) or is_obsidian_boat then
|
||||
if is_water(p) then
|
||||
-- Inside water: Slowly sink
|
||||
local y = self.object:get_velocity().y
|
||||
y = y - 0.01
|
||||
|
@ -383,13 +377,13 @@ end
|
|||
-- Register one entity for all boat types
|
||||
minetest.register_entity("mcl_boats:boat", boat)
|
||||
|
||||
local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "boat_obsidian" }
|
||||
local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat"), S("Obsidian Boat") }
|
||||
local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak" }
|
||||
local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat") }
|
||||
local craftstuffs = {}
|
||||
if minetest.get_modpath("mcl_core") then
|
||||
craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood", "mcl_core:obsidian" }
|
||||
craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood" }
|
||||
end
|
||||
local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak", "obsidian" }
|
||||
local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak" }
|
||||
|
||||
for b=1, #boat_ids do
|
||||
local itemstring = "mcl_boats:"..boat_ids[b]
|
||||
|
@ -440,9 +434,8 @@ for b=1, #boat_ids do
|
|||
pos = vector.add(pos, vector.multiply(dir, boat_y_offset_ground))
|
||||
end
|
||||
local boat = minetest.add_entity(pos, "mcl_boats:boat")
|
||||
local texture = "mcl_boats_texture_"..images[b].."_boat.png"
|
||||
boat:get_luaentity()._itemstring = itemstring
|
||||
boat:set_properties({textures = { texture, texture, texture, texture, texture }})
|
||||
boat:set_properties({textures = { "mcl_boats_texture_"..images[b].."_boat.png" }})
|
||||
boat:set_yaw(placer:get_look_horizontal())
|
||||
if not minetest.is_creative_enabled(placer:get_player_name()) then
|
||||
itemstack:take_item()
|
||||
|
@ -477,6 +470,6 @@ minetest.register_craft({
|
|||
burntime = 20,
|
||||
})
|
||||
|
||||
if minetest.get_modpath("doc_identifier") then
|
||||
if minetest.get_modpath("doc_identifier") ~= nil then
|
||||
doc.sub.identifier.register_object("mcl_boats:boat", "craftitems", "mcl_boats:boat")
|
||||
end
|
||||
|
|
|
@ -6,7 +6,6 @@ Boats are used to travel on the surface of water.=Les bateaux sont utilisés pou
|
|||
Dark Oak Boat=Bateau en Chêne Noir
|
||||
Jungle Boat=Bateau en Acajou
|
||||
Oak Boat=Bateau en Chêne
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Utilisez [Sneak] pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet.
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Cliquez de nouveau avec le bouton droit sur le bateau pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet.
|
||||
Spruce Boat=Bateau en Sapin
|
||||
Water vehicle=Véhicule aquatique
|
||||
Sneak to dismount=
|
||||
Water vehicle=Véhicule aquatique
|
|
@ -1,12 +0,0 @@
|
|||
# textdomain: mcl_boats
|
||||
Acacia Boat=Akacjowa łódź
|
||||
Birch Boat=Brzozowa łódź
|
||||
Boat=Łódź
|
||||
Boats are used to travel on the surface of water.=Łodzie są wykorzystywane do podróżowania po powierzchni wody.
|
||||
Dark Oak Boat=Ciemno-dębowa łódź
|
||||
Jungle Boat=Tropikalna łódź
|
||||
Oak Boat=Dębowa łódź
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Kliknij prawym przyciskiem myszy na źródło wody by postawić łódź. Kliknij prawym przyciskiem myszy by w nią wsiąść. Użyj przycisków [Lewy] oraz [Prawy] by sterować, [Naprzód] by przyspieszyć i [W tył] by zwolnić lub się cofać. Kliknij [Skradanie] by z niej wyjść, uderz ją by wziąć ją jako przedmiot.
|
||||
Spruce Boat=Świerkowa łódź
|
||||
Water vehicle=Pojazd wodny
|
||||
Sneak to dismount=Skradaj się by opuścić łódź
|
|
@ -1,7 +1,7 @@
|
|||
name = mcl_boats
|
||||
author = PilzAdam
|
||||
description = Adds drivable boats.
|
||||
depends = mcl_player, flowlib, mcl_title
|
||||
depends = mcl_player, flowlib
|
||||
optional_depends = mcl_core, doc_identifier
|
||||
|
||||
|
||||
|
|
Before Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 535 B |
|
@ -67,9 +67,14 @@ function mcl_burning.set_on_fire(obj, burn_time)
|
|||
end
|
||||
|
||||
if not storage.burn_time or burn_time >= storage.burn_time then
|
||||
if obj:is_player() then
|
||||
mcl_burning.channels[obj]:send_all(tostring(mcl_burning.animation_frames))
|
||||
mcl_burning.channels[obj]:send_all("start")
|
||||
if obj:is_player() and not storage.fire_hud_id then
|
||||
storage.fire_hud_id = obj:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0.5, y = 0.5},
|
||||
scale = {x = -100, y = -100},
|
||||
text = "mcl_burning_entity_flame_animated.png^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. 1,
|
||||
z_index = 1000,
|
||||
})
|
||||
end
|
||||
storage.burn_time = burn_time
|
||||
storage.fire_damage_timer = 0
|
||||
|
@ -90,6 +95,7 @@ function mcl_burning.set_on_fire(obj, burn_time)
|
|||
fire_entity:set_properties({visual_size = size})
|
||||
fire_entity:set_attach(obj, "", offset, {x = 0, y = 0, z = 0})
|
||||
local fire_luaentity = fire_entity:get_luaentity()
|
||||
fire_luaentity:update_frame(obj, storage)
|
||||
|
||||
for _, other in pairs(minetest.get_objects_inside_radius(fire_entity:get_pos(), 0)) do
|
||||
local other_luaentity = other:get_luaentity()
|
||||
|
@ -105,7 +111,9 @@ function mcl_burning.extinguish(obj)
|
|||
if mcl_burning.is_burning(obj) then
|
||||
local storage = mcl_burning.get_storage(obj)
|
||||
if obj:is_player() then
|
||||
mcl_burning.channels[obj]:send_all("stop")
|
||||
if storage.fire_hud_id then
|
||||
obj:hud_remove(storage.fire_hud_id)
|
||||
end
|
||||
mcl_burning.storage[obj] = {}
|
||||
else
|
||||
storage.burn_time = nil
|
||||
|
@ -135,4 +143,4 @@ function mcl_burning.tick(obj, dtime, storage)
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,20 +1,14 @@
|
|||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
local pairs = pairs
|
||||
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
local get_item_group = minetest.get_item_group
|
||||
|
||||
mcl_burning = {
|
||||
storage = {},
|
||||
channels = {},
|
||||
animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8
|
||||
}
|
||||
|
||||
dofile(modpath .. "/api.lua")
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for _, player in pairs(get_connected_players()) do
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
local storage = mcl_burning.storage[player]
|
||||
if not mcl_burning.tick(player, dtime, storage) and not mcl_burning.is_affected_by_rain(player) then
|
||||
local nodes = mcl_burning.get_touching_nodes(player, {"group:puts_out_fire", "group:set_on_fire"}, storage)
|
||||
|
@ -22,12 +16,12 @@ minetest.register_globalstep(function(dtime)
|
|||
|
||||
for _, pos in pairs(nodes) do
|
||||
local node = minetest.get_node(pos)
|
||||
if get_item_group(node.name, "puts_out_fire") > 0 then
|
||||
if minetest.get_item_group(node.name, "puts_out_fire") > 0 then
|
||||
burn_time = 0
|
||||
break
|
||||
end
|
||||
|
||||
local value = get_item_group(node.name, "set_on_fire")
|
||||
local value = minetest.get_item_group(node.name, "set_on_fire")
|
||||
if value > burn_time then
|
||||
burn_time = value
|
||||
end
|
||||
|
@ -44,22 +38,23 @@ minetest.register_on_respawnplayer(function(player)
|
|||
mcl_burning.extinguish(player)
|
||||
end)
|
||||
|
||||
function mcl_burning.init_player(player)
|
||||
local meta = player:get_meta()
|
||||
-- NOTE: mcl_burning:data may be "return nil" (which deserialize into nil) for reasons unknown.
|
||||
if meta:get_string("mcl_burning:data"):find("return nil", 1, true) then
|
||||
minetest.log("warning", "[mcl_burning] 'mcl_burning:data' player meta field is invalid! Please report this bug")
|
||||
end
|
||||
mcl_burning.storage[player] = meta:contains("mcl_burning:data") and minetest.deserialize(meta:get_string("mcl_burning:data")) or {}
|
||||
mcl_burning.channels[player] = minetest.mod_channel_join("mcl_burning:" .. player:get_player_name())
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
mcl_burning.init_player(player)
|
||||
local storage
|
||||
|
||||
local burn_data = player:get_meta():get_string("mcl_burning:data")
|
||||
if burn_data == "" then
|
||||
storage = {}
|
||||
else
|
||||
storage = minetest.deserialize(burn_data)
|
||||
end
|
||||
|
||||
mcl_burning.storage[player] = storage
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
player:get_meta():set_string("mcl_burning:data", minetest.serialize(mcl_burning.storage[player]))
|
||||
local storage = mcl_burning.storage[player]
|
||||
storage.fire_hud_id = nil
|
||||
player:get_meta():set_string("mcl_burning:data", minetest.serialize(storage))
|
||||
mcl_burning.storage[player] = nil
|
||||
end)
|
||||
|
||||
|
@ -68,28 +63,27 @@ minetest.register_entity("mcl_burning:fire", {
|
|||
initial_properties = {
|
||||
physical = false,
|
||||
collisionbox = {0, 0, 0, 0, 0, 0},
|
||||
visual = "upright_sprite",
|
||||
textures = {
|
||||
name = "mcl_burning_entity_flame_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1.0,
|
||||
},
|
||||
},
|
||||
spritediv = {x = 1, y = mcl_burning.animation_frames},
|
||||
visual = "cube",
|
||||
pointable = false,
|
||||
glow = -1,
|
||||
backface_culling = false,
|
||||
},
|
||||
animation_frame = 0,
|
||||
animation_timer = 0,
|
||||
on_activate = function(self)
|
||||
self.object:set_sprite({x = 0, y = 0}, mcl_burning.animation_frames, 1.0 / mcl_burning.animation_frames)
|
||||
end,
|
||||
on_step = function(self)
|
||||
if not self:sanity_check() then
|
||||
on_step = function(self, dtime)
|
||||
local parent, storage = self:sanity_check()
|
||||
|
||||
if parent then
|
||||
self.animation_timer = self.animation_timer + dtime
|
||||
if self.animation_timer >= 0.1 then
|
||||
self.animation_timer = 0
|
||||
self.animation_frame = self.animation_frame + 1
|
||||
if self.animation_frame > mcl_burning.animation_frames - 1 then
|
||||
self.animation_frame = 0
|
||||
end
|
||||
self:update_frame(parent, storage)
|
||||
end
|
||||
else
|
||||
self.object:remove()
|
||||
end
|
||||
end,
|
||||
|
@ -97,15 +91,23 @@ minetest.register_entity("mcl_burning:fire", {
|
|||
local parent = self.object:get_attach()
|
||||
|
||||
if not parent then
|
||||
return false
|
||||
return
|
||||
end
|
||||
|
||||
local storage = mcl_burning.get_storage(parent)
|
||||
|
||||
if not storage or not storage.burn_time then
|
||||
return false
|
||||
return
|
||||
end
|
||||
|
||||
return true
|
||||
return parent, storage
|
||||
end,
|
||||
update_frame = function(self, parent, storage)
|
||||
local frame_overlay = "^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. self.animation_frame
|
||||
local fire_texture = "mcl_burning_entity_flame_animated.png" .. frame_overlay
|
||||
self.object:set_properties({textures = {"blank.png", "blank.png", fire_texture, fire_texture, fire_texture, fire_texture}})
|
||||
if parent:is_player() then
|
||||
parent:hud_change(storage.fire_hud_id, "text", "mcl_burning_hud_flame_animated.png" .. frame_overlay)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
-- Dripping Water Mod
|
||||
-- by kddekadenz
|
||||
|
||||
local math = math
|
||||
|
||||
-- License of code, textures & sounds: CC0
|
||||
|
||||
local function register_drop(liquid, glow, sound, nodes)
|
||||
minetest.register_entity("mcl_dripping:drop_" .. liquid, {
|
||||
hp_max = 1,
|
||||
physical = true,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.01, 0.01, -0.01, 0.01, 0.01, 0.01},
|
||||
glow = glow,
|
||||
pointable = false,
|
||||
visual = "sprite",
|
||||
visual_size = {x = 0.1, y = 0.1},
|
||||
textures = {""},
|
||||
spritediv = {x = 1, y = 1},
|
||||
initial_sprite_basepos = {x = 0, y = 0},
|
||||
static_save = false,
|
||||
_dropped = false,
|
||||
on_activate = function(self)
|
||||
self.object:set_properties({
|
||||
textures = {"[combine:2x2:" .. -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=default_" .. liquid .. "_source_animated.png"}
|
||||
})
|
||||
end,
|
||||
on_step = function(self, dtime)
|
||||
local k = math.random(1, 222)
|
||||
local ownpos = self.object:get_pos()
|
||||
if k == 1 then
|
||||
self.object:set_acceleration(vector.new(0, -5, 0))
|
||||
end
|
||||
if minetest.get_node(vector.offset(ownpos, 0, 0.5, 0)).name == "air" then
|
||||
self.object:set_acceleration(vector.new(0, -5, 0))
|
||||
end
|
||||
if minetest.get_node(vector.offset(ownpos, 0, -0.1, 0)).name ~= "air" then
|
||||
local ent = self.object:get_luaentity()
|
||||
if not ent._dropped then
|
||||
ent._dropped = true
|
||||
minetest.sound_play({name = "drippingwater_" .. sound .. "drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
|
||||
end
|
||||
if k < 3 then
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
minetest.register_abm({
|
||||
label = "Create drops",
|
||||
nodenames = nodes,
|
||||
neighbors = {"group:" .. liquid},
|
||||
interval = 2,
|
||||
chance = 22,
|
||||
action = function(pos)
|
||||
if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1, 0)).name, liquid) ~= 0
|
||||
and minetest.get_node(vector.offset(pos, 0, -1, 0)).name == "air" then
|
||||
local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100
|
||||
minetest.add_entity(vector.offset(pos, x, -0.520, z), "mcl_dripping:drop_" .. liquid)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
register_drop("water", 1, "", {"group:opaque", "group:leaves"})
|
||||
register_drop("lava", math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), "lava", {"group:opaque"})
|
|
@ -19,10 +19,7 @@ local function deal_falling_damage(self, dtime)
|
|||
end
|
||||
self._hit = self._hit or {}
|
||||
for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
|
||||
local entity = obj:get_luaentity()
|
||||
if entity and entity.name == "__builtin:item" then
|
||||
obj:remove()
|
||||
elseif mcl_util.get_hp(obj) > 0 and not self._hit[obj] then
|
||||
if mcl_util.get_hp(obj) > 0 and not self._hit[obj] then
|
||||
self._hit[obj] = true
|
||||
local way = self._startpos.y - pos.y
|
||||
local damage = (way - 1) * 2
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# textdomain: mcl_falling_nodes
|
||||
@1 was smashed by a falling anvil.=@1 została zmiażdżona przez spadające kowadło.
|
||||
@1 was smashed by a falling block.=@1 została zmiażdżona przez spadający blok.
|
|
@ -1,5 +1,5 @@
|
|||
--these are lua locals, used for higher performance
|
||||
local minetest, math, vector, ipairs, pairs = minetest, math, vector, ipairs, pairs
|
||||
local minetest, math, vector, ipairs = minetest, math, vector, ipairs
|
||||
|
||||
--this is used for the player pool in the sound buffer
|
||||
local pool = {}
|
||||
|
@ -233,7 +233,7 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
local dug_node = minetest.get_node(pos)
|
||||
local tooldef
|
||||
local tool
|
||||
if digger then
|
||||
if digger ~= nil then
|
||||
tool = digger:get_wielded_item()
|
||||
tooldef = minetest.registered_tools[tool:get_name()]
|
||||
|
||||
|
@ -290,10 +290,10 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
end
|
||||
end
|
||||
|
||||
if digger and mcl_experience.throw_xp and not silk_touch_drop then
|
||||
if digger and mcl_experience.throw_experience and not silk_touch_drop then
|
||||
local experience_amount = minetest.get_item_group(dug_node.name,"xp")
|
||||
if experience_amount > 0 then
|
||||
mcl_experience.throw_xp(pos, experience_amount)
|
||||
mcl_experience.throw_experience(pos, experience_amount)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -314,7 +314,7 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
end
|
||||
-- Spawn item and apply random speed
|
||||
local obj = minetest.add_item(dpos, drop_item)
|
||||
if obj then
|
||||
if obj ~= nil then
|
||||
local x = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
x = -x
|
||||
|
@ -363,17 +363,6 @@ if not time_to_live then
|
|||
time_to_live = 300
|
||||
end
|
||||
|
||||
local function cxcz(o, cw, one, zero)
|
||||
if cw < 0 then
|
||||
table.insert(o, { [one]=1, y=0, [zero]=0 })
|
||||
table.insert(o, { [one]=-1, y=0, [zero]=0 })
|
||||
else
|
||||
table.insert(o, { [one]=-1, y=0, [zero]=0 })
|
||||
table.insert(o, { [one]=1, y=0, [zero]=0 })
|
||||
end
|
||||
return o
|
||||
end
|
||||
|
||||
minetest.register_entity(":__builtin:item", {
|
||||
initial_properties = {
|
||||
hp_max = 1,
|
||||
|
@ -394,7 +383,7 @@ minetest.register_entity(":__builtin:item", {
|
|||
-- The itemstring MUST be set immediately to a non-empty string after creating the entity.
|
||||
-- The hand is NOT permitted as dropped item. ;-)
|
||||
-- Item entities will be deleted if they still have an empty itemstring on their first on_step tick.
|
||||
itemstring = "",
|
||||
itemstring = '',
|
||||
|
||||
-- If true, item will fall
|
||||
physical_state = true,
|
||||
|
@ -480,7 +469,7 @@ minetest.register_entity(":__builtin:item", {
|
|||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
local data = minetest.serialize({
|
||||
return minetest.serialize({
|
||||
itemstring = self.itemstring,
|
||||
always_collect = self.always_collect,
|
||||
age = self.age,
|
||||
|
@ -488,39 +477,6 @@ minetest.register_entity(":__builtin:item", {
|
|||
_flowing = self._flowing,
|
||||
_removed = self._removed,
|
||||
})
|
||||
-- sfan5 guessed that the biggest serializable item
|
||||
-- entity would have a size of 65530 bytes. This has
|
||||
-- been experimentally verified to be still too large.
|
||||
--
|
||||
-- anon5 has calculated that the biggest serializable
|
||||
-- item entity has a size of exactly 65487 bytes:
|
||||
--
|
||||
-- 1. serializeString16 can handle max. 65535 bytes.
|
||||
-- 2. The following engine metadata is always saved:
|
||||
-- • 1 byte (version)
|
||||
-- • 2 byte (length prefix)
|
||||
-- • 14 byte “__builtin:item”
|
||||
-- • 4 byte (length prefix)
|
||||
-- • 2 byte (health)
|
||||
-- • 3 × 4 byte = 12 byte (position)
|
||||
-- • 4 byte (yaw)
|
||||
-- • 1 byte (version 2)
|
||||
-- • 2 × 4 byte = 8 byte (pitch and roll)
|
||||
-- 3. This leaves 65487 bytes for the serialization.
|
||||
if #data > 65487 then -- would crash the engine
|
||||
local stack = ItemStack(self.itemstring)
|
||||
stack:get_meta():from_table(nil)
|
||||
self.itemstring = stack:to_string()
|
||||
minetest.log(
|
||||
"warning",
|
||||
"Overlong item entity metadata removed: “" ..
|
||||
self.itemstring ..
|
||||
"” had serialized length of " ..
|
||||
#data
|
||||
)
|
||||
return self:get_staticdata()
|
||||
end
|
||||
return data
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
|
@ -608,7 +564,7 @@ minetest.register_entity(":__builtin:item", {
|
|||
return true
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime, moveresult)
|
||||
on_step = function(self, dtime)
|
||||
if self._removed then
|
||||
self.object:set_properties({
|
||||
physical = false
|
||||
|
@ -618,7 +574,7 @@ minetest.register_entity(":__builtin:item", {
|
|||
return
|
||||
end
|
||||
self.age = self.age + dtime
|
||||
if self._collector_timer then
|
||||
if self._collector_timer ~= nil then
|
||||
self._collector_timer = self._collector_timer + dtime
|
||||
end
|
||||
if time_to_live > 0 and self.age > time_to_live then
|
||||
|
@ -675,18 +631,6 @@ minetest.register_entity(":__builtin:item", {
|
|||
end
|
||||
end
|
||||
|
||||
-- Destroy item when it collides with a cactus
|
||||
if moveresult and moveresult.collides then
|
||||
for _, collision in pairs(moveresult.collisions) do
|
||||
local pos = collision.node_pos
|
||||
if collision.type == "node" and minetest.get_node(pos).name == "mcl_core:cactus" then
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Push item out when stuck inside solid opaque node
|
||||
if def and def.walkable and def.groups and def.groups.opaque == 1 then
|
||||
local shootdir
|
||||
|
@ -698,6 +642,16 @@ minetest.register_entity(":__builtin:item", {
|
|||
-- 1st: closest
|
||||
-- 2nd: other direction
|
||||
-- 3rd and 4th: other axis
|
||||
local cxcz = function(o, cw, one, zero)
|
||||
if cw < 0 then
|
||||
table.insert(o, { [one]=1, y=0, [zero]=0 })
|
||||
table.insert(o, { [one]=-1, y=0, [zero]=0 })
|
||||
else
|
||||
table.insert(o, { [one]=-1, y=0, [zero]=0 })
|
||||
table.insert(o, { [one]=1, y=0, [zero]=0 })
|
||||
end
|
||||
return o
|
||||
end
|
||||
if math.abs(cx) < math.abs(cz) then
|
||||
order = cxcz(order, cx, "x", "z")
|
||||
order = cxcz(order, cz, "z", "x")
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
local modname = minetest.get_current_modname()
|
||||
local S = minetest.get_translator(modname)
|
||||
local S = minetest.get_translator("mcl_minecarts")
|
||||
|
||||
local has_mcl_wip = minetest.get_modpath("mcl_wip")
|
||||
|
||||
mcl_minecarts = {}
|
||||
mcl_minecarts.modpath = minetest.get_modpath(modname)
|
||||
mcl_minecarts.modpath = minetest.get_modpath("mcl_minecarts")
|
||||
mcl_minecarts.speed_max = 10
|
||||
mcl_minecarts.check_float_time = 15
|
||||
|
||||
|
@ -198,27 +197,14 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
|||
else
|
||||
self._last_float_check = self._last_float_check + dtime
|
||||
end
|
||||
|
||||
local pos, rou_pos, node = self.object:get_pos()
|
||||
local r = 0.6
|
||||
for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do
|
||||
if minetest.get_node(vector.offset(pos, node_pos[1], 0, node_pos[2])).name == "mcl_core:cactus" then
|
||||
detach_driver(self)
|
||||
for d = 1, #drop do
|
||||
minetest.add_item(pos, drop[d])
|
||||
end
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local pos, rou_pos, node
|
||||
-- Drop minecart if it isn't on a rail anymore
|
||||
if self._last_float_check >= mcl_minecarts.check_float_time then
|
||||
pos = self.object:get_pos()
|
||||
rou_pos = vector.round(pos)
|
||||
node = minetest.get_node(rou_pos)
|
||||
local g = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||
if g ~= self._railtype and self._railtype then
|
||||
if g ~= self._railtype and self._railtype ~= nil then
|
||||
-- Detach driver
|
||||
if player then
|
||||
if self._old_pos then
|
||||
|
@ -537,7 +523,7 @@ function mcl_minecarts.place_minecart(itemstack, pointed_thing, placer)
|
|||
local cart = minetest.add_entity(railpos, entity_id)
|
||||
local railtype = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||
local le = cart:get_luaentity()
|
||||
if le then
|
||||
if le ~= nil then
|
||||
le._railtype = railtype
|
||||
end
|
||||
local cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype)
|
||||
|
@ -620,7 +606,7 @@ Register a minecart
|
|||
local function register_minecart(itemstring, entity_id, description, tt_help, longdesc, usagehelp, mesh, textures, icon, drop, on_rightclick, on_activate_by_rail, creative)
|
||||
register_entity(entity_id, mesh, textures, drop, on_rightclick, on_activate_by_rail)
|
||||
register_craftitem(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative)
|
||||
if minetest.get_modpath("doc_identifier") then
|
||||
if minetest.get_modpath("doc_identifier") ~= nil then
|
||||
doc.sub.identifier.register_object(entity_id, "craftitems", itemstring)
|
||||
end
|
||||
end
|
||||
|
@ -659,7 +645,7 @@ register_minecart(
|
|||
if player then
|
||||
mcl_player.player_set_animation(player, "sit" , 30)
|
||||
player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0})
|
||||
mcl_title.set(clicker, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60})
|
||||
mcl_tmp_message.message(clicker, S("Sneak to dismount"))
|
||||
end
|
||||
end, name)
|
||||
end
|
||||
|
|
|
@ -33,4 +33,3 @@ Activates minecarts when powered=Active les wagonnets lorsqu'il est alimenté
|
|||
Emits redstone power when a minecart is detected=Émet de l'énergie redstone lorsqu'un wagonnet est détecté
|
||||
Vehicle for fast travel on rails=Véhicule pour voyager rapidement sur rails
|
||||
Can be ignited by tools or powered activator rail=Peut être allumé par des outils ou un rail d'activation motorisé
|
||||
Sneak to dismount=
|
|
@ -1,36 +0,0 @@
|
|||
# textdomain: mcl_minecarts
|
||||
Minecart=Wagonik
|
||||
Minecarts can be used for a quick transportion on rails.=Wagoniki mogą być użyte do szybkiego transportu po torach.
|
||||
Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type.=Wagoniki mogą jeździć tylko po torach i zawsze podążają za wytyczoną ścieżką. W przypadku skrzyżowań typu T, gdzie nie ma prostej ścieżki, skręcają w lew. Ich szybkość zależy od typu torów.
|
||||
You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=Możesz postawić wagonik na torach. Kliknij prawym przyciskiem myszy aby do niego wejść. Uderz go by zaczął się poruszać.
|
||||
To obtain the minecart, punch it while holding down the sneak key.=Aby odzyskać wagonik uderz go podczas skradania.
|
||||
A minecart with TNT is an explosive vehicle that travels on rail.=Wagonik z TNT jest wybuchowym pojazdem podróżującym po torach.
|
||||
Place it on rails. Punch it to move it. The TNT is ignited with a flint and steel or when the minecart is on an powered activator rail.=Postaw go na torach. Uderz by zaczął się poruszać. TNT zapala się krzesiwem lub gdy wagonik jest na zasilonych torach aktywacyjnych.
|
||||
To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=Aby odzyskać wagonik z TNT uderz go podczas skradania. Nie możesz tego zrobić gdy TNT jest zapalone.
|
||||
A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=Wagonik z piecem jest pojazdem podróżującym na torach. Napędza on samego siebie za pomocą paliwa.
|
||||
Place it on rails. If you give it some coal, the furnace will start burning for a long time and the minecart will be able to move itself. Punch it to get it moving.=Postaw go na torach. Jeśli dasz mu nieco węgla piec zacznie palić przez długi czas, a wagonik będzie się sam poruszał. Uderz go by zaczął się poruszać.
|
||||
To obtain the minecart and furnace, punch them while holding down the sneak key.=Aby odzyskać wagonik z piecem uderz go podczas skradania.
|
||||
Minecart with Chest=Wagonik ze skrzynią
|
||||
Minecart with Furnace=Wagonik z piecem
|
||||
Minecart with Command Block=Wagonik z blokiem poleceń
|
||||
Minecart with Hopper=Wagonik z lejem
|
||||
Minecart with TNT=Wagonik z TNT
|
||||
Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed.=Postaw je na ziemi by zbudować ścieżkę z torów. Tory automatycznie połączą się ze sobą i zamienią się w zakręty, skrzyżowania typu T, skrzyżowania i równie w zależności od potrzeb.
|
||||
Rail=Tor
|
||||
Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Zwyczajne tory nieco spowalniają wagoniki ze względu na tarcie.
|
||||
Powered Rail=Zasilane tory
|
||||
Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Zasilane tory mogą przyspieszać lub spowalniać wagoniki.
|
||||
Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Bez zasilania czerwienitem tory będą spowalniać wagoniki. Aby sprawić by je przyspieszały zasil je czerwienitem.
|
||||
Activator Rail=Tory aktywacyjne
|
||||
Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Tory aktywacyjne są wykorzystywane do aktywacji specjalnych wagoników.
|
||||
To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=Aby ten tor aktywował wagonik, zasil go czerwienitem i spraw by wagonik po nim przejechał.
|
||||
Detector Rail=Tory z czujnikiem
|
||||
Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Tory z czujnikiem są w stanie wykryć kiedy wagonik po nich przejeżdża i wysłać sygnał do czerwienitowych mechanizmów.
|
||||
To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=Aby wykryć wagonik i dostarczyć zasilanie czerwienitem podłącz go czerwienitem to mechanizmu i spraw by wagonik po nim przejechał.
|
||||
Track for minecarts=Tor dla wagoników
|
||||
Speed up when powered, slow down when not powered=Przyspiesza gdy zasilane, spowalnia gdy nie
|
||||
Activates minecarts when powered=Aktywuje wagoniki gdy zasilane
|
||||
Emits redstone power when a minecart is detected=Emituje zasilanie czerwienitem gdy wagonik jest wykryty
|
||||
Vehicle for fast travel on rails=Pojazd do szybkiej podróży na torach
|
||||
Can be ignited by tools or powered activator rail=Może być zapalony przez narzędzia, lub zasilane tor aktywacyjne
|
||||
Sneak to dismount=Zacznij się skradać by zejść
|
|
@ -1,6 +1,6 @@
|
|||
name = mcl_minecarts
|
||||
author = Krock
|
||||
description = Minecarts are vehicles to move players quickly on rails.
|
||||
depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons
|
||||
depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons
|
||||
optional_depends = doc_identifier, mcl_wip
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mcl_minecarts")
|
||||
|
||||
-- Template rail function
|
||||
local function register_rail(itemstring, tiles, def_extras, creative)
|
||||
|
@ -206,11 +206,11 @@ register_rail("mcl_minecarts:detector_rail_on",
|
|||
|
||||
-- Crafting
|
||||
minetest.register_craft({
|
||||
output = "mcl_minecarts:rail 16",
|
||||
output = 'mcl_minecarts:rail 16',
|
||||
recipe = {
|
||||
{"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"},
|
||||
{"mcl_core:iron_ingot", "mcl_core:stick", "mcl_core:iron_ingot"},
|
||||
{"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"},
|
||||
{'mcl_core:iron_ingot', '', 'mcl_core:iron_ingot'},
|
||||
{'mcl_core:iron_ingot', 'mcl_core:stick', 'mcl_core:iron_ingot'},
|
||||
{'mcl_core:iron_ingot', '', 'mcl_core:iron_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ local mod_mobspawners = minetest_get_modpath("mcl_mobspawners")
|
|||
--local height_switcher = false
|
||||
|
||||
-- Get translator
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mcl_mobs")
|
||||
|
||||
-- CMI support check
|
||||
--local use_cmi = minetest.global_exists("cmi")
|
||||
|
@ -129,7 +129,6 @@ end
|
|||
local api_path = minetest.get_modpath(minetest.get_current_modname()).."/api/mob_functions/"
|
||||
|
||||
--ignite all parts of the api
|
||||
dofile(api_path .. "flow_lib.lua")
|
||||
dofile(api_path .. "ai.lua")
|
||||
dofile(api_path .. "animation.lua")
|
||||
dofile(api_path .. "collision.lua")
|
||||
|
@ -430,7 +429,7 @@ function mobs:register_mob(name, def)
|
|||
--harmed_by_heal = def.harmed_by_heal,
|
||||
})
|
||||
|
||||
if minetest_get_modpath("doc_identifier") then
|
||||
if minetest_get_modpath("doc_identifier") ~= nil then
|
||||
doc.sub.identifier.register_object(name, "basics", "mobs")
|
||||
end
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@ local minetest_get_item_group = minetest.get_item_group
|
|||
local minetest_get_node = minetest.get_node
|
||||
local minetest_line_of_sight = minetest.line_of_sight
|
||||
local minetest_get_node_light = minetest.get_node_light
|
||||
local minetest_registered_nodes = minetest.registered_nodes
|
||||
local flow = mobs.get_flowing_dir
|
||||
|
||||
local DOUBLE_PI = math.pi * 2
|
||||
local THIRTY_SECONDTH_PI = DOUBLE_PI * 0.03125
|
||||
|
@ -523,8 +521,8 @@ ______ _
|
|||
| _| | | | | |
|
||||
| | | | |_| |
|
||||
\_| |_|\__, |
|
||||
__/ |
|
||||
|___/
|
||||
__/ |
|
||||
|___/
|
||||
]]--
|
||||
|
||||
-- state switching logic (stand, walk, run, attacks)
|
||||
|
@ -677,12 +675,12 @@ end
|
|||
--[[
|
||||
___
|
||||
|_ |
|
||||
| |_ _ _ __ ___ _ __
|
||||
| | | | | '_ ` _ \| '_ \
|
||||
| |_ _ _ __ ___ _ __
|
||||
| | | | | '_ ` _ \| '_ \
|
||||
/\__/ / |_| | | | | | | |_) |
|
||||
\____/ \__,_|_| |_| |_| .__/
|
||||
| |
|
||||
|_|
|
||||
| |
|
||||
|_|
|
||||
]]--
|
||||
|
||||
|
||||
|
@ -789,8 +787,8 @@ ___ ___ _ _ _
|
|||
| |\/| |/ _` | | '_ \ | | / _ \ / _` | |/ __|
|
||||
| | | | (_| | | | | | | |___| (_) | (_| | | (__
|
||||
\_| |_/\__,_|_|_| |_| \_____/\___/ \__, |_|\___|
|
||||
__/ |
|
||||
|___/
|
||||
__/ |
|
||||
|___/
|
||||
]]--
|
||||
|
||||
--the main loop
|
||||
|
@ -992,7 +990,7 @@ function mobs.mob_step(self, dtime)
|
|||
if self.memory <= 0 then
|
||||
|
||||
--reset states when coming out of hostile state
|
||||
if self.attacking then
|
||||
if self.attacking ~= nil then
|
||||
self.state_timer = -1
|
||||
end
|
||||
|
||||
|
@ -1013,19 +1011,6 @@ function mobs.mob_step(self, dtime)
|
|||
end
|
||||
end
|
||||
|
||||
--mobs flow from Crafter
|
||||
local pos = self.object:get_pos()
|
||||
if pos then
|
||||
local flow_dir = flow(pos)
|
||||
if flow_dir then
|
||||
flow_dir = vector.multiply(flow_dir,10)
|
||||
local vel = self.object:get_velocity()
|
||||
local acceleration = vector.new(flow_dir.x-vel.x,flow_dir.y-vel.y,flow_dir.z-vel.z)
|
||||
acceleration = vector.multiply(acceleration, 0.01)
|
||||
self.object:add_velocity(acceleration)
|
||||
end
|
||||
end
|
||||
|
||||
--mob is stunned after being hit
|
||||
if self.pause_timer > 0 then
|
||||
self.pause_timer = self.pause_timer - dtime
|
||||
|
|
|
@ -41,7 +41,7 @@ mobs.explode_attack_walk = function(self,dtime)
|
|||
--make mob walk up to player within 2 nodes distance then start exploding
|
||||
if distance_from_attacking >= self.reach and
|
||||
--don't allow explosion to cancel unless out of the reach boundary
|
||||
not (self.explosion_animation and self.explosion_animation > 0 and distance_from_attacking <= self.defuse_reach) then
|
||||
not (self.explosion_animation ~= nil and self.explosion_animation > 0 and distance_from_attacking <= self.defuse_reach) then
|
||||
|
||||
mobs.set_velocity(self, self.run_velocity)
|
||||
mobs.set_mob_animation(self,"run")
|
||||
|
@ -85,8 +85,9 @@ end
|
|||
|
||||
--this is a small helper function to make working with explosion animations easier
|
||||
mobs.reverse_explosion_animation = function(self,dtime)
|
||||
|
||||
--if explosion animation was greater than 0 then reverse it
|
||||
if self.explosion_animation and self.explosion_animation > 0 then
|
||||
if self.explosion_animation ~= nil and self.explosion_animation > 0 then
|
||||
self.explosion_animation = self.explosion_animation - dtime
|
||||
if self.explosion_animation < 0 then
|
||||
self.explosion_animation = 0
|
||||
|
|
|
@ -122,10 +122,7 @@ mobs.death_logic = function(self, dtime)
|
|||
if self.death_animation_timer >= 1.25 then
|
||||
item_drop(self,false,1)
|
||||
mobs.death_effect(self)
|
||||
mcl_experience.throw_xp(self.object:get_pos(), math_random(self.xp_min, self.xp_max))
|
||||
if self.on_die then
|
||||
self.on_die(self, self.object:get_pos())
|
||||
end
|
||||
mcl_experience.throw_experience(self.object:get_pos(), math_random(self.xp_min, self.xp_max))
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
@ -158,4 +155,4 @@ mobs.death_logic = function(self, dtime)
|
|||
if self.pause_timer <= 0 then
|
||||
mobs.set_velocity(self,0)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,78 +0,0 @@
|
|||
--this is from https://github.com/HybridDog/builtin_item/blob/e6dfd9dce86503b3cbd1474257eca5f6f6ca71c2/init.lua#L50
|
||||
local
|
||||
minetest,vector,math,pairs,minetest_get_node,vector_subtract,minetest_registered_nodes
|
||||
=
|
||||
minetest,vector,math,pairs,minetest.get_node,vector.subtract,minetest.registered_nodes
|
||||
|
||||
local tab
|
||||
local n
|
||||
local function get_nodes(pos)
|
||||
tab,n = {},1
|
||||
for i = -1,1,2 do
|
||||
for _,p in pairs({
|
||||
{x=pos.x+i, y=pos.y, z=pos.z},
|
||||
{x=pos.x, y=pos.y, z=pos.z+i}
|
||||
}) do
|
||||
tab[n] = {p, minetest_get_node(p)}
|
||||
n = n+1
|
||||
end
|
||||
end
|
||||
return tab
|
||||
end
|
||||
|
||||
|
||||
local data
|
||||
local param2
|
||||
local nd
|
||||
local par2
|
||||
local name
|
||||
local tmp
|
||||
local c_node
|
||||
function mobs.get_flowing_dir(pos)
|
||||
c_node = minetest_get_node(pos).name
|
||||
if c_node ~= "mcl_core:water_flowing" and c_node ~= "mcl_core:water" then
|
||||
return nil
|
||||
end
|
||||
data = get_nodes(pos)
|
||||
param2 = minetest_get_node(pos).param2
|
||||
if param2 > 7 then
|
||||
return nil
|
||||
end
|
||||
if c_node == "mcl_core:water" then
|
||||
for _,i in pairs(data) do
|
||||
nd = i[2]
|
||||
name = nd.name
|
||||
par2 = nd.param2
|
||||
if name == "mcl_core:water_flowing" and par2 == 7 then
|
||||
return(vector_subtract(i[1],pos))
|
||||
end
|
||||
end
|
||||
end
|
||||
for _,i in pairs(data) do
|
||||
nd = i[2]
|
||||
name = nd.name
|
||||
par2 = nd.param2
|
||||
if name == "mcl_core:water_flowing" and par2 < param2 then
|
||||
return(vector_subtract(i[1],pos))
|
||||
end
|
||||
end
|
||||
for _,i in pairs(data) do
|
||||
nd = i[2]
|
||||
name = nd.name
|
||||
par2 = nd.param2
|
||||
if name == "mcl_core:water_flowing" and par2 >= 11 then
|
||||
return(vector_subtract(i[1],pos))
|
||||
end
|
||||
end
|
||||
for _,i in pairs(data) do
|
||||
nd = i[2]
|
||||
name = nd.name
|
||||
par2 = nd.param2
|
||||
tmp = minetest_registered_nodes[name]
|
||||
if tmp and not tmp.walkable and name ~= "mcl_core:water_flowing" and name ~= "mcl_core:water" then
|
||||
return(vector_subtract(i[1],pos))
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
|
@ -32,15 +32,12 @@ end
|
|||
mobs.float = function(self)
|
||||
|
||||
local acceleration = self.object:get_acceleration()
|
||||
|
||||
if not acceleration then
|
||||
if acceleration and acceleration.y ~= 0 then
|
||||
self.object:set_acceleration(vector.new(0,0,0))
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
if acceleration.y ~= 0 then
|
||||
self.object:set_acceleration({x=0, y=0, z=0})
|
||||
end
|
||||
|
||||
local current_velocity = self.object:get_velocity()
|
||||
|
||||
local goal_velocity = {
|
||||
|
@ -49,7 +46,7 @@ mobs.float = function(self)
|
|||
z = 0,
|
||||
}
|
||||
|
||||
local new_velocity_addition = vector.subtract(goal_velocity, current_velocity)
|
||||
local new_velocity_addition = vector.subtract(goal_velocity,current_velocity)
|
||||
|
||||
new_velocity_addition.x = 0
|
||||
new_velocity_addition.z = 0
|
||||
|
|
|
@ -36,8 +36,9 @@ mobs.shoot_projectile_handling = function(arrow_item, pos, dir, yaw, shooter, po
|
|||
le._collectable = collectable
|
||||
|
||||
--play custom shoot sound
|
||||
if shooter and shooter.shoot_sound then
|
||||
if shooter ~= nil and shooter.shoot_sound then
|
||||
minetest.sound_play(shooter.shoot_sound, {pos=pos, max_hear_distance=16}, true)
|
||||
end
|
||||
|
||||
return obj
|
||||
end
|
|
@ -5,7 +5,6 @@ local get_node_light = minetest.get_node_light
|
|||
local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air
|
||||
local get_biome_name = minetest.get_biome_name
|
||||
local get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
|
||||
|
||||
local math_random = math.random
|
||||
|
@ -19,7 +18,6 @@ local vector_floor = vector.floor
|
|||
local table_copy = table.copy
|
||||
local table_remove = table.remove
|
||||
|
||||
local pairs = pairs
|
||||
|
||||
-- range for mob count
|
||||
local aoc_range = 48
|
||||
|
@ -281,7 +279,7 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh
|
|||
end
|
||||
|
||||
-- if toggle set to nil then ignore day/night check
|
||||
if day_toggle then
|
||||
if day_toggle ~= nil then
|
||||
|
||||
local tod = (minetest.get_timeofday() or 0) * 24000
|
||||
|
||||
|
@ -371,7 +369,7 @@ function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ligh
|
|||
if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
|
||||
-- inside block
|
||||
minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!")
|
||||
if ent.spawn_small_alternative and (not minetest.registered_nodes[node_ok(pos).name].walkable) then
|
||||
if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then
|
||||
minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative)
|
||||
spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative)
|
||||
end
|
||||
|
@ -542,7 +540,7 @@ if mobs_spawn then
|
|||
timer = timer + dtime
|
||||
if timer >= 10 then
|
||||
timer = 0
|
||||
for _,player in pairs(get_connected_players()) do
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
-- after this line each "break" means "continue"
|
||||
local do_mob_spawning = true
|
||||
repeat
|
||||
|
@ -550,15 +548,15 @@ if mobs_spawn then
|
|||
--they happen in a single server step
|
||||
|
||||
local player_pos = player:get_pos()
|
||||
local dimension = mcl_worlds.pos_to_dimension(player_pos)
|
||||
local _,dimension = mcl_worlds.y_to_layer(player_pos.y)
|
||||
|
||||
if dimension == "void" or dimension == "default" then
|
||||
break -- ignore void and unloaded area
|
||||
end
|
||||
|
||||
local min, max = decypher_limits(player_pos.y)
|
||||
local min,max = decypher_limits(player_pos.y)
|
||||
|
||||
for i = 1, math_random(1,4) do
|
||||
for i = 1,math_random(1,4) do
|
||||
-- after this line each "break" means "continue"
|
||||
local do_mob_algorithm = true
|
||||
repeat
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mcl_mobs")
|
||||
|
||||
-- name tag
|
||||
minetest.register_craftitem("mcl_mobs:nametag", {
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# textdomain: mcl_mobs
|
||||
Peaceful mode active! No monsters will spawn.=Tryb pokojowy aktywowany! Potwory nie będą się pojawiać.
|
||||
This allows you to place a single mob.=To pozwala na przywołanie jednego moba.
|
||||
Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=Postaw to w miejscu w którym chcesz aby pojawił się mob. Zwierzęta pojawią się jako oswojone chyba, że będziesz się skradał podczas stawiania. Jeśli postawisz to na spawnerze to zmienisz którego moba przywołuje.
|
||||
You need the “maphack” privilege to change the mob spawner.=Potrzebujesz przywileju "maphack", aby zmienić spawner.
|
||||
Name Tag=Znacznik
|
||||
A name tag is an item to name a mob.=Znacznik jest przedmiotem pozwalającym nazwać moba.
|
||||
Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=Zanim użyjesz znacznika musisz wybrać imię przy kowadle. Następnie możesz użyć znacznika by nazwać moba. To zużywa znacznik.
|
||||
Only peaceful mobs allowed!=Tylko pokojowe moby są dozwolone!
|
||||
Give names to mobs=Nazwij moby
|
||||
Set name at anvil=Wybierz imię przy kowadle
|
|
@ -1,9 +1,8 @@
|
|||
mcl_paintings = {}
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
dofile(minetest.get_modpath(modname).."/paintings.lua")
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/paintings.lua")
|
||||
|
||||
local S = minetest.get_translator(modname)
|
||||
local S = minetest.get_translator("mcl_paintings")
|
||||
|
||||
local math = math
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:mcl_paintings
|
||||
Painting=Obraz
|
|
@ -8,7 +8,7 @@
|
|||
-- NOTE: Most strings intentionally not marked for translation, other mods already have these items.
|
||||
-- TODO: Remove this file eventually, most items are already outsourced in other mods.
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
local c = mobs_mc.is_item_variable_overridden
|
||||
|
||||
|
@ -234,8 +234,8 @@ end
|
|||
if c("ender_eye") and c("blaze_powder") and c("blaze_rod") then
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mobs_mc:ender_eye",
|
||||
recipe = { "mobs_mc:blaze_powder", "mobs_mc:blaze_rod"},
|
||||
output = 'mobs_mc:ender_eye',
|
||||
recipe = { 'mobs_mc:blaze_powder', 'mobs_mc:blaze_rod'},
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
-- NOTE: Strings intentionally not marked for translation, other mods already have these items.
|
||||
-- TODO: Remove this file eventually, all items here are already outsourced in other mods.
|
||||
|
||||
--local S = minetest.get_translator(minetest.get_current_modname())
|
||||
--local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--maikerumines throwing code
|
||||
--arrow (weapon)
|
||||
|
@ -83,7 +83,7 @@ THROWING_ARROW_ENTITY.on_step = function(self, dtime)
|
|||
if self.timer>0.2 then
|
||||
local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1.5)
|
||||
for k, obj in pairs(objs) do
|
||||
if obj:get_luaentity() then
|
||||
if obj:get_luaentity() ~= nil then
|
||||
if obj:get_luaentity().name ~= "mobs_mc:arrow_entity" and obj:get_luaentity().name ~= "__builtin:item" then
|
||||
local damage = 3
|
||||
minetest.sound_play("damage", {pos = pos}, true)
|
||||
|
@ -108,7 +108,7 @@ THROWING_ARROW_ENTITY.on_step = function(self, dtime)
|
|||
if self.lastpos.x~=nil then
|
||||
if node.name ~= "air" then
|
||||
minetest.sound_play("bowhit1", {pos = pos}, true)
|
||||
minetest.add_item(self.lastpos, "mobs_mc:arrow")
|
||||
minetest.add_item(self.lastpos, 'mobs_mc:arrow')
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
|
@ -155,7 +155,7 @@ end
|
|||
|
||||
if c("arrow") and c("flint") and c("feather") and c("stick") then
|
||||
minetest.register_craft({
|
||||
output = "mobs_mc:arrow 4",
|
||||
output = 'mobs_mc:arrow 4',
|
||||
recipe = {
|
||||
{mobs_mc.items.flint},
|
||||
{mobs_mc.items.stick},
|
||||
|
@ -181,11 +181,11 @@ if c("bow") then
|
|||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mobs_mc:bow_wood",
|
||||
output = 'mobs_mc:bow_wood',
|
||||
recipe = {
|
||||
{mobs_mc.items.string, mobs_mc.items.stick, ""},
|
||||
{mobs_mc.items.string, "", mobs_mc.items.stick},
|
||||
{mobs_mc.items.string, mobs_mc.items.stick, ""},
|
||||
{mobs_mc.items.string, mobs_mc.items.stick, ''},
|
||||
{mobs_mc.items.string, '', mobs_mc.items.stick},
|
||||
{mobs_mc.items.string, mobs_mc.items.stick, ''},
|
||||
}
|
||||
})
|
||||
end
|
||||
|
@ -259,7 +259,7 @@ if c("egg") then
|
|||
})
|
||||
|
||||
-- shoot egg
|
||||
local function mobs_shoot_egg(item, player, pointed_thing)
|
||||
local mobs_shoot_egg = function (item, player, pointed_thing)
|
||||
|
||||
local playerpos = player:get_pos()
|
||||
|
||||
|
@ -349,7 +349,7 @@ mobs:register_arrow("mobs_mc:snowball_entity", {
|
|||
|
||||
if c("snowball") then
|
||||
-- shoot snowball
|
||||
local function mobs_shoot_snowball(item, player, pointed_thing)
|
||||
local mobs_shoot_snowball = function (item, player, pointed_thing)
|
||||
|
||||
local playerpos = player:get_pos()
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
-- TODO: Remove this file eventually, all items here are already outsourced in other mods.
|
||||
-- TODO: Add translation.
|
||||
|
||||
--local S = local S = minetest.get_translator(minetest.get_current_modname())
|
||||
--local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
-- Heads system
|
||||
|
||||
|
|
|
@ -190,10 +190,9 @@ Origin of those models:
|
|||
* [Spennnyyy](https://freesound.org/people/Spennnyyy/) (CC0)
|
||||
* `mcl_totems_totem.ogg`
|
||||
* Source: <https://freesound.org/people/Spennnyyy/sounds/323502/>
|
||||
* [Baŝto](https://opengameart.org/users/ba%C5%9Dto) (remixer) and [kantouth](https://freesound.org/people/kantouth/) (original author)
|
||||
* [Baŝto](https://opengameart.org/users/ba%C5%9Dto)
|
||||
* `mobs_mc_skeleton_random.*.ogg` (CC BY 3.0)
|
||||
* Source: <https://opengameart.org/content/walking-skeleton>
|
||||
* Based on: <https://freesound.org/people/kantouth/sounds/115113/>
|
||||
* [spookymodem](https://freesound.org/people/spookymodem/)
|
||||
* `mobs_mc_skeleton_death.ogg` (CC0)
|
||||
* <https://freesound.org/people/spookymodem/sounds/202091/>
|
||||
|
@ -307,4 +306,4 @@ Origin of those models:
|
|||
|
||||
Note: Many of these sounds have been more or less modified to fit the game.
|
||||
|
||||
Sounds not mentioned here are licensed under CC0.
|
||||
Sounds not mentioned hre are licensed under CC0.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
--################### AGENT - seemingly unused
|
||||
--###################
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
mobs:register_mob("mobs_mc:agent", {
|
||||
type = "npc",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
mobs:register_mob("mobs_mc:bat", {
|
||||
description = S("Bat"),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
-- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez
|
||||
-- blaze.lua partial copy of mobs_mc/ghast.lua
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### BLAZE
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### CHICKEN
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
local cow_def = {
|
||||
description = S("Cow"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### CREEPER
|
||||
|
@ -37,7 +37,7 @@ mobs:register_mob("mobs_mc:creeper", {
|
|||
},
|
||||
makes_footstep_sound = false,
|
||||
walk_velocity = 1.05,
|
||||
run_velocity = 2.1,
|
||||
run_velocity = 3.25,
|
||||
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
|
||||
attack_type = "explode",
|
||||
eye_height = 1.25,
|
||||
|
@ -47,8 +47,8 @@ mobs:register_mob("mobs_mc:creeper", {
|
|||
--explosion_radius = 3,
|
||||
--explosion_damage_radius = 6,
|
||||
--explosiontimer_reset_radius = 6,
|
||||
reach = 3,
|
||||
defuse_reach = 5.2,
|
||||
reach = 1.5,
|
||||
defuse_reach = 4,
|
||||
explosion_timer = 0.3,
|
||||
allow_fuse_reset = true,
|
||||
stop_to_explode = true,
|
||||
|
@ -72,7 +72,7 @@ mobs:register_mob("mobs_mc:creeper", {
|
|||
-- TODO: Make creeper flash after doing this as well.
|
||||
-- TODO: Test and debug this code.
|
||||
on_rightclick = function(self, clicker)
|
||||
if self._forced_explosion_countdown_timer then
|
||||
if self._forced_explosion_countdown_timer ~= nil then
|
||||
return
|
||||
end
|
||||
local item = clicker:get_wielded_item()
|
||||
|
@ -92,11 +92,10 @@ mobs:register_mob("mobs_mc:creeper", {
|
|||
end
|
||||
end,
|
||||
do_custom = function(self, dtime)
|
||||
if self._forced_explosion_countdown_timer then
|
||||
if self._forced_explosion_countdown_timer ~= nil then
|
||||
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
|
||||
if self._forced_explosion_countdown_timer <= 0 then
|
||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||
mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { griefing = mobs_griefing, drop_chance = 1.0}, self.object)
|
||||
mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
@ -152,7 +151,6 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
|||
description = S("Charged Creeper"),
|
||||
type = "monster",
|
||||
spawn_class = "hostile",
|
||||
hostile = true,
|
||||
hp_min = 20,
|
||||
hp_max = 20,
|
||||
xp_min = 5,
|
||||
|
@ -188,8 +186,8 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
|||
--explosion_radius = 3,
|
||||
--explosion_damage_radius = 6,
|
||||
--explosiontimer_reset_radius = 3,
|
||||
reach = 3,
|
||||
defuse_reach = 5.2,
|
||||
reach = 1.5,
|
||||
defuse_reach = 4,
|
||||
explosion_timer = 0.3,
|
||||
allow_fuse_reset = true,
|
||||
stop_to_explode = true,
|
||||
|
@ -198,7 +196,7 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
|||
-- TODO: Make creeper flash after doing this as well.
|
||||
-- TODO: Test and debug this code.
|
||||
on_rightclick = function(self, clicker)
|
||||
if self._forced_explosion_countdown_timer then
|
||||
if self._forced_explosion_countdown_timer ~= nil then
|
||||
return
|
||||
end
|
||||
local item = clicker:get_wielded_item()
|
||||
|
@ -218,11 +216,10 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
|||
end
|
||||
end,
|
||||
do_custom = function(self, dtime)
|
||||
if self._forced_explosion_countdown_timer then
|
||||
if self._forced_explosion_countdown_timer ~= nil then
|
||||
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
|
||||
if self._forced_explosion_countdown_timer <= 0 then
|
||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||
mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { griefing = mobs_griefing, drop_chance = 1.0}, self.object)
|
||||
mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
--################### ENDERDRAGON
|
||||
--###################
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
mobs:register_mob("mobs_mc:enderdragon", {
|
||||
description = S("Ender Dragon"),
|
||||
|
@ -103,7 +103,7 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
|||
mcl_portals.spawn_gateway_portal()
|
||||
mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open")
|
||||
if self._initial then
|
||||
mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000
|
||||
mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000
|
||||
minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,11 +24,9 @@
|
|||
-- added rain damage.
|
||||
-- fixed the grass_with_dirt issue.
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
local vector = vector
|
||||
|
||||
local function telesound(pos, is_source)
|
||||
local telesound = function(pos, is_source)
|
||||
local snd
|
||||
if is_source then
|
||||
snd = "mobs_mc_enderman_teleport_src"
|
||||
|
@ -304,7 +302,7 @@ mobs:register_mob("mobs_mc:enderman", {
|
|||
if self.attacking then
|
||||
local target = self.attacking
|
||||
local pos = target:get_pos()
|
||||
if pos then
|
||||
if pos ~= nil then
|
||||
if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then
|
||||
self:teleport(target)
|
||||
end
|
||||
|
@ -343,8 +341,8 @@ mobs:register_mob("mobs_mc:enderman", {
|
|||
-- self:teleport(nil)
|
||||
-- self.state = ""
|
||||
--else
|
||||
if self.attack and not minetest.settings:get_bool("creative_mode") then
|
||||
self.state = "attack"
|
||||
if self.attack ~= nil and not minetest.settings:get_bool("creative_mode") then
|
||||
self.state = 'attack'
|
||||
end
|
||||
--end
|
||||
end
|
||||
|
@ -461,7 +459,7 @@ mobs:register_mob("mobs_mc:enderman", {
|
|||
end
|
||||
end
|
||||
end
|
||||
elseif self._taken_node and self._taken_node ~= "" and self._take_place_timer >= self._next_take_place_time then
|
||||
elseif self._taken_node ~= nil and self._taken_node ~= "" and self._take_place_timer >= self._next_take_place_time then
|
||||
-- Place taken node
|
||||
self._take_place_timer = 0
|
||||
self._next_take_place_time = math.random(take_frequency_min, take_frequency_max)
|
||||
|
@ -487,12 +485,12 @@ mobs:register_mob("mobs_mc:enderman", {
|
|||
end
|
||||
end,
|
||||
do_teleport = function(self, target)
|
||||
if target then
|
||||
if target ~= nil then
|
||||
local target_pos = target:get_pos()
|
||||
-- Find all solid nodes below air in a 10×10×10 cuboid centered on the target
|
||||
local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(target_pos, 5), vector.add(target_pos, 5), {"group:solid", "group:cracky", "group:crumbly"})
|
||||
local telepos
|
||||
if nodes then
|
||||
if nodes ~= nil then
|
||||
if #nodes > 0 then
|
||||
-- Up to 64 attempts to teleport
|
||||
for n=1, math.min(64, #nodes) do
|
||||
|
@ -527,7 +525,7 @@ mobs:register_mob("mobs_mc:enderman", {
|
|||
-- We need to add (or subtract) different random numbers to each vector component, so it couldn't be done with a nice single vector.add() or .subtract():
|
||||
local randomCube = vector.new( pos.x + 8*(pr:next(0,16)-8), pos.y + 8*(pr:next(0,16)-8), pos.z + 8*(pr:next(0,16)-8) )
|
||||
local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(randomCube, 4), vector.add(randomCube, 4), {"group:solid", "group:cracky", "group:crumbly"})
|
||||
if nodes then
|
||||
if nodes ~= nil then
|
||||
if #nodes > 0 then
|
||||
-- Up to 8 low-level (in total up to 8*8 = 64) attempts to teleport
|
||||
for n=1, math.min(8, #nodes) do
|
||||
|
@ -559,13 +557,13 @@ mobs:register_mob("mobs_mc:enderman", {
|
|||
end,
|
||||
on_die = function(self, pos)
|
||||
-- Drop carried node on death
|
||||
if self._taken_node and self._taken_node ~= "" then
|
||||
if self._taken_node ~= nil and self._taken_node ~= "" then
|
||||
minetest.add_item(pos, self._taken_node)
|
||||
end
|
||||
end,
|
||||
do_punch = function(self, hitter, tflp, tool_caps, dir)
|
||||
-- damage from rain caused by itself so we don't want it to attack itself.
|
||||
if hitter ~= self.object and hitter then
|
||||
if hitter ~= self.object and hitter ~= nil then
|
||||
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
|
||||
-- self:teleport(nil)
|
||||
--else
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
--################### ENDERMITE
|
||||
--###################
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
mobs:register_mob("mobs_mc:endermite", {
|
||||
description = S("Endermite"),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### GHAST
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
--################### GUARDIAN
|
||||
--###################
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
mobs:register_mob("mobs_mc:guardian", {
|
||||
description = S("Guardian"),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
--################### GUARDIAN
|
||||
--###################
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
mobs:register_mob("mobs_mc:guardian_elder", {
|
||||
description = S("Elder Guardian"),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### HORSE
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local path = minetest.get_modpath(minetest.get_current_modname())
|
||||
local path = minetest.get_modpath("mobs_mc")
|
||||
|
||||
if not minetest.get_modpath("mobs_mc_gameconfig") then
|
||||
mobs_mc = {}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### IRON GOLEM
|
||||
|
@ -158,11 +158,11 @@ mobs_mc.tools.check_iron_golem_summon = function(pos)
|
|||
if ok then
|
||||
-- Remove the nodes
|
||||
minetest.remove_node(pos)
|
||||
minetest.check_for_falling(pos)
|
||||
core.check_for_falling(pos)
|
||||
for i=1, 4 do
|
||||
local cpos = vector.add(pos, checks[c][i])
|
||||
minetest.remove_node(cpos)
|
||||
minetest.check_for_falling(cpos)
|
||||
core.check_for_falling(cpos)
|
||||
end
|
||||
-- Summon iron golem
|
||||
local place
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### LLAMA
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
# textdomain: mobs_mc
|
||||
Totem of Undying=Token nieśmiertelności
|
||||
A totem of undying is a rare artifact which may safe you from certain death.=Totem nieśmiertelności to rzadki artefakt, który może uchronić cię przed pewną śmiercią.
|
||||
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=Totem działa tylko kiedy trzymasz go w dłoni. Jeśli otrzymasz obrażenia od upadku zostaniesz oszczędzony i pozostanie ci 1 HP, jednak totem zostanie wtedy zniszczony.
|
||||
Agent=Agent
|
||||
Bat=Nietoperz
|
||||
Blaze=Płomyk
|
||||
Chicken=Kurczak
|
||||
Cow=Krowa
|
||||
Mooshroom=Muuuchomor
|
||||
Creeper=Creeper
|
||||
Ender Dragon=Smok kresu
|
||||
Enderman=Enderman
|
||||
Endermite=Endermit
|
||||
Ghast=Ghast
|
||||
Elder Guardian=Prastrażnik
|
||||
Guardian=Strażnik
|
||||
Horse=Koń
|
||||
Skeleton Horse=Koń szkielet
|
||||
Zombie Horse=Koń zombie
|
||||
Donkey=Osioł
|
||||
Mule=Muł
|
||||
Iron Golem=Żelazny golem
|
||||
Llama=Lama
|
||||
Ocelot=Ocelot
|
||||
Parrot=Papuga
|
||||
Pig=Świnia
|
||||
Polar Bear=Niedźwiedź polarny
|
||||
Rabbit=Królik
|
||||
Killer Bunny=Królik zabójca
|
||||
Sheep=Owca
|
||||
Shulker=Shulker
|
||||
Silverfish=Rybik cukrowy
|
||||
Skeleton=Szkielet
|
||||
Stray=Tułacz
|
||||
Wither Skeleton=Witherowy szkielet
|
||||
Magma Cube=Kostka magmy
|
||||
Slime=Szlam
|
||||
Snow Golem=Śnieżny golem
|
||||
Spider=Pająk
|
||||
Cave Spider=Pająk jaskiniowy
|
||||
Squid=Kałamarnica
|
||||
Vex=Dręczyciel
|
||||
Evoker=Przywoływacz
|
||||
Illusioner=Iluzjonista
|
||||
Villager=Osadnik
|
||||
Vindicator=Obrońca
|
||||
Zombie Villager=Osadnik zombie
|
||||
Witch=Wiedźma
|
||||
Wither=Wither
|
||||
Wolf=Wilk
|
||||
Husk=Posuch
|
||||
Zombie=Zombie
|
||||
Zombie Pigman=Świniak zombie
|
||||
Iron Horse Armor=Żelazna zbroja dla konia
|
||||
Iron horse armor can be worn by horses to increase their protection from harm a bit.=Żelazna zbroja dla konia może być noszona przez konie aby nieco zwiększyć ich odporność na obrażenia.
|
||||
Golden Horse Armor=Złota zbroja dla konia
|
||||
Golden horse armor can be worn by horses to increase their protection from harm.=Złota zbroja dla konia może być noszona przez konie aby zwiększyć ich odporność na obrażenia.
|
||||
Diamond Horse Armor=Diamentowa zbroja dla konia
|
||||
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Diamentowa zbroja dla konia może być noszona przez konie aby istotnie zwiększyć ich odporność na obrażenia.
|
||||
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Połóż ją na koniu aby założyć zbroję dla konia. Osły i muły nie mogą nosić zbroi dla konia.
|
||||
Farmer=Rolnik
|
||||
Fisherman=Rybak
|
||||
Fletcher=Łuczarz
|
||||
Shepherd=Pasterz
|
||||
Librarian=Bibliotekarz
|
||||
Cartographer=Kartograf
|
||||
Armorer=Płatnerz
|
||||
Leatherworker=Rymarz
|
||||
Butcher=Rzeźnik
|
||||
Weapon Smith=Zbrojmistrz
|
||||
Tool Smith=Narzędziarz
|
||||
Cleric=Kapłan
|
||||
Nitwit=Głupiec
|
||||
Protects you from death while wielding it=Chroni przed śmiercią gdy go trzymasz
|
|
@ -28,7 +28,6 @@ Pig=
|
|||
Polar Bear=
|
||||
Rabbit=
|
||||
Killer Bunny=
|
||||
The Killer Bunny=
|
||||
Sheep=
|
||||
Shulker=
|
||||
Silverfish=
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### OCELOT AND CAT
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### PARROT
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
mobs:register_mob("mobs_mc:pig", {
|
||||
description = S("Pig"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### POLARBEAR
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
local rabbit = {
|
||||
description = S("Rabbit"),
|
||||
|
@ -233,4 +233,4 @@ mobs:spawn(spawn_grass)
|
|||
mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0)
|
||||
|
||||
-- Note: This spawn egg does not exist in Minecraft
|
||||
mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit_caerbannog.png", 0)
|
||||
mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit.png^[colorize:#FF0000:192", 0) -- TODO: Update inventory image
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### SHEEP
|
||||
|
@ -38,7 +38,7 @@ local rainbow_colors = {
|
|||
"unicolor_red_violet"
|
||||
}
|
||||
|
||||
if minetest.get_modpath("mcl_wool") then
|
||||
if minetest.get_modpath("mcl_wool") ~= nil then
|
||||
colors["unicolor_light_blue"] = { mobs_mc.items.wool_light_blue, "#5050FFD0" }
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### SHULKER
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
--################### SILVERFISH
|
||||
--###################
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
mobs:register_mob("mobs_mc:silverfish", {
|
||||
description = S("Silverfish"),
|
||||
|
@ -61,7 +61,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
|
|||
description = "Stone Monster Egg",
|
||||
tiles = {"default_stone.png"},
|
||||
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
|
||||
drop = "",
|
||||
drop = '',
|
||||
is_ground_content = true,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
after_dig_node = spawn_silverfish,
|
||||
|
@ -72,7 +72,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
|
|||
tiles = {"default_cobble.png"},
|
||||
is_ground_content = false,
|
||||
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
|
||||
drop = "",
|
||||
drop = '',
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
after_dig_node = spawn_silverfish,
|
||||
})
|
||||
|
@ -82,7 +82,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
|
|||
tiles = {"default_mossycobble.png"},
|
||||
is_ground_content = false,
|
||||
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
|
||||
drop = "",
|
||||
drop = '',
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
after_dig_node = spawn_silverfish,
|
||||
})
|
||||
|
@ -94,7 +94,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
|
|||
tiles = {"default_stone_brick.png"},
|
||||
is_ground_content = false,
|
||||
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
|
||||
drop = "",
|
||||
drop = '',
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
after_dig_node = spawn_silverfish,
|
||||
})
|
||||
|
@ -104,7 +104,7 @@ if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then
|
|||
tiles = {"default_stone_block.png"},
|
||||
is_ground_content = false,
|
||||
groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1},
|
||||
drop = "",
|
||||
drop = '',
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
after_dig_node = spawn_silverfish,
|
||||
})
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local mod_bows = minetest.get_modpath("mcl_bows")
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
local mod_bows = minetest.get_modpath("mcl_bows") ~= nil
|
||||
|
||||
--###################
|
||||
--################### SKELETON
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### WITHER SKELETON
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
-- Returns a function that spawns children in a circle around pos.
|
||||
-- To be used as on_die callback.
|
||||
|
@ -31,22 +31,20 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
|
|||
speed_penalty = 0.5
|
||||
end
|
||||
local mob = minetest.add_entity(newpos, child_mob)
|
||||
if mob then
|
||||
if (not mother_stuck) then
|
||||
mob:set_velocity(vector.multiply(dir, eject_speed * speed_penalty))
|
||||
end
|
||||
mob:set_yaw(angle - math.pi/2)
|
||||
table.insert(children, mob)
|
||||
angle = angle + (math.pi*2)/children_count
|
||||
if (not mother_stuck) then
|
||||
mob:set_velocity(vector.multiply(dir, eject_speed * speed_penalty))
|
||||
end
|
||||
mob:set_yaw(angle - math.pi/2)
|
||||
table.insert(children, mob)
|
||||
angle = angle + (math.pi*2)/children_count
|
||||
end
|
||||
-- If mother was murdered, children attack the killer after 1 second
|
||||
if self.state == "attack" then
|
||||
minetest.after(1.0, function(children, enemy)
|
||||
for c = 1, #children do
|
||||
for c=1, #children do
|
||||
local child = children[c]
|
||||
local le = child:get_luaentity()
|
||||
if le then
|
||||
if le ~= nil then
|
||||
le.state = "attack"
|
||||
le.attack = enemy
|
||||
end
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
local snow_trail_frequency = 0.5 -- Time in seconds for checking to add a new snow trail
|
||||
|
||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||
local mod_throwing = minetest.get_modpath("mcl_throwing")
|
||||
local mod_throwing = minetest.get_modpath("mcl_throwing") ~= nil
|
||||
|
||||
local gotten_texture = {
|
||||
"mobs_mc_snowman.png",
|
||||
|
@ -179,9 +179,9 @@ mobs_mc.tools.check_snow_golem_summon = function(pos)
|
|||
minetest.remove_node(pos)
|
||||
minetest.remove_node(b1)
|
||||
minetest.remove_node(b2)
|
||||
minetest.check_for_falling(pos)
|
||||
minetest.check_for_falling(b1)
|
||||
minetest.check_for_falling(b2)
|
||||
core.check_for_falling(pos)
|
||||
core.check_for_falling(b1)
|
||||
core.check_for_falling(b2)
|
||||
local obj = minetest.add_entity(place, "mobs_mc:snowman")
|
||||
if obj then
|
||||
summon_particles(obj)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--made for MC like Survival game
|
||||
--License for code WTFPL and otherwise stated in readmes
|
||||
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local S = minetest.get_translator("mobs_mc")
|
||||
|
||||
--###################
|
||||
--################### SPIDER
|
||||
|
|