Merge branch 'master' into dyable-leather-armor

This commit is contained in:
AFCMS 2021-04-16 13:45:05 +02:00
commit fb0a687bdc
95 changed files with 1075 additions and 790 deletions

42
.luacheckrc Normal file
View File

@ -0,0 +1,42 @@
unused_args = false
allow_defined_top = true
max_line_length = false
globals = {
"minetest", "core",
}
read_globals = {
"DIR_DELIM",
"dump", "dump2",
"vector",
"VoxelManip", "VoxelArea",
"PseudoRandom", "PcgRandom",
"ItemStack",
"Settings",
"unpack",
table = {
fields = {
"copy",
"indexof",
"insert_all",
"key_value_swap",
}
},
string = {
fields = {
"split",
"trim",
}
},
math = {
fields = {
"hypot",
"sign",
"factorial"
}
},
}

View File

@ -7,13 +7,11 @@ But first, some things to note:
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 ***.
MineClone 2 is maintained by two persons. Namely, kay27 and EliasFleckenstein. You can find us
in the Minetest forums (forums.minetest.net), in IRC in the #minetest
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>.
There is **no** guarantee we will accept anything from anybody.
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.
@ -26,8 +24,7 @@ For small and medium changes:
* Fork the repository
* Do your change in a new branch
* Upload the repository somewhere where it can be accessed from the Internet and
notify us
* Create a pull request to get your changes merged into master
For small changes, sending us a patch is also good.
@ -41,40 +38,30 @@ 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.
Contributors will be credited in `README.md`.
If your code causes bugs and crashes, it is your responsibility to fix them as soon as possible.
## Quality remarks
Again: There is ***no*** guarantee we will accept anything from anybody.
But we will gladly take in code from others when we feel it saves us work
in the long run.
We mostly use plain merging rather than rebasing or squash merging.
### Inclusion criteria
Depending on what you add, the chances for inclusion vary:
Your commit names should be relatively descriptive, e.g. when saying "Fix #issueid", the commit message should also contain the title of the issue.
### High chance for inclusion
* Gameplay features in Minecraft which are missing in MineClone 2
Contributors will be credited in `CREDITS.md`.
### Medium chance for inclusion (discuss first)
* Features which don't a impact on gameplay
* GUI improvement
* Features from pocket or console edition
## Features > 1.12
### Low chance for inclusion (discuss/optimize first)
* Overhaul of architecture / mod structure
* Mass-itemstring changes all over the place
* Added files have a unusual high file size
* Indentation looks like crazy
* Single commits which add several unrelated things
* Gameplay features which don't exist in Minecraft
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.
### Instant rejection
* Proprietary **anything**
* Code contains `minetest.env` anywhere
## What we accept
## Coding style guide
* Indentations should reflect the code flow
* Use tabs, not spaces for indentation (tab size = 8)
* Never use `minetest.env`
* 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.
## What we reject
* Any features which cause critical bugs, sending them to rework/fix or trying to fix immediately.
* Some small portions of big entirely missing features which just definitely break gamplay balance give nothing useful
* Controversial features, which some people support while others do not should be discussed well, with publishing forum announcements, at least during the week. In case if there are still doubts - send them into the mod.
## Reporting bugs
Report all bugs and missing Minecraft features here:

117
CREDITS.md Normal file
View File

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

52
LEGAL.md Normal file
View File

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

View File

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

194
README.md
View File

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

View File

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

View File

@ -4350,7 +4350,7 @@ function mobs:alias_mob(old_name, new_name)
end
--[[
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
@ -4367,4 +4367,3 @@ minetest.register_globalstep(function(dtime)
end
timer = 0
end)
]]--

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 1021 B

View File

@ -38,12 +38,12 @@ mobs:register_mob("mobs_mc:villager_zombie", {
visual = "mesh",
mesh = "mobs_mc_villager_zombie.b3d",
textures = {
{"mobs_mc_zombie_butcher.png"},
{"mobs_mc_zombie_farmer.png"},
{"mobs_mc_zombie_librarian.png"},
{"mobs_mc_zombie_priest.png"},
{"mobs_mc_zombie_smith.png"},
{"mobs_mc_zombie_villager.png"}
{"mobs_mc_empty.png", "mobs_mc_zombie_butcher.png", "mobs_mc_empty.png"},
{"mobs_mc_empty.png", "mobs_mc_zombie_farmer.png", "mobs_mc_empty.png"},
{"mobs_mc_empty.png", "mobs_mc_zombie_librarian.png", "mobs_mc_empty.png"},
{"mobs_mc_empty.png", "mobs_mc_zombie_priest.png", "mobs_mc_empty.png"},
{"mobs_mc_empty.png", "mobs_mc_zombie_smith.png", "mobs_mc_empty.png"},
{"mobs_mc_empty.png", "mobs_mc_zombie_villager.png", "mobs_mc_empty.png"},
},
visual_size = {x=2.75, y=2.75},
makes_footstep_sound = true,
@ -147,8 +147,8 @@ mobs:register_mob("mobs_mc:villager_zombie", {
})
mobs:spawn_specific(
"mobs_mc:villager_zombie",
"overworld",
"mobs_mc:villager_zombie",
"overworld",
"ground",
{
"FlowerForest_underground",
@ -231,15 +231,14 @@ mobs:spawn_specific(
"MesaBryce_sandlevel",
"Mesa_sandlevel",
},
0,
7,
30,
4090,
4,
mobs_mc.spawn_height.overworld_min,
0,
7,
30,
4090,
4,
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
--mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0)

View File

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

View File

@ -67,7 +67,7 @@ doc_identifier.identify = function(itemstack, user, pointed_thing)
local pos = pointed_thing.under
local node = minetest.get_node(pos)
if minetest.registered_nodes[node.name] ~= nil then
local nodedef = minetest.registered_nodes[node.name]
--local nodedef = minetest.registered_nodes[node.name]
if(node.name == "ignore") then
show_message(username, "error_ignore")
elseif doc.entry_exists("nodes", node.name) then
@ -198,7 +198,7 @@ minetest.register_craft({
if minetest.get_modpath("mcl_core") ~= nil then
minetest.register_craft({
output = "doc_identifier:identifier_solid",
recipe = { { "mcl_core:glass" },
recipe = { { "mcl_core:glass" },
{ "group:stick" } }
})
end

View File

@ -907,7 +907,7 @@ doc.add_category("nodes", {
-- Do some cleanup of the probability table
if max == 1 or max == nil then
-- Sort by rarity
local comp = function(p1, p2)
local comp = function(p1, p2)
return p1.rarity < p2.rarity
end
table.sort(probtables, comp)
@ -1269,7 +1269,6 @@ local function gather_descs()
if type(def._doc_items_hidden) == "boolean" then
hidden = def._doc_items_hidden
end
local custom_image
name = scrub_newlines(name)
local infotable = {
name = name,

View File

@ -33,7 +33,6 @@ local fmt, find, gmatch, match, sub, split, lower =
local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil
local pairs, next, unpack = pairs, next, unpack
local vec_add, vec_mul = vector.add, vector.multiply
local DEFAULT_SIZE = 10
local MIN_LIMIT, MAX_LIMIT = 10, 12
@ -1001,7 +1000,7 @@ else
end
end)
local function on_use(user)
--[[local function on_use(user)
local name = user:get_player_name()
if next(recipe_filters) then
@ -1011,7 +1010,7 @@ else
end
show_formspec(name, "mcl_craftguide", make_formspec(name))
end
end]]
end
@ -1098,7 +1097,6 @@ if progressive_mode then
local name = player:get_player_name()
init_data(name)
local meta = player:get_meta()
local name = player:get_player_name()
local data = player_data[name]
data.inv_items = deserialize(meta:get_string("inv_items")) or {}
@ -1144,7 +1142,7 @@ else
end
function mcl_craftguide.show(name)
local player = minetest.get_player_by_name(name)
local player = get_player_by_name(name)
if next(recipe_filters) then
local data = player_data[name]
data.items_raw = get_filtered_items(player)

View File

@ -62,7 +62,6 @@ end)
-- nodes which have flower placement rules
doc.sub.items.register_factoid("nodes", "groups", function(itemstring, def)
local datastring = ""
if def.groups.place_flowerlike == 1 then
return S("This plant can only grow on grass blocks and dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher.")
elseif def.groups.place_flowerlike == 2 then
@ -130,7 +129,7 @@ end)
-- Armor
doc.sub.items.register_factoid(nil, "use", function(itemstring, def)
local def = minetest.registered_items[itemstring]
--local def = minetest.registered_items[itemstring]
local s = ""
local head = minetest.get_item_group(itemstring, "armor_head")
local torso = minetest.get_item_group(itemstring, "armor_torso")
@ -173,7 +172,6 @@ end)
doc.sub.items.register_factoid(nil, "groups", function(itemstring, def)
if def._repair_material then
local mdef = minetest.registered_items[def._repair_material]
local desc
if mdef and mdef.description and mdef.description ~= "" then
return S("This item can be repaired at an anvil with: @1.", mdef.description)
elseif def._repair_material == "group:wood" then

View File

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

View File

@ -15,6 +15,7 @@ minetest.register_tool("mcl_armor:elytra", {
_doc_items_usagehelp = usage,
inventory_image = "mcl_armor_inv_elytra.png",
groups = {armor_torso=1, mcl_armor_points=0, mcl_armor_uses=10, enchantability=0},
_repair_material = "mcl_mobitems:leather",
sounds = {
_mcl_armor_equip = "mcl_armor_equip_leather",
_mcl_armor_unequip = "mcl_armor_unequip_leather",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 746 B

After

Width:  |  Height:  |  Size: 271 B

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -99,7 +99,7 @@ minetest.register_abm({
-- No decay near unloaded areas since these might include water.
if not check_surroundings(pos, "ignore") then
if wet <= 0 then
local n_def = minetest.registered_nodes[node.name] or nil
--local n_def = minetest.registered_nodes[node.name] or nil
local nn = minetest.get_node_or_nil({x=pos.x,y=pos.y+1,z=pos.z})
if not nn or not nn.name then
return

View File

@ -5,7 +5,10 @@ minetest.register_craftitem("mcl_farming:wheat_seeds", {
description = S("Wheat Seeds"),
_tt_help = S("Grows on farmland"),
_doc_items_longdesc = S("Grows into a wheat plant. Chickens like wheat seeds."),
_doc_items_usagehelp = S("Place the wheat seeds on farmland (which can be created with a hoe) to plant a wheat plant. They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it wheat seeds."),
_doc_items_usagehelp = S([[
Place the wheat seeds on farmland (which can be created with a hoe) to plant a wheat plant.
They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it wheat seeds.
]]),
groups = { craftitem=1 },
inventory_image = "mcl_farming_wheat_seeds.png",
on_place = function(itemstack, placer, pointed_thing)
@ -28,7 +31,10 @@ for i=1,7 do
if i == 1 then
create = true
name = S("Premature Wheat Plant")
longdesc = S("Premature wheat plants grow on farmland under sunlight in 8 stages. On hydrated farmland, they grow faster. They can be harvested at any time but will only yield a profit when mature.")
longdesc = S([[
Premature wheat plants grow on farmland under sunlight in 8 stages.
On hydrated farmland, they grow faster. They can be harvested at any time but will only yield a profit when mature.
]])
else
create = false
end
@ -54,7 +60,8 @@ for i=1,7 do
{-0.5, -0.5, -0.5, 0.5, sel_heights[i], 0.5}
},
},
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1},
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1,
dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
})
@ -62,7 +69,10 @@ end
minetest.register_node("mcl_farming:wheat", {
description = S("Mature Wheat Plant"),
_doc_items_longdesc = S("Mature wheat plants are ready to be harvested for wheat and wheat seeds. They won't grow any further."),
_doc_items_longdesc = S([[
Mature wheat plants are ready to be harvested for wheat and wheat seeds.
They won't grow any further.
]]),
sunlight_propagates = true,
paramtype = "light",
paramtype2 = "meshoptions",
@ -81,7 +91,8 @@ minetest.register_node("mcl_farming:wheat", {
{ items = {'mcl_farming:wheat_item'} }
}
},
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1},
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1, attached_node=1,
dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
})
@ -144,9 +155,9 @@ minetest.register_node("mcl_farming:hay_block", {
is_ground_content = false,
stack_max = 64,
paramtype2 = "facedir",
is_ground_content = false,
on_place = mcl_util.rotate_axis,
groups = {handy=1, hoey=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80},
groups = {handy=1, hoey=1, flammable=2, fire_encouragement=60,
fire_flammability=20, building_block=1, fall_damage_add_percent=-80},
sounds = mcl_sounds.node_sound_leaves_defaults(),
on_rotate = on_rotate,
_mcl_blast_resistance = 0.5,

View File

@ -76,7 +76,7 @@ mcl_fences.register_fence_gate = function(id, fence_gate_name, texture, groups,
local meta2
local state2 = 0
local function update_gate(pos, node)
local function update_gate(pos, node)
minetest.set_node(pos, node)
end

View File

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

View File

@ -6,7 +6,7 @@ local add_entity = minetest.add_entity
-- Fire Charge
minetest.register_craftitem("mcl_fire:fire_charge", {
description = S("Fire Charge"),
_tt_help = S("Dispenser projectile").."\n"..S("Starts fires and ignites blocks"),
_tt_help = S("Dispenser projectile").."\n"..S("Starts fires and ignites blocks"),
_doc_items_longdesc = S("Fire charges are primarily projectiles which can be launched from dispensers, they will fly in a straight line and burst into a fire on impact. Alternatively, they can be used to ignite fires directly."),
_doc_items_usagehelp = S("Put the fire charge into a dispenser and supply it with redstone power to launch it. To ignite a fire directly, simply place the fire charge on the ground, which uses it up."),
inventory_image = "mcl_fire_fire_charge.png",

View File

@ -5,7 +5,7 @@ local add_node = minetest.add_node
-- Flint and Steel
minetest.register_tool("mcl_fire:flint_and_steel", {
description = S("Flint and Steel"),
_tt_help = S("Starts fires and ignites blocks"),
_tt_help = S("Starts fires and ignites blocks"),
_doc_items_longdesc = S("Flint and steel is a tool to start fires and ignite blocks."),
_doc_items_usagehelp = S("Rightclick the surface of a block to attempt to light a fire in front of it or ignite the block. A few blocks have an unique reaction when ignited."),
inventory_image = "mcl_fire_flint_and_steel.png",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

View File

@ -1,11 +1,6 @@
--Fishing Rod, Bobber, and Flying Bobber mechanics and Bobber artwork by Rootyjr.
local S = minetest.get_translator("mcl_fishing")
local mod_throwing = minetest.get_modpath("mcl_throwing")
local entity_mapping = {
["mcl_fishing:bobber"] = "mcl_fishing:bobber_entity",
}
local bobber_ENTITY={
physical = false,
@ -42,8 +37,7 @@ local fish = function(itemstack, player, pointed_thing)
local num = 0
local ent = nil
local noent = true
local durability = 65
local unbreaking = mcl_enchanting.get_enchantment(itemstack, "unbreaking")
if unbreaking > 0 then
@ -61,7 +55,6 @@ local fish = function(itemstack, player, pointed_thing)
local itemname
local items
local itemcount = 1
local itemwear = 0
local pr = PseudoRandom(os.time() * math.random(1, 100))
local r = pr:next(1, 100)
local fish_values = {85, 84.8, 84.7, 84.5}
@ -173,7 +166,7 @@ local fish = function(itemstack, player, pointed_thing)
if noent == true then
local playerpos = player:get_pos()
local dir = player:get_look_dir()
local obj = mcl_throwing.throw("mcl_fishing:flying_bobber", {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, 15, player:get_player_name())
mcl_throwing.throw("mcl_fishing:flying_bobber", {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, 15, player:get_player_name())
end
end
@ -344,10 +337,8 @@ mcl_throwing.register_throwable_object("mcl_fishing:flying_bobber", "mcl_fishing
-- If player leaves area, remove bobber.
minetest.register_on_leaveplayer(function(player)
local objs = minetest.get_objects_inside_radius(player:get_pos(), 250)
local num = 0
local ent = nil
local noent = true
for n = 1, #objs do
ent = objs[n]:get_luaentity()
if ent then

View File

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

View File

@ -180,7 +180,7 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im
if not inv_img then
inv_img = top_img
end
local usagehelp, noncreative, create_entry, paramtype2, palette
local noncreative, create_entry, paramtype2, palette
if is_flower == nil then
is_flower = true
end
@ -475,9 +475,6 @@ local fix_doubleplants = minetest.settings:get_bool("fix_doubleplants", true)
if mod_mcimport and mg_name == "singlenode" and fix_doubleplants == true then
local flowernames = { "peony", "rose_bush", "lilac", "sunflower", "double_fern", "double_grass" }
for c=1, 6 do
local flowername = flowernames[c]
end
minetest.register_lbm({
label = "Add double plant tops.",

View File

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

View File

@ -384,7 +384,6 @@ local function furnace_node_timer(pos, elapsed)
-- Update formspec and node
--
local formspec = inactive_formspec
local item_state
local item_percent = 0
if cookable then
item_percent = math.floor(src_time / cooked.time * 100)
@ -414,7 +413,7 @@ local function furnace_node_timer(pos, elapsed)
meta:set_float("fuel_time", fuel_time)
meta:set_float("src_time", src_time)
if srclist then
meta:set_string("src_item", srclist[1]:get_name())
meta:set_string("src_item", src_item)
else
meta:set_string("src_item", "")
end
@ -441,7 +440,12 @@ minetest.register_node("mcl_furnaces:furnace", {
_tt_help = S("Uses fuel to smelt or cook items"),
_doc_items_longdesc = S("Furnaces cook or smelt several items, using a furnace fuel, into something else."),
_doc_items_usagehelp =
S("Use the furnace to open the furnace menu. Place a furnace fuel in the lower slot and the source material in the upper slot. The furnace will slowly use its fuel to smelt the item. The result will be placed into the output slot at the right side.").."\n"..
S([[
Use the furnace to open the furnace menu.
Place a furnace fuel in the lower slot and the source material in the upper slot.
The furnace will slowly use its fuel to smelt the item.
The result will be placed into the output slot at the right side.
]]).."\n"..
S("Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn."),
_doc_items_hidden = false,
tiles = {

View File

@ -90,7 +90,7 @@ local function addhead(name, texture, desc, longdesc, rangemob, rangefactor)
local wdir = minetest.dir_to_wallmounted(diff)
local itemstring = itemstack:get_name()
local fakestack = ItemStack(itemstack)
--local fakestack = ItemStack(itemstack)
local idef = fakestack:get_definition()
local retval
if wdir == 0 or wdir == 1 then
@ -101,9 +101,7 @@ local function addhead(name, texture, desc, longdesc, rangemob, rangefactor)
if not retval then
return itemstack
end
local success
itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir)
itemstack,_ = minetest.item_place(fakestack, placer, pointed_thing, wdir)
itemstack:set_name(itemstring)
return itemstack
end,

View File

@ -152,7 +152,7 @@ def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing)
local z = upos.z - apos.z
local fake_itemstack = ItemStack(itemstack)
local newnode, param2
local param2
if x == -1 then
fake_itemstack:set_name("mcl_hoppers:hopper_side")
param2 = 0
@ -166,7 +166,7 @@ def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing)
fake_itemstack:set_name("mcl_hoppers:hopper_side")
param2 = 1
end
local itemstack, success = minetest.item_place_node(fake_itemstack, placer, pointed_thing, param2)
local itemstack,_ = minetest.item_place_node(fake_itemstack, placer, pointed_thing, param2)
itemstack:set_name("mcl_hoppers:hopper")
return itemstack
end
@ -411,7 +411,6 @@ minetest.register_abm({
-- Move an item from the hopper into container below
local downnode = minetest.get_node(downpos)
if not minetest.registered_nodes[downnode.name] then return end
g = minetest.registered_nodes[downnode.name].groups.container
mcl_util.move_item_container(pos, downpos)
end,
})
@ -462,7 +461,7 @@ minetest.register_abm({
-- Put fuel into fuel slot
local sinv = minetest.get_inventory({type="node", pos = pos})
local dinv = minetest.get_inventory({type="node", pos = front})
local slot_id, stack = mcl_util.get_eligible_transfer_item_slot(sinv, "main", dinv, "fuel", is_transferrable_fuel)
local slot_id,_ = mcl_util.get_eligible_transfer_item_slot(sinv, "main", dinv, "fuel", is_transferrable_fuel)
if slot_id then
mcl_util.move_item_container(pos, front, nil, slot_id, "fuel")
end

View File

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

View File

@ -20,11 +20,13 @@ local register_block = function(subname, description, tiles, is_ground_content)
is_ground_content = is_ground_content,
groups = {dig_immediate = 3, spawns_silverfish = 1, deco_block = 1},
drop = '',
is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(),
after_dig_node = spawn_silverfish,
_tt_help = S("Hides a silverfish"),
_doc_items_longdesc = S("An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart."),
_doc_items_longdesc = S([[
An infested block is a block from which a silverfish will pop out when it is broken.
It looks identical to its normal counterpart.
]]),
_mcl_hardness = 0,
_mcl_blast_resistance = 0.5,
})

View File

@ -4,7 +4,6 @@ local on_place = mcl_util.generate_on_place_plant_function(function(place_pos, p
local soil_node = minetest.get_node_or_nil({x=place_pos.x, y=place_pos.y-1, z=place_pos.z})
if not soil_node then return false end
local snn = soil_node.name -- soil node name
local sd = minetest.registered_nodes[snn] -- soil definition
-- Placement rules:
-- * Always allowed on podzol or mycelimu

View File

@ -265,7 +265,6 @@ minetest.register_abm({
if minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name ~= "mcl_core:water_source" then
-- Find dead form (it's the same as the node's drop)
local def = minetest.registered_nodes[node.name]
local dead
if def then
node.name = def.drop
else

View File

@ -37,14 +37,9 @@ local mt_record_protection_violation = minetest.record_protection_violation
local mt_is_creative_enabled = minetest.is_creative_enabled
local mt_sound_play = minetest.sound_play
local math_min = math.min
local math_max = math.max
local math_ceil = math.ceil
local math_floor = math.floor
local math_random = math.random
local string_format = string.format
local table_copy = table.copy
local table_insert = table.insert
local math = math
local string = string
local table = table
-- DEBUG: functions
-- local log = minetest.log
@ -122,7 +117,7 @@ function kelp.is_downward_flowing(pos, node, pos_above, node_above, __is_above__
-- Function params: (pos[, node]) or (node, pos_above) or (node, node_above)
local node = node or mt_get_node(pos)
local result = (math_floor(node.param2 / 8) % 2) == 1
local result = (math.floor(node.param2 / 8) % 2) == 1
if not (result or __is_above__) then
-- If not, also check node above.
-- (this is needed due a weird quirk in the definition of "downwards flowing"
@ -182,14 +177,14 @@ end
-- Roll whether to grow kelp or not.
function kelp.roll_growth(numerator, denominator)
-- Optional params: numerator, denominator
return math_random(denominator or kelp.ROLL_GROWTH_DENOMINATOR) <= (numerator or kelp.ROLL_GROWTH_NUMERATOR)
return math.random(denominator or kelp.ROLL_GROWTH_DENOMINATOR) <= (numerator or kelp.ROLL_GROWTH_NUMERATOR)
end
-- Roll initial age for kelp.
function kelp.roll_init_age(min, max)
-- Optional params
return math_random(min or kelp.MIN_AGE, (max or kelp.MAX_AGE)-1)
return math.random(min or kelp.MIN_AGE, (max or kelp.MAX_AGE)-1)
end
@ -197,7 +192,7 @@ end
-- For the special case where the max param2 is reached, interpret that as the
-- 16th kelp stem.
function kelp.get_height(param2)
return math_floor(param2 / 16) + math_floor(param2 % 16 / 8)
return math.floor(param2 / 16) + math.floor(param2 % 16 / 8)
end
@ -232,7 +227,7 @@ end
-- Obtain next param2.
function kelp.next_param2(param2)
-- param2 max value is 255, so adding to 256 causes overflow.
return math_min(param2+16 - param2 % 16, 255);
return math.min(param2+16 - param2 % 16, 255);
end
@ -242,8 +237,8 @@ function kelp.store_meta()
for _ in pairs(kelp.age_queue_pos) do
count = count + 1
end
-- chatlog(string_format("Storing age metadata: %d in queue", #kelp.age_queue))
-- chatlog(string_format("Storing age metadata: %d valid in queue", count))
-- chatlog(string.format("Storing age metadata: %d in queue", #kelp.age_queue))
-- chatlog(string.format("Storing age metadata: %d valid in queue", count))
for i=1,#kelp.age_queue do
local pos_hash = kelp.age_queue[i]
local pos = kelp.age_queue_pos[pos_hash]
@ -265,7 +260,7 @@ function kelp.store_age(age, pos, pos_hash)
kelp.age_pool[pos_hash] = age
if not kelp.age_queue_pos[pos_hash] then
table_insert(kelp.age_queue, pos_hash)
table.insert(kelp.age_queue, pos_hash)
kelp.age_queue_pos[pos_hash] = pos
return true, pos_hash
end
@ -713,7 +708,7 @@ function kelp.register_kelp_surface(surface, surface_deftemplate, surface_docs)
doc.add_entry_alias("nodes", surface_docs.entry_id_orig, "nodes", surfacename)
end
local sounds = table_copy(def.sounds)
local sounds = table.copy(def.sounds)
sounds.dig = kelp.leaf_sounds.dig
sounds.dug = kelp.leaf_sounds.dug
sounds.place = kelp.leaf_sounds.place
@ -732,9 +727,9 @@ end
-- Kelp surfaces nodes ---------------------------------------------------------
-- Dirt must be registered first, for the docs
kelp.register_kelp_surface(kelp.surfaces[1], table_copy(kelp.surface_deftemplate), kelp.surface_docs)
kelp.register_kelp_surface(kelp.surfaces[1], table.copy(kelp.surface_deftemplate), kelp.surface_docs)
for i=2, #kelp.surfaces do
kelp.register_kelp_surface(kelp.surfaces[i], table_copy(kelp.surface_deftemplate), kelp.surface_docs)
kelp.register_kelp_surface(kelp.surfaces[i], table.copy(kelp.surface_deftemplate), kelp.surface_docs)
end
-- Kelp item -------------------------------------------------------------------

View File

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

View File

@ -1,10 +1,8 @@
mcl_throwing = {}
local S = minetest.get_translator("mcl_throwing")
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
local modpath = minetest.get_modpath(minetest.get_current_modname())
--
--
-- Snowballs and other throwable items
--
@ -42,7 +40,7 @@ function mcl_throwing.get_player_throw_function(entity_name, velocity)
local func = function(item, player, pointed_thing)
local playerpos = player:get_pos()
local dir = player:get_look_dir()
local obj = mcl_throwing.throw(item, {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, velocity, player:get_player_name())
mcl_throwing.throw(item, {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, velocity, player:get_player_name())
if not minetest.is_creative_enabled(player:get_player_name()) then
item:take_item()
end

View File

@ -1,8 +1,6 @@
local S = minetest.get_translator("mcl_tnt")
local tnt_griefing = minetest.settings:get_bool("mcl_tnt_griefing", true)
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
local function spawn_tnt(pos, entname)
minetest.sound_play("tnt_ignite", {pos = pos,gain = 1.0,max_hear_distance = 15,}, true)
local tnt = minetest.add_entity(pos, entname)

View File

@ -233,7 +233,7 @@ if minetest.get_modpath("mcl_farming") then
local wear = mcl_autogroup.get_wear(toolname, "shearsy")
itemstack:add_wear(wear)
end
minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true)
minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = pointed_thing.above}, true)
local dir = vector.subtract(pointed_thing.under, pointed_thing.above)
local param2 = minetest.dir_to_facedir(dir)
minetest.swap_node(pointed_thing.under, {name="mcl_farming:pumpkin_face", param2 = param2})

View File

@ -1,3 +1,14 @@
local smoke_pdef = {
amount = 0.5,
maxexptime = 2.0,
minvel = { x = 0.0, y = 0.5, z = 0.0 },
maxvel = { x = 0.0, y = 0.6, z = 0.0 },
minsize = 1.5,
maxsize = 1.5,
minrelpos = { x = -1/16, y = 0.04, z = -1/16 },
maxrelpos = { x = 1/16, y = 0.06, z = 1/16 },
}
local spawn_flames_floor = function(pos)
-- Flames
mcl_particles.add_node_particlespawner(pos, {
@ -15,52 +26,39 @@ local spawn_flames_floor = function(pos)
glow = minetest.registered_nodes[minetest.get_node(pos).name].light_source,
}, "low")
-- Smoke
mcl_particles.add_node_particlespawner(pos, {
amount = 0.5,
time = 0,
minpos = vector.add(pos, { x = -1/16, y = 0.04, z = -1/16 }),
maxpos = vector.add(pos, { x = -1/16, y = 0.06, z = -1/16 }),
minvel = { x = 0, y = 0.5, z = 0 },
maxvel = { x = 0, y = 0.6, z = 0 },
minexptime = 2.0,
maxexptime = 2.0,
minsize = 1.5,
maxsize = 1.5,
texture = "mcl_particles_smoke_anim.png",
animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
length = 2.05,
},
}, "medium")
mcl_particles.spawn_smoke(pos, "torch", smoke_pdef)
end
local spawn_flames_wall = function(pos)
local minrelpos, maxrelpos
local node = minetest.get_node(pos)
local dir = minetest.wallmounted_to_dir(node.param2)
local smoke_pdef = table.copy(smoke_pdef)
if dir.x < 0 then
minrelpos = { x = -0.38, y = 0.04, z = -0.1 }
maxrelpos = { x = -0.2, y = 0.14, z = 0.1 }
smoke_pdef.minrelpos = { x = -0.38, y = 0.04, z = -0.1 }
smoke_pdef.maxrelpos = { x = -0.2, y = 0.14, z = 0.1 }
elseif dir.x > 0 then
minrelpos = { x = 0.2, y = 0.04, z = -0.1 }
maxrelpos = { x = 0.38, y = 0.14, z = 0.1 }
smoke_pdef.minrelpos = { x = 0.2, y = 0.04, z = -0.1 }
smoke_pdef.maxrelpos = { x = 0.38, y = 0.14, z = 0.1 }
elseif dir.z < 0 then
minrelpos = { x = -0.1, y = 0.04, z = -0.38 }
maxrelpos = { x = 0.1, y = 0.14, z = -0.2 }
smoke_pdef.minrelpos = { x = -0.1, y = 0.04, z = -0.38 }
smoke_pdef.maxrelpos = { x = 0.1, y = 0.14, z = -0.2 }
elseif dir.z > 0 then
minrelpos = { x = -0.1, y = 0.04, z = 0.2 }
maxrelpos = { x = 0.1, y = 0.14, z = 0.38 }
smoke_pdef.minrelpos = { x = -0.1, y = 0.04, z = 0.2 }
smoke_pdef.maxrelpos = { x = 0.1, y = 0.14, z = 0.38 }
else
return
end
-- Flames
mcl_particles.add_node_particlespawner(pos, {
amount = 8,
time = 0,
minpos = vector.add(pos, minrelpos),
maxpos = vector.add(pos, maxrelpos),
minpos = vector.add(pos, smoke_pdef.minrelpos),
maxpos = vector.add(pos, smoke_pdef.maxrelpos),
minvel = { x = -0.01, y = 0, z = -0.01 },
maxvel = { x = 0.01, y = 0.1, z = 0.01 },
minexptime = 0.3,
@ -71,25 +69,7 @@ local spawn_flames_wall = function(pos)
glow = minetest.registered_nodes[node.name].light_source,
}, "low")
-- Smoke
mcl_particles.add_node_particlespawner(pos, {
amount = 0.5,
time = 0,
minpos = vector.add(pos, minrelpos),
maxpos = vector.add(pos, maxrelpos),
minvel = { x = 0, y = 0.5, z = 0 },
maxvel = { x = 0, y = 0.6, z = 0 },
minexptime = 2.0,
maxexptime = 2.0,
minsize = 1.5,
maxsize = 1.5,
texture = "mcl_particles_smoke_anim.png",
animation = {
type = "vertical_frames",
aspect_w = 8,
aspect_h = 8,
length = 2.05,
},
}, "medium")
mcl_particles.spawn_smoke(pos, "torch", smoke_pdef)
end
local remove_flames = function(pos)
@ -277,7 +257,7 @@ minetest.register_lbm({
nodenames = {"group:torch_particles"},
run_at_every_load = true,
action = function(pos, node)
local torch_group = minetest.get_node_group(node.name, "torch")
local torch_group = minetest.get_item_group(node.name, "torch")
if torch_group == 1 then
spawn_flames_floor(pos)
elseif torch_group == 2 then

View File

@ -151,7 +151,7 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory
minetest.register_node(nodename.."_"..i, {
collision_box = {
type = 'fixed',
type = 'fixed',
fixed = {-4/16, -0.5, -4/16, 4/16, 1, 4/16}
},
drawtype = "nodebox",
@ -180,7 +180,7 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory
minetest.register_node(nodename.."_16", {
drawtype = "nodebox",
collision_box = {
type = 'fixed',
type = 'fixed',
fixed = {-4/16, -0.5, -4/16, 4/16, 1, 4/16}
},
tiles = tiles,
@ -206,7 +206,7 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory
minetest.register_node(nodename.."_21", {
drawtype = "nodebox",
collision_box = {
type = 'fixed',
type = 'fixed',
fixed = {-4/16, -0.5, -4/16, 4/16, 1, 4/16}
},
tiles = tiles,
@ -247,7 +247,7 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory
fixed = pillar
},
collision_box = {
type = 'fixed',
type = 'fixed',
fixed = {-4/16, -0.5, -4/16, 4/16, 1, 4/16}
},
collisionbox = {-0.2, 0, -0.2, 0.2, 1.4, 0.2},

View File

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

View File

@ -157,7 +157,6 @@ screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses)
if should_rotate and new_param2 ~= node.param2 then
node.param2 = new_param2
minetest.swap_node(pos, node)
minetest.check_for_falling(pos)
if ndef.after_rotate then
ndef.after_rotate(vector.new(pos))

View File

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

View File

@ -142,7 +142,7 @@ function xpanes.register_pane(name, def)
tiles = {def.textures[3], def.textures[2], def.textures[1]},
use_texture_alpha = def.use_texture_alpha,
groups = groups,
drop = "xpanes:" .. name .. "_flat",
drop = drop,
sounds = def.sounds,
node_box = {
type = "connected",
@ -153,7 +153,6 @@ function xpanes.register_pane(name, def)
connect_right = {{1/32, -1/2, -1/32, 1/2, 1/2, 1/32}},
},
connects_to = {"group:pane", "group:stone", "group:glass", "group:wood", "group:tree"},
drop = drop,
_mcl_blast_resistance = def._mcl_blast_resistance,
_mcl_hardness = def._mcl_hardness,
_mcl_silk_touch_drop = def._mcl_silk_touch_drop and {"xpanes:" .. name .. "_flat"},

View File

@ -3906,7 +3906,7 @@ end
-- Decorations in non-Overworld dimensions
local function register_dimension_decorations()
--[[ NETHER ]]
-- TODO: Nether
-- TODO: Nether
--[[ THE END ]]
@ -3973,7 +3973,7 @@ if mg_name ~= "singlenode" then
if deco_id_chorus_plant then
mcl_mapgen_core.register_generator("chorus_grow", nil, function(minp, maxp, blockseed)
local gennotify = minetest.get_mapgen_object("gennotify")
local poslist = {}
--local poslist = {}
for _, pos in ipairs(gennotify["decoration#"..deco_id_chorus_plant] or {}) do
local realpos = { x = pos.x, y = pos.y + 1, z = pos.z }
mcl_end.grow_chorus_plant(realpos)

View File

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

View File

@ -9,15 +9,15 @@ function settlements.ground(pos, pr) -- role model: Wendelsteinkircherl, Brannen
while true do
cnt = cnt+1
if cnt > 20 then break end
if cnt>pr:next(2,4) then
mat = "mcl_core:stone"
if cnt>pr:next(2,4) then
mat = "mcl_core:stone"
end
minetest.swap_node(p2, {name=mat})
p2.y = p2.y-1
end
end
-------------------------------------------------------------------------------
-- function clear space above baseplate
-- function clear space above baseplate
-------------------------------------------------------------------------------
function settlements.terraform(settlement_info, pr)
local fheight, fwidth, fdepth, schematic_data
@ -30,7 +30,7 @@ function settlements.terraform(settlement_info, pr)
break
end
end
local pos = settlement_info[i]["pos"]
local pos = settlement_info[i]["pos"]
if settlement_info[i]["rotat"] == "0" or settlement_info[i]["rotat"] == "180" then
fwidth = schematic_data["hwidth"]
fdepth = schematic_data["hdepth"]
@ -54,9 +54,9 @@ function settlements.terraform(settlement_info, pr)
-- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi}
-- local node = mcl_vars.get_node(p)
-- if node and node.name ~= "air" then
-- minetest.swap_node(p,{name="air"})
-- minetest.swap_node(p,{name="air"})
-- end
minetest.swap_node({x=pos.x+xi, y=pos.y+yi, z=pos.z+zi},{name="air"})
minetest.swap_node({x=pos.x+xi, y=pos.y+yi, z=pos.z+zi},{name="air"})
end
end
end

View File

@ -46,7 +46,7 @@ if minetest.get_modpath("mobs_mc") ~= nil then
7, --active_object_count
31000, --max_height
nil) --day_toggle
end
end
--]]
--
@ -85,7 +85,7 @@ if mg_name ~= "singlenode" then
if blockseed % 77 ~= 17 then return end
-- needed for manual and automated settlement building
-- don't build settlements on (too) uneven terrain
local heightmap = minetest.get_mapgen_object("heightmap")
--local heightmap = minetest.get_mapgen_object("heightmap")
local height_difference = settlements.evaluate_heightmap()
if height_difference > max_height_difference then return end

View File

@ -6,10 +6,10 @@ function settlements.paths(settlement_info)
local end_point
local distance
--for k,v in pairs(settlement_info) do
starting_point = settlement_info[1]["pos"]
starting_point = settlement_info[1]["pos"]
for o,p in pairs(settlement_info) do
end_point = settlement_info[o]["pos"]
end_point = settlement_info[o]["pos"]
if starting_point ~= end_point
then
-- loop until end_point is reched (distance == 0)
@ -40,35 +40,35 @@ function settlements.paths(settlement_info)
-- evaluate which pos is closer to the end_point
if dist_north_p_to_end <= dist_south_p_to_end and
dist_north_p_to_end <= dist_west_p_to_end and
dist_north_p_to_end <= dist_east_p_to_end
dist_north_p_to_end <= dist_east_p_to_end
then
starting_point = north_p
distance = dist_north_p_to_end
elseif dist_south_p_to_end <= dist_north_p_to_end and
dist_south_p_to_end <= dist_west_p_to_end and
dist_south_p_to_end <= dist_east_p_to_end
dist_south_p_to_end <= dist_east_p_to_end
then
starting_point = south_p
distance = dist_south_p_to_end
elseif dist_west_p_to_end <= dist_north_p_to_end and
dist_west_p_to_end <= dist_south_p_to_end and
dist_west_p_to_end <= dist_east_p_to_end
dist_west_p_to_end <= dist_east_p_to_end
then
starting_point = west_p
distance = dist_west_p_to_end
elseif dist_east_p_to_end <= dist_north_p_to_end and
dist_east_p_to_end <= dist_south_p_to_end and
dist_east_p_to_end <= dist_west_p_to_end
dist_east_p_to_end <= dist_west_p_to_end
then
starting_point = east_p
distance = dist_east_p_to_end
end
-- find surface of new starting point
local surface_point, surface_mat = settlements.find_surface(starting_point)
-- replace surface node with mcl_core:grass_path
-- replace surface node with mcl_core:grass_path
if surface_point
then
if surface_mat == "mcl_core:sand" or surface_mat == "mcl_core:redsand" then

View File

@ -126,7 +126,7 @@ function settlements.fill_chest(pos, pr)
-- fill chest
local inv = minetest.get_inventory( {type="node", pos=pos} )
local function get_treasures(pr)
local function get_treasures(prand)
local loottable = {{
stacks_min = 3,
stacks_max = 8,
@ -150,7 +150,7 @@ function settlements.fill_chest(pos, pr)
{ itemstring = "mobs_mc:diamond_horse_armor", weight = 1 },
}
}}
local items = mcl_loot.get_multi_loot(loottable, pr)
local items = mcl_loot.get_multi_loot(loottable, prand)
return items
end
@ -163,14 +163,14 @@ end
-------------------------------------------------------------------------------
function settlements.initialize_furnace(pos)
-- find chests within radius
local furnacepos = minetest.find_node_near(pos,
local furnacepos = minetest.find_node_near(pos,
7, --radius
{"mcl_furnaces:furnace"})
-- initialize furnacepos (mts furnacepos don't have meta)
if furnacepos
if furnacepos
then
local meta = minetest.get_meta(furnacepos)
if meta:get_string("infotext") ~= "furnace"
if meta:get_string("infotext") ~= "furnace"
then
minetest.registered_nodes["mcl_furnaces:furnace"].on_construct(furnacepos)
end
@ -181,14 +181,14 @@ end
-------------------------------------------------------------------------------
function settlements.initialize_anvil(pos)
-- find chests within radius
local anvilpos = minetest.find_node_near(pos,
local anvilpos = minetest.find_node_near(pos,
7, --radius
{"mcl_anvils:anvil"})
-- initialize anvilpos (mts anvilpos don't have meta)
if anvilpos
if anvilpos
then
local meta = minetest.get_meta(anvilpos)
if meta:get_string("infotext") ~= "anvil"
if meta:get_string("infotext") ~= "anvil"
then
minetest.registered_nodes["mcl_anvils:anvil"].on_construct(anvilpos)
end

View File

@ -1,7 +1,3 @@
local S = minetest.get_translator("mcl_commands")
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
local modpath = minetest.get_modpath(minetest.get_current_modname())
dofile(modpath.."/kill.lua")

View File

@ -6,7 +6,7 @@ minetest.register_chatcommand("setblock", {
privs = {give=true, interact=true},
func = function(name, param)
local p = {}
local nodestring = nil
local nodestring
p.x, p.y, p.z, nodestring = param:match("^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) +(.+)$")
p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z)
if p.x and p.y and p.z and nodestring then

View File

@ -4,39 +4,34 @@ minetest.register_chatcommand("playsound",{
params = S("<sound> <target>"), --TODO:add source
description = S("Play a sound. Arguments: <sound>: name of the sound. <target>: Target."),
privs = {server = true},
func = function(name, params)
func = function(name, rawparams)
local P = {}
local i = 0
for str in string.gmatch(params, "([^ ]+)") do
for str in string.gmatch(rawparams, "([^ ]+)") do
i = i + 1
P[i] = str
end
local params = {}
if P[1] == tostring(P[1]) then
params.name = P[1]
else
return false, S("Sound name is invalid!") --TODO: add mc chat message
end
if P[2] == tostring(P[2]) and minetest.player_exists(P[2]) then
params.target = P[2]
else
return false, S("Target is invalid!!")
end
-- if P[3] then
-- params.pos = nil --TODO:position
-- else
-- params.pos = nil
-- end
-- if P[4] == tonumber(P[4]) then
-- params.gain = P[4]
-- else
-- params.gain = 1.0
-- end
-- if P[5] == tonumber(P[5]) then
-- params.pitch = P[5]
-- else

View File

@ -27,7 +27,12 @@ minetest.register_craft({
minetest.register_craft({
type = "shapeless",
output = "mcl_ocean:prismarine_crystals",
recipe = { "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_core:gold_ingot" },
recipe = {
"mcl_ocean:prismarine_shard",
"mcl_ocean:prismarine_shard",
"mcl_ocean:prismarine_shard",
"mcl_core:gold_ingot",
},
})
minetest.register_craft({

View File

@ -20,7 +20,7 @@ minetest.register_on_dieplayer(function(player)
local playerinv = player:get_inventory()
local pos = player:get_pos()
-- No item drop if in deep void
local void, void_deadly = mcl_worlds.is_in_void(pos)
local _, void_deadly = mcl_worlds.is_in_void(pos)
for l=1,#mcl_death_drop.registered_dropped_lists do
local inv = mcl_death_drop.registered_dropped_lists[l].inv

View File

@ -86,7 +86,8 @@ if mcl_hunger.active then
function mcl_hunger.saturate(playername, increase, update_hudbar)
local player = minetest.get_player_by_name(playername)
local ok = mcl_hunger.set_saturation(player, math.min(mcl_hunger.get_saturation(player) + increase, mcl_hunger.get_hunger(player)))
local ok = mcl_hunger.set_saturation(player,
math.min(mcl_hunger.get_saturation(player) + increase, mcl_hunger.get_hunger(player)))
if update_hudbar ~= false then
mcl_hunger.update_saturation_hud(player, mcl_hunger.get_saturation(player), mcl_hunger.get_hunger(player))
end
@ -105,7 +106,7 @@ if mcl_hunger.active then
-- otherwise the following poison/exhaust fields are ignored
food[name].poison = poison -- poison damage per tick for poisonous food
food[name].exhaust = exhaust -- exhaustion per tick for poisonous food
food[name].poisonchance = poisonchance -- chance percentage that this item poisons the player (default: 100% if poisoning is enabled)
food[name].poisonchance = poisonchance -- chance percentage that this item poisons the player (default: 100%)
food[name].sound = sound -- special sound that is played when eating
end

View File

@ -2,7 +2,6 @@ local S = minetest.get_translator("mcl_hunger")
local mod_death_messages = minetest.get_modpath("mcl_death_messages")
-- wrapper for minetest.item_eat (this way we make sure other mods can't break this one)
local org_eat = minetest.do_item_eat
minetest.do_item_eat = function(hp_change, replace_with_item, itemstack, user, pointed_thing)
if not user or user:is_player() == false then
@ -38,7 +37,8 @@ minetest.do_item_eat = function(hp_change, replace_with_item, itemstack, user, p
-- FIXME: In singleplayer, there's a cheat to circumvent this, simply by pausing the game between eats.
-- This is because os.time() obviously does not care about the pause. A fix needs a different timer mechanism.
if no_eat_delay or (mcl_hunger.last_eat[name] < 0) or (os.difftime(os.time(), mcl_hunger.last_eat[name]) >= 2) then
local can_eat_when_full = creative or (mcl_hunger.active == false) or minetest.get_item_group(itemstack:get_name(), "can_eat_when_full") == 1
local can_eat_when_full = creative or (mcl_hunger.active == false)
or minetest.get_item_group(itemstack:get_name(), "can_eat_when_full") == 1
-- Don't allow eating when player has full hunger bar (some exceptional items apply)
if can_eat_when_full or (mcl_hunger.get_hunger(user) < 20) then
itemstack = mcl_hunger.eat(hp_change, replace_with_item, itemstack, user, pointed_thing)
@ -67,7 +67,8 @@ function mcl_hunger.eat(hp_change, replace_with_item, itemstack, user, pointed_t
def.saturation = hp_change
def.replace = replace_with_item
end
local func = mcl_hunger.item_eat(def.saturation, def.replace, def.poisontime, def.poison, def.exhaust, def.poisonchance, def.sound)
local func = mcl_hunger.item_eat(def.saturation, def.replace, def.poisontime,
def.poison, def.exhaust, def.poisonchance, def.sound)
return func(itemstack, user, pointed_thing)
end
@ -90,7 +91,6 @@ local function poisonp(tick, time, time_left, damage, exhaustion, name)
if not player then
return
end
local name = player:get_player_name()
-- Abort if food poisonings have been stopped
if mcl_hunger.poison_hunger[name] == 0 then
return
@ -131,7 +131,7 @@ function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poiso
itemstack:take_item()
end
local name = user:get_player_name()
local hp = user:get_hp()
--local hp = user:get_hp()
local pos = user:get_pos()
-- player height

View File

@ -65,9 +65,7 @@ end
-- Count number of poisonings a player has at once
mcl_hunger.poison_hunger = {} -- food poisoning, increasing hunger
-- HUD item ids
local hunger_hud = {}
-- HUD
local function init_hud(player)
hb.init_hudbar(player, "hunger", mcl_hunger.get_hunger(player))
if mcl_hunger.debug then

View File

@ -63,7 +63,6 @@ end
if has_mcl_skins == true then
--change the player's hand to their skin
mcl_skins.register_on_set_skin(function(player, skin)
local name = player:get_player_name()
local meta = mcl_skins.meta[skin]
if meta.gender == "female" then
player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin.."_female")

View File

@ -9,7 +9,7 @@ local animation_blend = 0
local function get_mouse_button(player)
local controls = player:get_player_control()
local get_wielded_item_name = player:get_wielded_item():get_name()
if controls.RMB and not string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") or controls.LMB then
if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") or controls.LMB then
return true
else
return false
@ -110,7 +110,7 @@ function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname)
local name = player:get_player_name()
local model = player_model[name]
local anim = models[model].animations[player_anim[name]]
return "model[" .. x .. "," .. y .. ";" .. w .. "," .. h .. ";" .. fsname .. ";" .. model .. ";" .. table.concat(player_textures[name], ",") .. ";0," .. 180 .. ";false;false;" .. anim.x .. "," .. anim.y .. "]"
return "model["..x..","..y..";"..w..","..h..";"..fsname..";"..model..";"..table.concat(player_textures[name], ",")..";0,".. 180 ..";false;false;"..anim.x..","..anim.y.."]"
end
function mcl_player.player_set_animation(player, anim_name, speed)
@ -179,7 +179,10 @@ minetest.register_globalstep(function(dtime)
-- Apply animations based on what the player is doing
if player:get_hp() == 0 then
player_set_animation(player, "die")
elseif walking and velocity.x > 0.35 or walking and velocity.x < -0.35 or walking and velocity.z > 0.35 or walking and velocity.z < -0.35 then
elseif walking and velocity.x > 0.35
or walking and velocity.x < -0.35
or walking and velocity.z > 0.35
or walking and velocity.z < -0.35 then
if player_sneak[name] ~= controls.sneak then
player_anim[name] = nil
player_sneak[name] = controls.sneak

View File

@ -1,6 +1,6 @@
local S = minetest.get_translator("mcl_playerplus")
local elytra = {}
elytra = {}
local node_stand_return = ":air"
local get_connected_players = minetest.get_connected_players
@ -24,11 +24,12 @@ local mcl_playerplus_internal = {}
local def = {}
local time = 0
local look_pitch = 0
local player_collision = function(player)
local pos = player:get_pos()
local vel = player:get_velocity()
--local vel = player:get_velocity()
local x = 0
local z = 0
local width = .75
@ -57,18 +58,8 @@ local function degrees(rad)
return rad * 180.0 / math.pi
end
local pi = math.pi
local atann = math.atan
local atan = function(x)
if not x or x ~= x then
return 0
else
return atann(x)
end
end
local dir_to_pitch = function(dir)
local dir2 = vector.normalize(dir)
--local dir2 = vector.normalize(dir)
local xz = math.abs(dir.x) + math.abs(dir.z)
return -math.atan2(-dir.y, xz)
end
@ -120,7 +111,7 @@ function limit_vel_yaw(player_vel_yaw, yaw)
return player_vel_yaw
end
local pitch, name, node_stand, node_stand_below, node_head, node_feet, pos
local node_stand, node_stand_below, node_head, node_feet
minetest.register_on_punchplayer(function(player, hitter, damage)
@ -175,14 +166,14 @@ minetest.register_globalstep(function(dtime)
]]--
local controls = player:get_player_control()
local control = player:get_player_control()
local name = player:get_player_name()
local meta = player:get_meta()
--local meta = player:get_meta()
local parent = player:get_attach()
local wielded = player:get_wielded_item()
local player_velocity = player:get_velocity() or player:get_player_velocity()
-- controls head bone
-- control head bone
local pitch = - degrees(player:get_look_vertical())
local yaw = degrees(player:get_look_horizontal())
@ -194,16 +185,44 @@ minetest.register_globalstep(function(dtime)
player_vel_yaws[name] = player_vel_yaw
if minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}) then
node_stand_return = minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}).name
node_stand_return = minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.1, z=player:get_pos().z}).name
else
minetest.log("action", "somehow player got of loaded areas")
end
local chestplate = player:get_inventory():get_stack("armor", 3)
if player_rocketing[player] and player_rocketing[player] == true and chestplate:get_name() == "mcl_armor:elytra" then
if math.abs(player_velocity.x) + math.abs(player_velocity.y) + math.abs(player_velocity.z) < 40 then
player:add_player_velocity(vector.multiply(player:get_look_dir(), 4))
elytra[player] = true
end
end
controls.register_on_press(function(player, key)
if key~="jump" and key~="RMB" then return end
if key=="jump" then
if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" and player_velocity.y < -6 and elytra[player] ~= true then
elytra[player] = true
elseif key=="RMB" then
if wielded:get_name() == "mcl_tools:rocket" then
wielded:take_item()
player:set_wielded_item(wielded)
end
end
end
end)
if elytra[player] == true and node_stand_return ~= "air" or elytra[player] == true and player:get_inventory():get_stack("armor", 3):get_name() ~= "mcl_armor:elytra" or player:get_attach() ~= nil then
elytra[player] = false
end
--[[
if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" and player_velocity.y < -6 and elytra[player] ~= true and is_sprinting(name) then
elytra[player] = true
elseif elytra[player] == true and node_stand_return ~= "air" or elytra[player] == true and player:get_inventory():get_stack("armor", 3):get_name() ~= "mcl_armor:elytra" or player:get_attach() ~= nil then
elytra[player] = false
end
end]]
if elytra[player] == true then
mcl_player.player_set_animation(player, "fly")
@ -213,23 +232,23 @@ minetest.register_globalstep(function(dtime)
end
if math.abs(player_velocity.x) + math.abs(player_velocity.z) < 20 then
local dir = minetest.yaw_to_dir(player:get_look_horizontal())
player:add_velocity({x=dir.x, y=0, z=dir.z})
end
if controls.sneak then
if player_velocity.y > -5 then
player:add_velocity({x=0, y=-2, z=0})
if degrees(player:get_look_vertical()) * -.01 < .1 then
look_pitch = degrees(player:get_look_vertical()) * -.01
else
look_pitch = .1
end
player:add_velocity({x=dir.x, y=look_pitch, z=dir.z})
end
else
playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra")
end
-- controls right and left arms pitch when shooting a bow
if string.find(wielded:get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then
if string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB and not control.LMB and not control.up and not control.down and not control.left and not control.right then
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35))
-- when punching
elseif controls.LMB and not parent then
elseif control.LMB and not parent then
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0))
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(0,0,0))
-- when holding an item.
@ -246,15 +265,15 @@ minetest.register_globalstep(function(dtime)
-- set head pitch and yaw when swimming
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0))
-- sets eye height, and nametag color accordingly
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
-- control body bone when swimming
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0))
elseif parent then
local parent_yaw = degrees(parent:get_yaw())
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0))
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0,0,0))
elseif controls.sneak then
elseif control.sneak then
-- controls head pitch when sneaking
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0))
-- sets eye height, and nametag color accordingly
@ -265,12 +284,12 @@ minetest.register_globalstep(function(dtime)
-- set head pitch and yaw when swimming
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90-degrees(dir_to_pitch(player_velocity)),player_vel_yaw - yaw,0))
-- sets eye height, and nametag color accordingly
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,0.8,0.312}, eye_height = 0.5, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
-- control body bone when swimming
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(degrees(dir_to_pitch(player_velocity)) - 90,-player_vel_yaw + yaw + 180,0))
else
-- sets eye height, and nametag color accordingly
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 225, g = 225 }})
player:set_properties({collisionbox = {-0.312,0,-0.312,0.312,1.8,0.312}, eye_height = 1.5, nametag_color = { r = 225, b = 225, a = 0, g = 225 }})
player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch, player_vel_yaw - yaw, 0))
player:set_bone_position("Body_Control", vector.new(0,6.3,0), vector.new(0, -player_vel_yaw + yaw, 0))
@ -283,9 +302,9 @@ minetest.register_globalstep(function(dtime)
mcl_playerplus_internal[name].jump_cooldown = mcl_playerplus_internal[name].jump_cooldown - dtime
end
if controls.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then
if control.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then
pos = player:get_pos()
--pos = player:get_pos()
node_stand = mcl_playerinfo[name].node_stand
node_stand_below = mcl_playerinfo[name].node_stand_below

View File

@ -198,7 +198,6 @@ minetest.register_chatcommand("setskin", {
end
end
local skin
local ok = mcl_skins.set_player_skin(player, skin_id)
if not ok then
return false, S("Invalid skin number! Valid numbers: 0 to @1", mcl_skins.skin_count)

View File

@ -1,45 +0,0 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

View File

@ -53,7 +53,10 @@ local function setSprinting(playerName, sprinting) --Sets the state of a player
local controls = player:get_player_control()
if players[playerName] then
players[playerName].sprinting = sprinting
if sprinting == true or controls.RMB and string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") and player:get_wielded_item():get_name() ~= "mcl_bows:bow" then
if sprinting == true
or controls.RMB
and string.find(player:get_wielded_item():get_name(), "mcl_bows:bow")
and player:get_wielded_item():get_name() ~= "mcl_bows:bow" then
if sprinting == true then
players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2)
players[playerName].fade_time = .15
@ -65,7 +68,10 @@ local function setSprinting(playerName, sprinting) --Sets the state of a player
if sprinting == true then
playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED)
end
elseif sprinting == false and player:get_wielded_item():get_name() ~= "mcl_bows:bow_0" and player:get_wielded_item():get_name() ~= "mcl_bows:bow_1" and player:get_wielded_item():get_name() ~= "mcl_bows:bow_2" then
elseif sprinting == false
and player:get_wielded_item():get_name() ~= "mcl_bows:bow_0"
and player:get_wielded_item():get_name() ~= "mcl_bows:bow_1"
and player:get_wielded_item():get_name() ~= "mcl_bows:bow_2" then
players[playerName].fov = math.max(players[playerName].fov - 0.05, 1.0)
player:set_fov(players[playerName].fov, true, 0.15)
if sprinting == false then
@ -186,7 +192,8 @@ minetest.register_globalstep(function(dtime)
if players[playerName]["shouldSprint"] == true then --Stopped
local sprinting
-- Prevent sprinting if hungry or sleeping
if (mcl_hunger.active and mcl_hunger.get_hunger(player) <= 6) or (player:get_meta():get_string("mcl_beds:sleeping") == "true") then
if (mcl_hunger.active and mcl_hunger.get_hunger(player) <= 6)
or (player:get_meta():get_string("mcl_beds:sleeping") == "true") then
sprinting = false
cancelClientSprinting(playerName)
else

View File

@ -1,4 +1,3 @@
local time = 0
local update_time = tonumber(minetest.settings:get("wieldview_update_time"))
if not update_time then
update_time = 2
@ -69,14 +68,14 @@ end
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
wieldview.wielded_item[name] = ""
minetest.after(0, function(player)
minetest.after(0, function(target)
-- if the player left :is_player() will return nil
if not player:is_player() then
if not target:is_player() then
return
end
wieldview:update_wielded_item(player)
local itementity = minetest.add_entity(player:get_pos(), "wieldview:wieldnode")
itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45))
wieldview:update_wielded_item(target)
local itementity = minetest.add_entity(target:get_pos(), "wieldview:wieldnode")
itementity:set_attach(target, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45))
itementity:get_luaentity().wielder = name
end, player)
end)

0
tools/create_luacheck.py Normal file
View File