Compare commits

..

161 Commits

Author SHA1 Message Date
marro 4e22b811d1 Deleted extra space 2024-11-11 02:32:40 +01:00
the-real-herowl 32b334322b Merge pull request 'Mobile fixes & improvements (cherry-pick from Mineclonia)' (#4685) from grorp/MineClone2:vl-mobile-fixes-and-improvements into master
Reviewed-on: VoxeLibre/VoxeLibre#4685
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-11-11 01:44:27 +01:00
grorp 88c3c4558b Fix for VoxeLibre 2024-11-10 15:14:56 +01:00
grorp 3954acdfb7 Creative inventory: padding[-0.015,-0.015] on mobile
- less wasted screen space
- matches old layout
2024-11-10 15:14:56 +01:00
grorp 02b354f54a Avoid tab buttons going off-screen with high scaling values 2024-11-10 15:14:56 +01:00
grorp cb624fe1d9 Creative inventory: Make the whole tab button clickable
Previously, only the tab icon was clickable. Clicking next to the icon would
just close the inventory.
The icon is still kept clickable too since that gives a nicer press animation.
I didn't end up using image_button because that resulted in a different image
size and position, even with the exact same coordinates.
2024-11-10 15:14:56 +01:00
grorp bd9ab16762 Add touch_interaction to (cross)bow and spyglass 2024-11-10 15:14:56 +01:00
kno10 fb3c85e289 Improve stalker textures (#4674)
- don't change back to default texture when falling, but rather keep the previous texture
- use a colorized default texture for gaps in the texture

Reviewed-on: VoxeLibre/VoxeLibre#4674
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-11-10 12:02:20 +01:00
kno10 f6f5481f30 Attempt to fix chest minecarts, at least for 5.9 (#4684)
Not using the `RecheckCartHack` on >5.9 seems to help with #4670 - not tested on older minetest; chest minecarts might still be empty there when the block is unloaded in the meantime. For <5.9, maybe it helps to decrease the time interval, 3 seconds seems to fairly long.

This also makes the minecarts random: 40% minecart, 40% chest minecart, 20% tnt minecart.

Reviewed-on: VoxeLibre/VoxeLibre#4684
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-11-10 11:41:19 +01:00
the-real-herowl c428fa576b Merge pull request 'bonemeal API update' (#4221) from teknomunk/MineClone2:bonemeal-2 into master
Reviewed-on: VoxeLibre/VoxeLibre#4221
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-11-10 11:38:08 +01:00
teknomunk a46833eaa4 Fix alias 2024-11-09 20:30:35 -06:00
teknomunk 3514fe211f Implement more bonemeal mod shim, update bonemeal dependencies 2024-11-09 20:30:35 -06:00
teknomunk 94d9e4c881 Address review comments 2024-11-09 20:30:35 -06:00
teknomunk 6b1aa43238 Only show particles if bone meal is consumed, don't continue testing positions if bonemeal was used on the first check position 2024-11-09 20:30:35 -06:00
teknomunk cfdef2435a Show particles regardless of success 2024-11-09 20:30:35 -06:00
teknomunk 49c8ae2fa0 Quick patch to get cherry saplings growing pending inclusing of a proper tree API 2024-11-09 20:30:33 -06:00
teknomunk 6ada1a3477 Remove check with mcl_core.check_vines_supported for twisted and crimson vines 2024-11-09 20:24:02 -06:00
teknomunk 189a2c62ad Address review comments on mcl_util.trace_nodes 2024-11-09 20:24:02 -06:00
teknomunk 981cddddd4 Add growth limits to crimson/twisting vines 2024-11-09 20:24:02 -06:00
teknomunk 66b5a369f1 Add mcl_util.trace_node(), rewrite bamboo growth code to fix bone meal growth 2024-11-09 20:24:02 -06:00
teknomunk 4eda77acd1 Prevent bonemealing grass from making flowers and also bonemealing the block above the grass 2024-11-09 20:24:02 -06:00
teknomunk afc270195a Fix crash when bonemealing weaping and twisting vines, fix weaping vine growth 2024-11-09 20:24:02 -06:00
teknomunk 8f53074b58 Reorder functions to prevent crash 2024-11-09 20:24:02 -06:00
teknomunk 70e8ba9a89 Remove TODO pending future discussions, revert timer change in composter code 2024-11-09 20:24:02 -06:00
teknomunk 6741c5a809 Make composter_progress_chance local, as it is not used anywhere except in mcl_composters 2024-11-09 20:24:02 -06:00
teknomunk d09791db7b Fix typo that prevented bone mealing pumpkin plants 2024-11-09 20:24:02 -06:00
teknomunk 354160e9e6 Check both above and below in pointed_thing for bonemealing (and pass thru the position as .under), make crimson vines and twisting vines compostable by rightclicking on the composter 2024-11-09 20:24:02 -06:00
teknomunk cf1325d466 Fix crash at one more spot 2024-11-09 20:24:02 -06:00
teknomunk 7112369917 Fix crashes when using bonemeal on nether nodes 2024-11-09 20:24:02 -06:00
teknomunk e6e13bdc67 Change _mcl_on_bonemealing to _on_bone_meal, update API.md to reflect this 2024-11-09 20:24:02 -06:00
teknomunk 42d37210c5 Fix mods/ITEMS/mcl_composters/locale/mcl_composters.ru.tr 2024-11-09 20:24:02 -06:00
teknomunk c3a33ea2c2 Update mod authors, remove a TODO 2024-11-09 20:24:02 -06:00
teknomunk 7f6d456a32 Remove bone to bone meal recipe from mcl_dye as it now resides in mcl_bone_meal 2024-11-09 20:24:02 -06:00
teknomunk 44d154f594 Modify backtrace listing to use minetest.log 2024-11-09 20:24:02 -06:00
teknomunk eb6131b037 Fix localization errors 2024-11-09 20:24:02 -06:00
teknomunk 3c2f2593db Only consume bone meal if a _mcl_on_bonemealing callback is defined or the legacy API returns true, convert vines to use new bonemeal API 2024-11-09 20:24:02 -06:00
teknomunk 9e6d49dd38 Fix localization except mcl_composters.ru.tr 2024-11-09 20:24:02 -06:00
teknomunk 4a865fa2df Enable bamboo bonemealing despite rightclick handling strangeness 2024-11-09 20:24:02 -06:00
teknomunk 55b4d3d5ee Rename localization files 2024-11-09 20:24:02 -06:00
teknomunk 09bcf3d22b Add untested bonemeal mod compatibility shim 2024-11-09 20:24:02 -06:00
teknomunk 57678e31bc Move commented out bamboo bone meal code into mods/ITEMS/mcl_bamboo/bamboo_base.lua 2024-11-09 20:24:02 -06:00
teknomunk d5684ca305 Add new API call mcl_bone_meal.use_bone_meal and use this to remove duplicate code, update mcl_farming:sweet_berries to use bonemeal API, add stub for bonemeal mod compatibility 2024-11-09 20:24:02 -06:00
teknomunk a4f1ccd0ee Update mcl_crimson to use bonemealing API 2024-11-09 20:24:02 -06:00
teknomunk 1e0f7618ba Remove bone meal definition in mcl_dye, make textures in mcl_cocoas match master branch 2024-11-09 20:24:02 -06:00
teknomunk f44102c238 Display call stack to assist in removing deprecated function calls 2024-11-09 20:24:02 -06:00
teknomunk 5b1fcf76f6 Fix mod dependencies 2024-11-09 20:24:02 -06:00
kabou f61a7ab4cb Remove color specifications from bone meal.
* The bone meal craftitem definition still had color specifications
  from its past as a dye substitute.  These can be removed now.
* Also remove default stack_max setting.
2024-11-09 20:24:02 -06:00
kabou 4449f74742 Remove color specifications from cocoa beans.
* The cocoa beans craftitem definition still had color specifications
  from its past as a dye substitute.  These can be removed now.
2024-11-09 20:24:02 -06:00
kabou ba1e0e4301 Also generate double grass when bonemealing grass blocks. 2024-11-09 20:24:02 -06:00
kabou 7938fba4a5 Remove expired bone meal API.md from mcl_dye. 2024-11-09 20:24:02 -06:00
kabou 8acddab74f Bonemealing mechanics bugfix.
When applying bonemeal to eg. farm crops, these have a chance to grow in
response to the application of bone meal. When a node can be bonemealed, the
applied bone meal item should always be spent after using it, regardless of
the results.  Currently this does not work correctly, if the result of
bonemealing has no effect on the node, the used bone meal item is not spent.

This commit fixes the behavior of the bone meal item to always be taken when
used on a node that defines a `_mcl_on_bonemealing()` callback.

The nodes that implement the callback imay use the handler's return value
only to signal if the bonemealing was succesful, not to signal if it was at
all possible.  For this reason, some nodes need to be made more strictly
conforming to the API.

* Always take the used bone meal item (if user is not in creative mode),
  regardless of whether the bonemealed node's handler returned `true`.
* Make dispensers spawn particles after succesful bonemealing.
* Trivial comment fix.
* Ripe cocoa pod cannot be bonemealed.
* Update API.md to describe the stricter API semantics.
2024-11-09 20:24:02 -06:00
kabou c2c7df820f Improve mcl_bone_meal fr translations.
* Changed the wording after suggestions by AFCMS.
2024-11-09 20:24:02 -06:00
kabou e5cf4bd225 Add missing es translation to mcl_bone_meal. 2024-11-09 20:24:02 -06:00
kabou 810051c591 Move cocoa beans item to mcl_cocoas.
* Add `mcl_cocoas:coca_beans` craftitem to mcl_cocoas.
* Remove `mcl_dye:brown` craftitem from mcl_dye.
* Move cocoa beans translations from mcl_dye to mcl_cocoas.
* Add `mcl_dye:brown` alias for `mcl_cocoas:cocoa_beans` to
  mcl_dye.
* Abstract cocoa pod node registration into a loop.
* Update chocolate cookies crafting recipe in mcl_farming.
2024-11-09 20:24:02 -06:00
kabou ae56a864d0 Remove stray line from locale template.
* Removed a line from the mcl_bone_meal locale template that had by
  accident put there during the bone meal <-> white dye changes.
2024-11-09 20:24:02 -06:00
kabou 7ddcf3f93f Use better override mechanism.
* Use `minetest.override_item()` instead of re-registering the node with
  ":" prefixed to its name.  Thanks again to wsor for mentioning this.
2024-11-09 20:24:02 -06:00
kabou e8d965e21a Add more particles when bonemealing grass.
* Bonemealing dirt_with_grass spawns new growth over a wide area, so it
  looks better if we spawn a few more extra bone meal particles.
* Update mod.conf depends to mcl_bone_meal.
2024-11-09 20:24:02 -06:00
kabou 8855246dd4 Update to new bone meal API.
* Update to use new mcl_bone_meal API:
* Use new bone meal item and remove related comment.
* Update mod depends in mod.conf
* Spelling fixes: s/bonemeal/bone meal/g
2024-11-09 20:24:02 -06:00
kabou 3889abbaf4 Add mcl_bone_meal.
* New mod mcl_bone_meal, replacing bone meal functionality previously
  held in mcl_dye.
* Improve bonemealing API using callbacks in the nodes that support
  bonemealing.
* Rename bone meal item to `"mcl_bone_meal:bone_meal"` and updated its
  crafting recipe.
* Implement legacy compatibility for older bone meal API.
* Remove all non dye-related bone meal code, texture and translations from
  mcl_dye.
* Add legacy compatibility shims to mcl_dye that refer to mcl_bone_meal.
* Add an alias for "mcl_dye:white" to keep mcl_dye and its API working
  uniterrupted.
* Update mod depends in mcl_dye mod.conf.
2024-11-09 20:24:02 -06:00
kabou f6235e8e92 Add bonemealing callback for fern.
* Adds a _mcl_on_bonemealing callback to fern.
2024-11-09 20:24:02 -06:00
kabou 2190080832 Add bonemealing callback for tall grass.
* Adds a _mcl_on_bonemealing callback to tall grass.
2024-11-09 20:24:02 -06:00
kabou ea1d52baab Add bonemealing callback for double flowers.
* Adds a _mcl_on_bonemealing callback to the double flowers.
2024-11-09 20:24:02 -06:00
kabou fdc7f4634d Add bonemealing callback for dirt with grass.
* Add new file mcl_flowers/bonemeal.lua, containing the bonemealing
  callback for "mcl_core:dirt_with_grass".
* Override "mcl_core:dirt_with_grass" with a _mcl_on_bonemealing handler
  calling a function defined in mcl_flowers. This sidesteps the problem
  that bonemealing a node from mcl_core needs knowledge of mcl_flowers,
  which would create a circular dependency.  H/t to cora for suggesting
  this solution. H/t to wsor for suggesting a solution that also works.
2024-11-09 20:24:02 -06:00
kabou bde0d9b238 Add bonemealing callback to cocoa.
* Adds a _mcl_on_bonemealing callback to the unripe cocoa pods.
2024-11-09 20:24:02 -06:00
teknomunk f644d37332 Keep same selection box size 2024-11-09 20:24:02 -06:00
kabou 17f2d85de9 Refactor beetroots and add bonemealing callback.
* Abstract unripe beetroot plant node registrations into a single
  indexed definition and do the registration in a loop.
* Adds a _mcl_on_bonemealing callback to the unripe melon plants.
2024-11-09 20:24:02 -06:00
kabou d07e8d9536 Add bonemealing callback to melons.
* Adds a _mcl_on_bonemealing callback to the unripe melon plants.
2024-11-09 20:24:02 -06:00
kabou 5d2fa8072a Add bonemealing callback to pumpkins.
* Adds a _mcl_on_bonemealing callback to the unripe pumpkin plants.
2024-11-09 20:24:02 -06:00
kabou 2d8bb12fad Add bonemealing callback to carrots.
* Adds a _mcl_on_bonemealing callback to the unripe carrot plants.
2024-11-09 20:24:02 -06:00
kabou 69032c3222 Add bonemealing callback to potatoes.
* Adds a _mcl_on_bonemealing callback to the unripe potato plants.
2024-11-09 20:24:02 -06:00
kabou 71e6fa9646 Add bonemealing callback to wheat.
* Adds a _mcl_on_bonemealing callback to the unripe wheat node definitions.
2024-11-09 20:24:02 -06:00
kabou 9ea52ce9b3 Add bonemealing callback to small mushrooms.
* Adds a _mcl_on_bonemealing callback to the mushroom node definitions.
2024-11-09 20:24:02 -06:00
kabou 0422635047 Add bonemealing callback to saplings.
* Adds a _mcl_on_bonemealing callback to the sapling node definitions.
2024-11-09 20:24:02 -06:00
kno10 b540e6c77b Improve head swivel code (#4622)
* Utilize the minetest 5.9.0 API that uses radians not degree.
* Simplify computations to make this more efficient, in particular by querying and updating the bone position less frequently.
* Resolves minetest warning `Deprecated call to set_bone_position, use set_bone_override instead` in this location, but other uses remain.
* `mcl_util.set_bone_position` not modified, because it redundantly compares to the previous rotation once more.

Reviewed-on: VoxeLibre/VoxeLibre#4622
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-11-10 02:41:55 +01:00
kno10 d49426d453 Cleanup of mcl_core/functions (#4592)
Cleanup of mods/ITEMS/mcl_core/functions.lua

This improves several further ABMs such as vine growing, and uses the `vector` API instead of tables.

Reviewed-on: VoxeLibre/VoxeLibre#4592
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-11-10 02:32:51 +01:00
the-real-herowl 2b7b7f1872 Merge pull request 'Improve plant growth system, add moisture level' (#4681) from kno10/VoxeLibre:pumpkin-melon-growth-1 into master
Reviewed-on: VoxeLibre/VoxeLibre#4681
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-11-10 02:11:37 +01:00
kno10 b5afa34469 Remove "wet" metadata altogether 2024-11-10 02:11:37 +01:00
kno10 ebf6cf32e8 meta:set_private("wet"), require only walkable nodes 2024-11-10 02:11:37 +01:00
kno10 a8318f6600 simplify catch-up LBM logic 2024-11-10 02:11:37 +01:00
kno10 fa7a7f4e81 more fixes to plant growth 2024-11-10 02:11:37 +01:00
kno10 c097c65262 adjust growth rates again 2024-11-10 02:11:37 +01:00
kno10 220a7b06e6 code review feedback 2024-11-10 02:11:37 +01:00
kno10 540a070c59 always use day light level, more fixes 2024-11-10 02:11:37 +01:00
kno10 78a958db4e Double the odds, to halve the ABM frequencies. 2024-11-10 02:11:37 +01:00
kno10 e9453d6210 Add plant growth speed option, drop average light level
Closes: #4683 by removal
2024-11-10 02:11:37 +01:00
kno10 9376cf92b1 Adjust growth speeds 2024-11-10 02:11:37 +01:00
kno10 c4030115c4 improve moisture logic 2024-11-10 02:11:37 +01:00
kno10 e1ace4ad01 pumpkin/melon growth only tests one neighbor every time 2024-11-10 02:11:37 +01:00
the-real-herowl e3b7847df1 Merge pull request 'Shield improvements and bugfixes (fixes #2756)' (#4582) from shieldy_shields into master
Reviewed-on: VoxeLibre/VoxeLibre#4582
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-11-10 01:34:50 +01:00
Mikita Wiśniewski f86a641dfa Improve shield block code and unhardcode offhand group 2024-11-10 01:34:50 +01:00
Mikita Wiśniewski 084741b733 Fix using shield on unknown nodes and cleanup 2024-11-10 01:34:50 +01:00
Mikita Wiśniewski d5bc0613d8 Make node itemstack check in mcl_shields less hacky 2024-11-10 01:34:50 +01:00
Loveaabb f26c34e65f Bugfix: Shield fails to block arrows 2024-11-10 01:34:50 +01:00
Loveaabb 04e29c5796 Several improvements to the Shield 2024-11-10 01:34:50 +01:00
Elias Åström 45ae170447 Deduplicate shield slowdown removal code 2024-11-10 01:34:50 +01:00
Elias Åström d0d1217dec Remove unused code in mcl_privs 2024-11-10 01:34:50 +01:00
Elias Åström cffc8e0145 Fix loosing interact bug in mcl_shields 2024-11-10 01:34:50 +01:00
the-real-herowl b136cbf9bb Changed bamboo cap drawtype (#4658)
Reviewed-on: VoxeLibre/VoxeLibre#4658
Co-authored-by: the-real-herowl <wiktor_t-i@proton.me>
Co-committed-by: the-real-herowl <wiktor_t-i@proton.me>
2024-11-02 21:04:00 +01:00
the-real-herowl e6d8d840db Merge pull request 'Fix missing protection checks in smithing tables' (#4659) from smithing_table_patch into master
Reviewed-on: VoxeLibre/VoxeLibre#4659
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-11-02 21:00:19 +01:00
Mikita Wiśniewski 78125f425a Fix taking items out of protected smithing tables 2024-11-02 21:00:19 +01:00
cora cb1999414b Fix putting items in protected smithing tables 2024-11-02 21:00:19 +01:00
Mikita Wiśniewski 41b188caea Remove "double drop" mechanics for bamboo (fixes #4514) (#4642)
Reviewed-on: VoxeLibre/VoxeLibre#4642
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-committed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-10-27 14:16:06 +01:00
kno10 ae7995d195 Fix axolotl attacking water mobs (#4675)
Also avoid jumping out of the water closes #4644

Reviewed-on: VoxeLibre/VoxeLibre#4675
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <kno10@noreply.git.minetest.land>
Co-committed-by: kno10 <kno10@noreply.git.minetest.land>
2024-10-27 14:10:11 +01:00
kno10 e293cbe631 Better handling of touching_ground for bouncing on beds (#4689)
Reviewed-on: VoxeLibre/VoxeLibre#4689
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-10-27 14:03:50 +01:00
the-real-herowl fd6cac5f0c Merge pull request 'Fix fog tint in overworld, apply memory leak fix, fix rain->clear clouds' (#4669) from weather-fixes into master
Reviewed-on: VoxeLibre/VoxeLibre#4669
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
2024-10-11 07:14:01 +02:00
teknomunk e864cc19ed Make fog_tint_type = "default" when weather is present to match behavior at 0.87.2 2024-10-09 01:05:20 +02:00
teknomunk 66c3c014a1 Make sure fog tints are preserved during weather is present 2024-10-09 01:05:20 +02:00
teknomunk 7807093b50 Another correction to color interpolation, change day color from layer position 0.15 to 0.50 2024-10-09 01:05:20 +02:00
teknomunk f6c3f4bd16 Correct value clamping 2024-10-09 01:05:20 +02:00
teknomunk 96a03b1923 Remove posibility of nil sky colors in overworld, add line break 2024-10-09 01:05:20 +02:00
teknomunk 2145470f63 Fix clouds during rain->clear weather transition 2024-10-09 01:05:20 +02:00
teknomunk 2ca0ccd8fe Fix fog tint in overworld, apply memory leak fix from rain.lua to snow.lua and thunder.lua 2024-10-09 01:05:20 +02:00
teknomunk 614518c6cd Revert minetest.add_entity() -> mcl_mobs.spawn() from #4445 (#4679)
Reviewed-on: VoxeLibre/VoxeLibre#4679
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
Co-authored-by: teknomunk <teknomunk@protonmail.com>
Co-committed-by: teknomunk <teknomunk@protonmail.com>
2024-10-08 15:34:30 +02:00
kno10 253a06fa08 Fix mob egg double-spawns (#4657)
If you spawn a mob clicking on a wall, two mobs will be spawned.

To reproduce: face a stack of stones, with a spawn egg click on the side of a stone. It does not happen when you click the top of a node, because spawning below fails and only the second one succeeds.

Reviewed-on: VoxeLibre/VoxeLibre#4657
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <kno10@noreply.git.minetest.land>
Co-committed-by: kno10 <kno10@noreply.git.minetest.land>
2024-09-30 19:21:40 +02:00
kno10 dcfd31d17a Avoid random jumps when standing due to gravity (fewer villagers on the roofs) (#4547)
Reviewed-on: VoxeLibre/VoxeLibre#4547
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-30 11:22:31 +02:00
teknomunk c34aecfcab Don't make 'ignore' nodes break bamboo or kelp (#4551)
This modifies the behavior of kelp and bamboo so that neither breaks when an unloaded node is encountered.

Reviewed-on: VoxeLibre/VoxeLibre#4551
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: teknomunk <teknomunk@protonmail.com>
Co-committed-by: teknomunk <teknomunk@protonmail.com>
2024-09-29 13:57:52 +02:00
Mikita Wiśniewski 9cb4f51468 Fix invalid global call in mcl_chests LBM (#4667)
Reviewed-on: VoxeLibre/VoxeLibre#4667
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-committed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-09-29 13:34:20 +02:00
kno10 d264ba70d8 Fix growth logic, clean up mcl_farming/shared_functions (#4640)
Reviewed-on: VoxeLibre/VoxeLibre#4640
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-20 14:00:49 +02:00
Mikita Wiśniewski 513413afc7 Use `remove_node` instead of `dig_node` in mcl_core ABMs (fixes #4628) (#4629)
The mycelium ABM has been left untouched because of the potential destructiveness. If we ever find that to be an issue, it can be fixed as part of a bigger PR.

Reviewed-on: VoxeLibre/VoxeLibre#4629
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-committed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-09-19 18:54:39 +02:00
kno10 011be754ca Allow deepslate copper to be mined with stone pickaxe (#4635)
Reviewed-on: VoxeLibre/VoxeLibre#4635
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: kno10 <kno10@noreply.git.minetest.land>
Co-committed-by: kno10 <kno10@noreply.git.minetest.land>
2024-09-18 10:11:55 +02:00
teknomunk eea96867c4 Don't add rain skycolor layer if the current layer is already the rain skycolor (#4648)
Fixes #4647 Rain makes the sky black until restart. This also fixes a memory leak caused by rain adding a color layer every time step.

Reviewed-on: VoxeLibre/VoxeLibre#4648
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: teknomunk <teknomunk@protonmail.com>
Co-committed-by: teknomunk <teknomunk@protonmail.com>
2024-09-18 10:10:53 +02:00
the-real-herowl cd2ee49591 Merge pull request 'Make Soul Speed work on Soul Soil' (#4604) from upstream/soul_soil_speed into master
Reviewed-on: VoxeLibre/VoxeLibre#4604
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-09-18 10:06:03 +02:00
seventeenthShulker de3b34f5ea Update English translation keys with soul soil 2024-09-18 10:06:03 +02:00
seventeenthShulker e2bcd129c1 Use soul_block group for soul speed bonus 2024-09-18 10:06:03 +02:00
seventeenthShulker 79e8452f62 Soul speed works on soul soil too
(needs localization)
2024-09-18 10:06:03 +02:00
the-real-herowl b239549774 Merge pull request 'Correct space check when spawning mobs' (#4445) from fix-has_room into master
Reviewed-on: VoxeLibre/VoxeLibre#4445
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
2024-09-17 11:49:29 +02:00
teknomunk 0b62c827aa Remove has_room debug data 2024-09-16 13:32:06 +02:00
teknomunk 626bdd13d8 Change several places where mobs are created to use mcl_mobs.spawn() instead of minetest.add_entity() 2024-09-16 13:32:06 +02:00
teknomunk 31a3788ce1 Address review comments 2024-09-16 13:32:06 +02:00
teknomunk e65370b845 Fixes 2024-09-16 13:32:06 +02:00
teknomunk 6c50e0a82b Fix volume used for room check during spawn, make mcl_mobs.spawn check for room before adding entity, change iron golems and mob spawners to use mcl_mobs.spawn 2024-09-16 13:32:06 +02:00
teknomunk 8ef08128b1 Add short circuit if sub-node space check isn't possible: 2024-09-16 13:32:06 +02:00
teknomunk 15efd00a29 Replace second call to minetest.find_nodes_in_area with checking top layer for matching nodes, change p2 calculation to use ceil(value) - 1, fix dx*dy*dz calculation 2024-09-16 13:32:06 +02:00
teknomunk fa3df0d8c6 Add check for presence of minetest.get_node_boxes before attempting sub-node space checks 2024-09-16 13:32:06 +02:00
teknomunk c41ce8ba59 Make spiders require 3x1x3 space to spawn 2024-09-16 13:32:06 +02:00
teknomunk 4d58f63485 Implement partial node spawning check 2024-09-16 13:32:06 +02:00
teknomunk fa09b65010 Add most of the code for sub-node accurate spawning volume check (needs a function to calculate bounding box height of nodes) 2024-09-16 13:32:06 +02:00
teknomunk d8d39ffd52 Add spawnbox parameter that overrides collision box for spawn volume checks 2024-09-16 13:32:06 +02:00
teknomunk b6aafedf25 Fix space check function has_room() in mcl_mobs/spawning.lua so it allows spiderproofing 2024-09-16 13:32:06 +02:00
Mikita Wiśniewski 178cb9340d Clean-up `set_string(..., nil)` usage (fixes #4639) (#4641)
Reviewed-on: VoxeLibre/VoxeLibre#4641
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
Co-authored-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-committed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-09-16 12:12:55 +02:00
kno10 f219e5f4ae Fix structure spawns under water + peaceful spawns (#4607)
- peaceful structure spawns would not run in peaceful mode (e.g., parrots)
- water structure spawns (e.g., guardians) would not run because the code required air above
- small code improvements

Reviewed-on: VoxeLibre/VoxeLibre#4607
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-15 23:15:30 +02:00
kno10 66b7a52d47 Make zombies and skeletons not float (#4512)
Reviewed-on: VoxeLibre/VoxeLibre#4512
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-15 23:14:10 +02:00
WillConker ce5eb8d88d Remove mobs_mc name check from mcl_mobspawners warning (#4501)
Fixes a warning.
Mobs spawners really only need to check the entity `.is_mob` as all mobs should have this set.

Reviewed-on: VoxeLibre/VoxeLibre#4501
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: WillConker <willconker@noreply.git.minetest.land>
Co-committed-by: WillConker <willconker@noreply.git.minetest.land>
2024-09-15 23:08:37 +02:00
the-real-herowl 6eb0d3c9d9 Merge pull request 'SmallJoker's mod load order patches' (#4541) from dependency_paradise into master
Reviewed-on: VoxeLibre/VoxeLibre#4541
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-09-15 22:25:44 +02:00
teknomunk 1707eef672 Fix two additional dependency issues 2024-09-15 22:25:44 +02:00
SmallJoker fb3e9dae84 autogroup: Do node overwrites after all mods have loaded 2024-09-15 22:25:44 +02:00
SmallJoker 7f5b19cda8 Fix missing dependencies for random_mod_load_order 2024-09-15 22:25:44 +02:00
the-real-herowl 7f372d066e Merge pull request 'FIX spawning' (#4636) from kno10/VoxeLibre:fix-spawning-brown-paperbag into master
Reviewed-on: VoxeLibre/VoxeLibre#4636
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-09-15 22:21:23 +02:00
kno10 f9290c6493 drop entirely 2024-09-15 22:21:23 +02:00
kno10 52124bd201 FIX spawning 2024-09-15 22:21:23 +02:00
Mikita Wiśniewski 19d662dee4 Fix some typos in the API documentation (#4630)
Reviewed-on: VoxeLibre/VoxeLibre#4630
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-committed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-09-12 18:13:52 +02:00
the-real-herowl 2be54212b7 Merge pull request 'Performance optimizations of spawning' (#4470) from kno10/VoxeLibre:delay_binome_check into master
Reviewed-on: VoxeLibre/VoxeLibre#4470
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-09-09 20:41:27 +02:00
kno10 7d763b7257 more mob spawn code improvements 2024-09-09 20:33:03 +02:00
kno10 bdd3ae2cd8 avoid spawning ground mobs in shallow water 2024-09-09 20:33:03 +02:00
kno10 2e1df31399 Refactor and clean up spawn checks, optimize. 2024-09-09 20:33:03 +02:00
kno10 382a35bb44 delay biome check when spawning 2024-09-09 20:33:03 +02:00
kno10 0752ed17d8 Improve cacti and cane growth ABM (#4590)
- local functions, as they are not called by anywhere else
- delay water check of reed, first check height
- reduce number of get_node calls (for height 1,2,3 the old code used 4,5,4 calls, the new only 2,3,3)
- cane growth rate is also reduced

This will make the ABM cheaper.

Reviewed-on: VoxeLibre/VoxeLibre#4590
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-09 20:22:04 +02:00
kno10 72c7489976 use vector.new in mcl_dungeons (#4567)
No functional changes, just more vector API, which supposedly is faster?

Reviewed-on: VoxeLibre/VoxeLibre#4567
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-09 20:08:30 +02:00
kno10 71881154e9 use vector.in_area instead of own code in mapgen (#4562)
`between` and `in_cube` duplicate functionality already in minetest `vector`.

Reviewed-on: VoxeLibre/VoxeLibre#4562
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-09 20:05:59 +02:00
kno10 6c38823606 More randomness for slime chunks (#4466)
Use a classic pseudo-random hashing approach, by multiplication of chunk numbers
with large primes that should be more random.
- make slime density (as 1 in N) and maximum light level (default: no limit) configurable
- Allow using a 3d chunking system where y is also used for hashing

This does *not* modify spawn frequency, only the chunk logic.

Reviewed-on: VoxeLibre/VoxeLibre#4466
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-09 19:58:54 +02:00
kno10 dd4898b319 Fix surface pools with deep holes (#4571)
Sometimes, pools would spawn deep underground and then produce deep holes.
I noticed that such pools would be at +48, at the block boundary.
IMHO this may be an error in minetest surface detection.

Nevertheless, here is a workaround: require air above pool spawns.

Also clean up the pool code

Reviewed-on: VoxeLibre/VoxeLibre#4571
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-09-09 13:25:30 +02:00
139 changed files with 2486 additions and 2768 deletions

View File

@ -117,10 +117,6 @@ end
-- Array of unique hardness values for each group which affects dig time.
local hardness_values = get_hardness_values_for_groups()
-- Map indexed by hardness values which return the index of that value in
-- hardness_value. Used for quick lookup.
local hardness_lookup = get_hardness_lookup_for_groups(hardness_values)
--[[local function compute_creativetimes(group)
local creativetimes = {}
@ -186,6 +182,7 @@ local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency)
local mult = capsdef.speed or 1
local uses = capsdef.uses
local def = mcl_autogroup.registered_diggroups[g]
assert(def, toolname .. " has unknown diggroup '" .. dump(g) .. "'")
local max_level = def.levels and #def.levels or 1
assert(capsdef.level, toolname .. ' is missing level for ' .. g)
@ -313,6 +310,13 @@ function mcl_autogroup.get_wear(toolname, diggroup)
end
local function overwrite()
-- Refresh, now that all groups are known.
hardness_values = get_hardness_values_for_groups()
-- Map indexed by hardness values which return the index of that value in
-- hardness_value. Used for quick lookup.
local hardness_lookup = get_hardness_lookup_for_groups(hardness_values)
for nname, ndef in pairs(minetest.registered_nodes) do
local newgroups = table.copy(ndef.groups)
if (nname ~= "ignore" and ndef.diggable) then
@ -374,4 +378,5 @@ local function overwrite()
end
end
overwrite()
-- Make sure all tools and groups are registered
minetest.register_on_mods_loaded(overwrite)

View File

@ -1,3 +1,4 @@
name = _mcl_autogroup
depends = mcl_autogroup
author = ryvnf
description = VoxeLibre core mod which automatically adds groups to all items. Very important for digging times.

View File

@ -2,33 +2,33 @@
Simple flow functions.
## flowlib.is_touching(realpos, nodepos, radius)
Return true if a sphere of <radius> at <realpos> collide with node at <nodepos>.
Return true if a sphere of `radius` at `realpos` collide with node at `nodepos`.
* realpos: position
* nodepos: position
* radius: number
## flowlib.is_water(pos)
Return true if node at <pos> is water, false overwise.
Return true if node at `pos` is water, false otherwise.
* pos: position
## flowlib.node_is_water(node)
Return true if <node> is water, false overwise.
Return true if `node` is water, false otherwise.
* node: node
## flowlib.is_lava(pos)
Return true if node at <pos> is lava, false overwise.
Return true if node at `pos` is lava, false otherwise.
* pos: position
## flowlib.node_is_lava(node)
Return true if <node> is lava, false overwise.
Return true if `node` is lava, false otherwise.
* node: node
## flowlib.is_liquid(pos)
Return true if node at <pos> is liquid, false overwise.
Return true if node at `pos` is liquid, false otherwise.
* pos: position
## flowlib.node_is_liquid(node)
Return true if <node> is liquid, false overwise.
Return true if `node` is liquid, false otherwise.
* node: node
## flowlib.quick_flow(pos, node)
@ -37,9 +37,9 @@ Return direction where the water is flowing (to be use to push mobs, items...).
* node: node
## flowlib.move_centre(pos, realpos, node, radius)
Return the pos of the nearest not water block near from <pos> in a sphere of <radius> at <realpos>.
WARNING: This function is never used in mcl2, use at your own risk. The informations described here may be wrong.
Return the pos of the nearest not water block near from `pos` in a sphere of `radius` at `realpos`.
WARNING: This function is never used in VL, use at your own risk. The informations described here may be wrong.
* pos: position
* realpos: position, position of the entity
* node: node
* radius: number
* radius: number

View File

@ -1,8 +1,8 @@
# mcl_autogroup
This mod emulate digging times from mc.
This mod emulates digging times from MC.
## mcl_autogroup.can_harvest(nodename, toolname, player)
Return true if <nodename> can be dig with <toolname> by <player>.
Return true if `nodename` can be dig with `toolname` by <player>.
* nodename: string, valid nodename
* toolname: (optional) string, valid toolname
* player: (optinal) ObjectRef, valid player
@ -14,7 +14,7 @@ WARNING: This function can only be called after mod initialization.
* efficiency: (optional) integer, the efficiency level the tool is enchanted with (default 0)
## mcl_autogroup.get_wear(toolname, diggroup)
Return the max wear of <toolname> with <diggroup>
Return the max wear of `toolname` with `diggroup`
WARNING: This function can only be called after mod initialization.
* toolname: string, name of the tool used
* diggroup: string, the name of the diggroup the tool is used on
@ -25,4 +25,4 @@ WARNING: This function can only be called after mod initialization.
* level: (optional) string, if specified it is an array containing the names of the different digging levels the digging group supports
## mcl_autogroup.registered_diggroups
List of registered diggroups, indexed by name.
List of registered diggroups, indexed by name.

View File

@ -1,5 +1,5 @@
# mcl_colors
Mod providing global table containing legacity minecraft colors to be used in mods.
Mod providing global table containing legacy Minecraft colors to be used in mods.
## mcl_colors.*
Colors by upper name, in hex value.

View File

@ -6,10 +6,10 @@ WARNING: Not using it inside your mods may cause strange bugs (using the native
## Callbacks
To modify the amount of damage made by something:
To modify the amount of damage dealt by something:
```lua
--obj: an ObjectRef
mcl_damage.register_modifier(function(obj, damage, reason)
end, 0)
```
```

View File

@ -1,9 +1,13 @@
## mcl_events
### Registering Events
`mlc_events.register_event("name",def)`
# mcl_events
#### Event Definition
{
## Registering Events
`mcl_events.register_event("name", def)`
### Event Definition
```
{
stage = 0,
max_stage = 1,
percent = 100,
@ -22,6 +26,8 @@
cond_complete = function(event) end,
--return true if event finished successfully
}
```
### Debugging
* /event_start <event> -- starts the given event at the current player coordinates
## Debugging
* /event_start `event` -- starts the given event at the current player coordinates

View File

@ -3,13 +3,13 @@ This mod provide helper functions to create explosions.
## mcl_explosions.explode(pos, strength, info, puncher)
* pos: position, initial position of the explosion
* strenght: number, radius of the explosion
* strength: number, radius of the explosion
* info: table, explosion informations:
* drop_chance: number, if specified becomes the drop chance of all nodes in the explosion (default: 1.0 / strength)
* max_blast_resistance: int, if specified the explosion will treat all non-indestructible nodes as having a blast resistance of no more than this value
* sound: bool, if true, the explosion will play a sound (default: true)
* particles: bool, if true, the explosion will create particles (default: true)
* fire: bool, if true, 1/3 nodes become fire (default: false)
* fire: bool, if true, 1/3 of nodes become fire (default: false)
* griefing: bool, if true, the explosion will destroy nodes (default: true)
* grief_protected: bool, if true, the explosion will also destroy nodes which have been protected (default: false)
* puncher: (optional) entity, will be used as source for damage done by the explosion
* puncher: (optional) entity, will be used as source for damage done by the explosion

View File

@ -48,6 +48,20 @@ function table.pairs_by_keys(t, f)
return iter
end
-- Removes one element randomly selected from the array section of the table and
-- returns it, or nil if there are no elements in the array section of the table
function table.remove_random_element(table)
local count = #table
if count == 0 then return nil end
local idx = math.random(count)
local res = table[idx]
table[idx] = table[count]
table[count] = nil
count = count - 1
return res
end
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default", false)
local LOG_MODULE = "[MCL2]"
function mcl_util.mcl_log(message, module, bypass_default_logger)
@ -1108,3 +1122,34 @@ function mcl_util.to_bool(val)
if not val then return false end
return true
end
if not vector.in_area then
-- backport from minetest 5.8, can be removed when the minimum version is 5.8
vector.in_area = function(pos, min, max)
return (pos.x >= min.x) and (pos.x <= max.x) and
(pos.y >= min.y) and (pos.y <= max.y) and
(pos.z >= min.z) and (pos.z <= max.z)
end
end
-- Traces along a line of nodes vertically to find the next possition that isn't an allowed node
---@param pos The position to start tracing from
---@param dir The direction to trace in. 1 is up, -1 is down, all other values are not allowed.
---@param allowed_nodes A set of node names to trace along.
---@param limit The maximum number of steps to make. Defaults to 16 if nil or missing
---@return Three return values:
--- the position of the next node that isn't allowed or nil if no such node was found,
--- the distance from the start where that node was found,
--- the node table if a node was found
function mcl_util.trace_nodes(pos, dir, allowed_nodes, limit)
if (dir ~= -1) and (dir ~= 1) then return nil, 0, nil end
limit = limit or 16
for i = 1,limit do
pos = vector.offset(pos, 0, dir, 0)
local node = minetest.get_node(pos)
if not allowed_nodes[node.name] then return pos, i, node end
end
return nil, limit, nil
end

View File

@ -5,20 +5,21 @@ This mod provides utility functions about positions and dimensions.
This function returns:
* true, true: if pos is in deep void (deadly)
* true, false: if the pos is in void (non deadly)
* false, false: owerwise
* true, false: if the pos is in void (non-deadly)
* false, false: otherwise
Params:
* pos: position
## mcl_worlds.y_to_layer(y)
This function is used to calculate the minetest y layer and dimension of the given <y> minecraft layer.
This function is used to calculate the Minetest y layer and dimension of the given y Minecraft layer.
Mainly used for ore generation.
Takes an Y coordinate as input and returns:
Takes a Y coordinate as input and returns:
* The corresponding Minecraft layer (can be `nil` if void)
* The corresponding Minecraft dimension ("overworld", "nether" or "end") or "void" if y is in the void
* The corresponding Minecraft layer (can be nil if void)
* The corresponding Minecraft dimension ("overworld", "nether" or "end") or "void" if <y> is in the void
If the Y coordinate is not located in any dimension, it will return: nil, "void"
Params:
@ -26,7 +27,7 @@ Params:
* y: int
## mcl_worlds.pos_to_dimension(pos)
This function return the Minecraft dimension of <pos> ("overworld", "nether" or "end") or "void" if <y> is in the void.
This function return the Minecraft dimension of pos ("overworld", "nether" or "end") or "void" if y is in the void.
* pos: position
@ -38,31 +39,32 @@ mc_dimension can be "overworld", "nether", "end" (default: "overworld").
* mc_dimension: string
## mcl_worlds.has_weather(pos)
Returns true if <pos> can have weather, false owerwise.
Returns true if pos can have weather, false otherwise.
Weather can be only in the overworld.
* pos: position
## mcl_worlds.has_dust(pos)
Returns true if <pos> can have nether dust, false owerwise.
Returns true if pos can have nether dust, false otherwise.
Nether dust can be only in the nether.
* pos: position
## mcl_worlds.compass_works(pos)
Returns true if compasses are working at <pos>, false owerwise.
In mc, you cant use compass in the nether and the end.
Returns true if compasses are working at pos, false otherwise.
In MC, you cant use compass in the nether and the end.
* pos: position
## mcl_worlds.compass_works(pos)
Returns true if clock are working at <pos>, false owerwise.
In mc, you cant use clock in the nether and the end.
Returns true if clock are working at pos, false otherwise.
In MC, you cant use clock in the nether and the end.
* pos: position
## mcl_worlds.register_on_dimension_change(function(player, dimension, last_dimension))
Register a callback function func(player, dimension).
It will be called whenever a player changes between dimensions.
The void counts as dimension.
@ -75,7 +77,7 @@ The void counts as dimension.
Table containing all function registered with mcl_worlds.register_on_dimension_change()
## mcl_worlds.dimension_change(player, dimension)
Notify this mod of a dimension change of <player> to <dimension>
Notify this mod of a dimension change of player to dimension
* player: player, player who changed the dimension
* dimension: string, new dimension ("overworld", "nether", "end", "void")

View File

@ -388,7 +388,7 @@ end
local function on_step_work (self, dtime)
local function on_step_work(self, dtime, moveresult)
local pos = self.object:get_pos()
if not pos then return end
@ -402,7 +402,7 @@ local function on_step_work (self, dtime)
-- Do we abandon out of here now?
end
if self:falling(pos) then return end
if self:falling(pos, moveresult) then return end
if self:step_damage (dtime, pos) then return end
if self.state == "die" then return end
@ -502,11 +502,11 @@ end
-- main mob function
function mob_class:on_step(dtime)
function mob_class:on_step(dtime, moveresult)
if not DEVELOPMENT then
-- Removed as bundled Lua (5.1 doesn't support xpcall)
--local status, retVal = xpcall(on_step_work, on_step_error_handler, self, dtime)
local status, retVal = pcall(on_step_work, self, dtime)
local status, retVal = pcall(on_step_work, self, dtime, moveresult)
if status then
return retVal
else
@ -521,7 +521,7 @@ function mob_class:on_step(dtime)
log_error (dump(retVal), dump(pos), dump(self))
end
else
return on_step_work (self, dtime)
return on_step_work (self, dtime, moveresult)
end
end

View File

@ -285,6 +285,7 @@ function mob_class:check_breeding()
end
local child = mcl_mobs.spawn_child(pos, parent1.name)
if not child then return end
local ent_c = child:get_luaentity()

View File

@ -5,6 +5,7 @@ local validate_vector = mcl_util.validate_vector
local active_particlespawners = {}
local disable_blood = minetest.settings:get_bool("mobs_disable_blood")
local DEFAULT_FALL_SPEED = -9.81*1.5
local PI_THIRD = math.pi / 3 -- 60 degrees
local PATHFINDING = "gowp"
@ -294,86 +295,66 @@ function mcl_mobs:set_animation(self, anim)
self:set_animation(anim)
end
local function dir_to_pitch(dir)
--local dir2 = vector.normalize(dir)
local xz = math.abs(dir.x) + math.abs(dir.z)
return -math.atan2(-dir.y, xz)
end
local function who_are_you_looking_at (self, dtime)
local pos = self.object:get_pos()
if self.order == "sleep" then
self._locked_object = nil
return
end
local stop_look_at_player_chance = math.random(833/self.curiosity)
-- was 10000 - div by 12 for avg entities as outside loop
local stop_look_at_player = stop_look_at_player_chance == 1
local stop_look_at_player = math.random() * 833 <= self.curiosity
if self.attack then
if not self.target_time_lost then
self._locked_object = self.attack
else
self._locked_object = nil
end
self._locked_object = not self.target_time_lost and self.attack or nil
elseif self.following then
self._locked_object = self.following
elseif self._locked_object then
if stop_look_at_player then
--minetest.log("Stop look: ".. self.name)
self._locked_object = nil
end
if stop_look_at_player then self._locked_object = nil end
elseif not self._locked_object then
if mcl_util.check_dtime_timer(self, dtime, "step_look_for_someone", 0.2) then
--minetest.log("Change look check: ".. self.name)
-- For the wither this was 20/60=0.33, so probably need to rebalance and divide rates.
-- but frequency of check isn't good as it is costly. Making others too infrequent requires testing
local chance = 150/self.curiosity
if chance < 1 then chance = 1 end
local look_at_player_chance = math.random(chance)
-- was 5000 but called in loop based on entities. so div by 12 as estimate avg of entities found,
-- then div by 20 as less freq lookup
local look_at_player = look_at_player_chance == 1
local pos = self.object:get_pos()
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 8)) do
if obj:is_player() and vector.distance(pos,obj:get_pos()) < 4 then
--minetest.log("Change look to player: ".. self.name)
if obj:is_player() and vector.distance(pos, obj:get_pos()) < 4 then
self._locked_object = obj
break
elseif obj:is_player() or (obj:get_luaentity() and obj:get_luaentity().name == self.name and self ~= obj:get_luaentity()) then
if look_at_player then
--minetest.log("Change look to mob: ".. self.name)
elseif obj:is_player() or (obj:get_luaentity() and self ~= obj:get_luaentity() and obj:get_luaentity().name == self.name) then
-- For the wither this was 20/60=0.33, so probably need to rebalance and divide rates.
-- but frequency of check isn't good as it is costly. Making others too infrequent requires testing
-- was 5000 but called in loop based on entities. so div by 12 as estimate avg of entities found,
-- then div by 20 as less freq lookup
if math.random() * 150 <= self.curiosity then
self._locked_object = obj
break
end
end
end
end
end
end
function mob_class:check_head_swivel(dtime)
if not self.head_swivel or type(self.head_swivel) ~= "string" then return end
who_are_you_looking_at(self, dtime)
who_are_you_looking_at (self, dtime)
local newr, oldp, oldr = vector.zero(), nil, nil
if self.object.get_bone_override then -- minetest >= 5.9
local ov = self.object:get_bone_override(self.head_swivel)
oldp, oldr = ov.position.vec, ov.rotation.vec
else -- minetest < 5.9
oldp, oldr = self.object:get_bone_position(self.head_swivel)
oldr = vector.apply(oldr, math.rad) -- old API uses radians
end
local final_rotation = vector.zero()
local oldp,oldr = self.object:get_bone_position(self.head_swivel)
if self._locked_object and (self._locked_object:is_player() or self._locked_object:get_luaentity()) and self._locked_object:get_hp() > 0 then
local locked_object = self._locked_object
if locked_object and (locked_object:is_player() or locked_object:get_luaentity()) and locked_object:get_hp() > 0 then
local _locked_object_eye_height = 1.5
if self._locked_object:get_luaentity() then
_locked_object_eye_height = self._locked_object:get_luaentity().head_eye_height
end
if self._locked_object:is_player() then
_locked_object_eye_height = self._locked_object:get_properties().eye_height
if locked_object:is_player() then
_locked_object_eye_height = locked_object:get_properties().eye_height
elseif locked_object:get_luaentity() then
_locked_object_eye_height = locked_object:get_luaentity().head_eye_height
end
if _locked_object_eye_height then
local self_rot = self.object:get_rotation()
-- If a mob is attached, should we really be messing with what they are looking at?
-- Should this be excluded?
@ -381,40 +362,48 @@ function mob_class:check_head_swivel(dtime)
self_rot = self.object:get_attach():get_rotation()
end
local player_pos = self._locked_object:get_pos()
local direction_player = vector.direction(vector.add(self.object:get_pos(), vector.new(0, self.head_eye_height*.7, 0)), vector.add(player_pos, vector.new(0, _locked_object_eye_height, 0)))
local mob_yaw = math.deg(-(-(self_rot.y)-(-minetest.dir_to_yaw(direction_player))))+self.head_yaw_offset
local mob_pitch = math.deg(-dir_to_pitch(direction_player))*self.head_pitch_multiplier
local ps = self.object:get_pos()
ps.y = ps.y + self.head_eye_height * .7
local pt = locked_object:get_pos()
pt.y = pt.y + _locked_object_eye_height
local dir = vector.direction(ps, pt)
local mob_yaw = self_rot.y + math.atan2(dir.x, dir.z) + self.head_yaw_offset
local mob_pitch = math.asin(-dir.y) * self.head_pitch_multiplier
if (mob_yaw < -60 or mob_yaw > 60) and not (self.attack and self.state == "attack" and not self.runaway) then
final_rotation = vector.multiply(oldr, 0.9)
if (mob_yaw < -PI_THIRD or mob_yaw > PI_THIRD) and not (self.attack and self.state == "attack" and not self.runaway) then
newr = vector.multiply(oldr, 0.9)
elseif self.attack and self.state == "attack" and not self.runaway then
if self.head_yaw == "y" then
final_rotation = vector.new(mob_pitch, mob_yaw, 0)
newr = vector.new(mob_pitch, mob_yaw, 0)
elseif self.head_yaw == "z" then
final_rotation = vector.new(mob_pitch, 0, -mob_yaw)
newr = vector.new(mob_pitch, 0, -mob_yaw)
end
else
if self.head_yaw == "y" then
final_rotation = vector.new(((mob_pitch-oldr.x)*.3)+oldr.x, ((mob_yaw-oldr.y)*.3)+oldr.y, 0)
newr = vector.new((mob_pitch-oldr.x)*.3+oldr.x, (mob_yaw-oldr.y)*.3+oldr.y, 0)
elseif self.head_yaw == "z" then
final_rotation = vector.new(((mob_pitch-oldr.x)*.3)+oldr.x, 0, -(((mob_yaw-oldr.y)*.3)+oldr.y)*3)
newr = vector.new((mob_pitch-oldr.x)*.3+oldr.x, 0, ((mob_yaw-oldr.y)*.3+oldr.y)*-3)
end
end
end
elseif not self._locked_object and math.abs(oldr.y) > 3 and math.abs(oldr.x) < 3 then
final_rotation = vector.multiply(oldr, 0.9)
else
--final_rotation = vector.new(0,0,0)
elseif not locked_object and math.abs(oldr.y) > 0.05 and math.abs(oldr.x) < 0.05 then
newr = vector.multiply(oldr, 0.9)
end
-- 0.02 is about 1.14 degrees tolerance, to update less often
local newp = vector.new(0, self.bone_eye_height, self.horizontal_head_height)
if math.abs(oldr.x-newr.x) + math.abs(oldr.y-newr.y) + math.abs(oldr.z-newr.z) < 0.02 and vector.equals(oldp, newp) then return end
if self.object.get_bone_override then -- minetest >= 5.9
self.object:set_bone_override(self.head_swivel, {
position = { vec = newp, absolute = true },
rotation = { vec = newr, absolute = true } })
else -- minetest < 5.9
-- old API uses degrees not radians
self.object:set_bone_position(self.head_swivel, newp, vector.apply(newr, math.deg))
end
mcl_util.set_bone_position(self.object,self.head_swivel, vector.new(0,self.bone_eye_height,self.horizontal_head_height), final_rotation)
end
function mob_class:set_animation_speed()
local v = self.object:get_velocity()
if v then

View File

@ -141,7 +141,7 @@ function mcl_mobs.register_mob(name, def)
local final_def = {
use_texture_alpha = def.use_texture_alpha,
head_swivel = def.head_swivel or nil, -- bool to activate this function
head_yaw_offset = def.head_yaw_offset or 0, -- for wonkey model bones
head_yaw_offset = math.rad(def.head_yaw_offset or 0), -- for wonkey model bones
head_pitch_multiplier = def.head_pitch_multiplier or 1, --for inverted pitch
bone_eye_height = def.bone_eye_height or 1.4, -- head bone offset
head_eye_height = def.head_eye_height or def.bone_eye_height or 0, -- how hight aproximatly the mobs head is fromm the ground to tell the mob how high to look up at the player
@ -528,7 +528,7 @@ end
-- Note: This also introduces the “spawn_egg” group:
-- * spawn_egg=1: Spawn egg (generic mob, no metadata)
-- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata)
function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addegg, no_creative)
function mcl_mobs.register_egg(mob_id, desc, background_color, overlay_color, addegg, no_creative)
local grp = {spawn_egg = 1}
@ -539,7 +539,7 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
local invimg = "(spawn_egg.png^[multiply:" .. background_color ..")^(spawn_egg_overlay.png^[multiply:" .. overlay_color .. ")"
if old_spawn_icons then
local mobname = mob:gsub("mobs_mc:","")
local mobname = mob_id:gsub("mobs_mc:","")
local fn = "mobs_mc_spawn_icon_"..mobname..".png"
if mcl_util.file_exists(minetest.get_modpath("mobs_mc").."/textures/"..fn) then
invimg = fn
@ -551,7 +551,7 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
end
-- register old stackable mob egg
minetest.register_craftitem(mob, {
minetest.register_craftitem(mob_id, {
description = desc,
inventory_image = invimg,
@ -561,7 +561,6 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
_doc_items_usagehelp = S("Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns."),
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.above
-- am I clicking on something with existing on_rightclick function?
@ -571,11 +570,12 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
return def.on_rightclick(pointed_thing.under, under, placer, itemstack)
end
local mob_name = itemstack:get_name()
if pos and within_limits(pos, 0) and not minetest.is_protected(pos, placer:get_player_name()) then
local name = placer:get_player_name()
local privs = minetest.get_player_privs(name)
if under.name == "mcl_mobspawners:spawner" then
if minetest.is_protected(pointed_thing.under, name) then
minetest.record_protection_violation(pointed_thing.under, name)
@ -593,7 +593,6 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
--minetest.log("max light: " .. mob_light_lvl[2])
-- Handle egg conversion
local mob_name = itemstack:get_name()
local convert_to = (minetest.registered_entities[mob_name] or {})._convert_to
if convert_to then mob_name = convert_to end
@ -604,19 +603,24 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
return itemstack
end
if not minetest.registered_entities[mob] then
if not minetest.registered_entities[mob_name] then
return itemstack
end
if minetest.settings:get_bool("only_peaceful_mobs", false)
and minetest.registered_entities[mob].type == "monster" then
and minetest.registered_entities[mob_name].type == "monster" then
minetest.chat_send_player(name, S("Only peaceful mobs allowed!"))
return itemstack
end
pos.y = pos.y - 0.5
pos.y = pos.y - 1
local mob = mcl_mobs.spawn(pos, mob_name)
if not mob then
pos.y = pos.y + 1
mob = mcl_mobs.spawn(pos, mob_name)
if not mob then return end
end
local mob = minetest.add_entity(pos, mob)
local entityname = itemstack:get_name()
minetest.log("action", "Player " ..name.." spawned "..entityname.." at "..minetest.pos_to_string(pos))
local ent = mob:get_luaentity()
@ -647,5 +651,4 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
return itemstack
end,
})
end

View File

@ -927,8 +927,7 @@ end
-- falling and fall damage
-- returns true if mob died
function mob_class:falling(pos)
function mob_class:falling(pos, moveresult)
if self.fly and self.state ~= "die" then
return
end
@ -951,7 +950,13 @@ function mob_class:falling(pos)
new_acceleration = vector.new(0, DEFAULT_FALL_SPEED, 0)
elseif v.y <= 0 and v.y > self.fall_speed then
-- fall downwards at set speed
new_acceleration = vector.new(0, self.fall_speed, 0)
if moveresult and moveresult.touching_ground then
-- when touching ground, retain a minimal gravity to keep the touching_ground flag
-- but also to not get upwards acceleration with large dtime when on bouncy ground
new_acceleration = vector.new(0, self.fall_speed * 0.01, 0)
else
new_acceleration = vector.new(0, self.fall_speed, 0)
end
else
-- stop accelerating once max fall speed hit
new_acceleration =vector.zero()

View File

@ -10,12 +10,12 @@ local overworld_sky_threshold = tonumber(minetest.settings:get("mcl_mobs_overwor
local overworld_passive_threshold = tonumber(minetest.settings:get("mcl_mobs_overworld_passive_threshold")) or 7
local get_node = minetest.get_node
local get_item_group = minetest.get_item_group
local get_node_light = minetest.get_node_light
local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air
local mt_get_biome_name = minetest.get_biome_name
local get_objects_inside_radius = minetest.get_objects_inside_radius
local get_connected_players = minetest.get_connected_players
local registered_nodes = minetest.registered_nodes
local math_min = math.min
local math_max = math.max
@ -25,6 +25,7 @@ local math_ceil = math.ceil
local math_cos = math.cos
local math_sin = math.sin
local math_sqrt = math.sqrt
local math_abs = math.abs
local vector_distance = vector.distance
local vector_new = vector.new
@ -35,18 +36,14 @@ local table_remove = table.remove
local pairs = pairs
local logging = minetest.settings:get_bool("mcl_logging_mobs_spawn", false)
local function mcl_log (message, property)
if logging then
if property then
message = message .. ": " .. dump(property)
end
mcl_util.mcl_log (message, "[Mobs spawn]", true)
end
local function mcl_log(message, property)
if property then message = message .. ": " .. dump(property) end
mcl_util.mcl_log(message, "[Mobs spawn]", true)
end
if not logging then mcl_log = function() end end
local dbg_spawn_attempts = 0
local dbg_spawn_succ = 0
local dbg_spawn_counts = {}
local remove_far = true
@ -99,169 +96,6 @@ mcl_log("Percentage of hostile spawns are group: " .. hostile_group_percentage_s
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false
-- THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs
-- Also used for missing parameter
-- Please update the list when adding new biomes!
local list_of_all_biomes = {
-- underground:
"FlowerForest_underground",
"JungleEdge_underground",
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
"MangroveSwamp_underground",
-- ocean:
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"MangroveSwamp_ocean",
"MangroveSwamp_deep_ocean",
-- water or beach?
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
-- beach:
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"BambooJungleM_shore",
"BambooJungle_shore",
"MangroveSwamp_shore",
-- dimension biome:
"Nether",
"BasaltDelta",
"CrimsonForest",
"WarpedForest",
"SoulsandValley",
"End",
-- Overworld regular:
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"ExtremeHillsM",
"ExtremeHills+_snowtop",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"MangroveSwamp",
"BambooJungle",
"BambooJungleEdge",
"BambooJungleEdgeM",
"BambooJungleM",
}
-- count how many mobs are in an area
local function count_mobs(pos,r,mob_type)
local num = 0
@ -289,11 +123,7 @@ local function count_mobs_total(mob_type)
end
local function count_mobs_add_entry (mobs_list, mob_cat)
if mobs_list[mob_cat] then
mobs_list[mob_cat] = mobs_list[mob_cat] + 1
else
mobs_list[mob_cat] = 1
end
mobs_list[mob_cat] = (mobs_list[mob_cat] or 0) + 1
end
--categorise_by can be name or type or spawn_class
@ -452,7 +282,7 @@ function mcl_mobs:spawn_setup(def)
local dimension = def.dimension or "overworld"
local type_of_spawning = def.type_of_spawning or "ground"
local biomes = def.biomes or list_of_all_biomes
local biomes = def.biomes or nil
local min_light = def.min_light or 0
local max_light = def.max_light or (minetest.LIGHT_MAX + 1)
local chance = def.chance or 1000
@ -619,14 +449,14 @@ local function get_next_mob_spawn_pos(pos)
xoff, yoff, zoff = xoff * dd, yoff * dd, zoff * dd
local goal_pos = vector.offset(pos, xoff, yoff, zoff)
if not ( math.abs(goal_pos.x) <= SPAWN_MAPGEN_LIMIT and math.abs(goal_pos.y) <= SPAWN_MAPGEN_LIMIT and math.abs(goal_pos.z) <= SPAWN_MAPGEN_LIMIT ) then
if not (math_abs(goal_pos.x) <= SPAWN_MAPGEN_LIMIT and math_abs(goal_pos.y) <= SPAWN_MAPGEN_LIMIT and math_abs(goal_pos.z) <= SPAWN_MAPGEN_LIMIT) then
mcl_log("Pos outside mapgen limits: " .. minetest.pos_to_string(goal_pos))
return nil
end
-- Calculate upper/lower y limits
local d2 = xoff*xoff + zoff*zoff -- squared distance in x,z plane only
local y1 = math_sqrt( MOB_SPAWN_ZONE_OUTER_SQ - d2 ) -- absolue value of distance to outer sphere
local y1 = math_sqrt(MOB_SPAWN_ZONE_OUTER_SQ - d2) -- absolue value of distance to outer sphere
local y_min, y_max
if d2 >= MOB_SPAWN_ZONE_INNER_SQ then
@ -635,7 +465,7 @@ local function get_next_mob_spawn_pos(pos)
y_max = pos.y + y1
else
-- Inner region, y range spans between inner and outer spheres
local y2 = math_sqrt( MOB_SPAWN_ZONE_INNER_SQ - d2 )
local y2 = math_sqrt(MOB_SPAWN_ZONE_INNER_SQ - d2)
if goal_pos.y > pos.y then
-- Upper hemisphere
y_min = pos.y + y2
@ -680,12 +510,12 @@ end
--a simple helper function for mob_spawn
local function biome_check(biome_list, biome_goal)
if not biome_goal then return false end
for _, data in pairs(biome_list) do
if data == biome_goal then
return true
end
end
return false
end
@ -700,8 +530,8 @@ local function get_water_spawn(p)
end
end
local function has_room(self,pos)
local cb = self.collisionbox
local function has_room(self, pos)
local cb = self.spawnbox or self.collisionbox
local nodes = {}
if self.fly_in then
local t = type(self.fly_in)
@ -712,18 +542,74 @@ local function has_room(self,pos)
end
end
table.insert(nodes,"air")
local x = cb[4] - cb[1]
local y = cb[5] - cb[2]
local z = cb[6] - cb[3]
local r = math.ceil(x * y * z)
local p1 = vector.offset(pos,cb[1],cb[2],cb[3])
local p2 = vector.offset(pos,cb[4],cb[5],cb[6])
local n = #minetest.find_nodes_in_area(p1,p2,nodes) or 0
if r > n then
minetest.log("warning","[mcl_mobs] No room for mob "..self.name.." at "..minetest.pos_to_string(vector.round(pos)))
return false
-- Calculate area to check for room
local cb_height = cb[5] - cb[2]
local p1 = vector.new(
math.round(pos.x + cb[1]),
math.floor(pos.y),
math.round(pos.z + cb[3]))
local p2 = vector.new(
math.round(pos.x + cb[4]),
math.ceil(p1.y + cb_height) - 1,
math.round(pos.z + cb[6]))
-- Check if the entire spawn volume is free
local dx = p2.x - p1.x + 1
local dy = p2.y - p1.y + 1
local dz = p2.z - p1.z + 1
local found_nodes = minetest.find_nodes_in_area(p1,p2,nodes) or 0
local n = #found_nodes
if n == dx * dy * dz then
return true
end
return true
-- If we don't have an implementation of get_node_boxes, we can't check for sub-node space
if not minetest.get_node_boxes then return false end
-- Check if it's possible for a sub-node space check to succeed
local needed_in_bottom_section = dx * ( dy - 1) * dz
if n < needed_in_bottom_section then return false end
-- Make sure the entire volume except for the top level is free before checking the top layer
if dy > 1 then
-- Remove nodes in the top layer from the count
for i = 1,#found_nodes do
if found_nodes[i].y == p2.y then
n = n - 1
end
end
-- If the entire volume except the top layer isn't air (or nodes) then we can't spawn this mob here
if n < needed_in_bottom_section then return false end
end
-- Check the top layer to see if we have enough space to spawn in
local top_layer_height = 1
local processed = {}
for x = p1.x,p2.x do
for z = p1.z,p2.z do
local test_pos = vector.new(x,p2.y,z)
local node = minetest.get_node(test_pos) or { name = "ignore" }
local cache_name = string.format("%s-%d", node.name, node.param2)
if not processed[cache_name] then
-- Calculate node bounding box and select the lowest y value
local boxes = minetest.get_node_boxes("collision_box", test_pos, node)
for i = 1,#boxes do
local box = boxes[i]
local y_test = box[2] + 0.5
if y_test < top_layer_height then top_layer_height = y_test end
local y_test = box[5] + 0.5
if y_test < top_layer_height then top_layer_height = y_test end
end
end
end
end
if top_layer_height + dy - 1 >= cb_height then return true end
-- We don't have room
return false
end
mcl_mobs.custom_biomecheck = nil
@ -732,119 +618,92 @@ function mcl_mobs.register_custom_biomecheck(custom_biomecheck)
mcl_mobs.custom_biomecheck = custom_biomecheck
end
local function get_biome_name(pos)
if mcl_mobs.custom_biomecheck then
return mcl_mobs.custom_biomecheck (pos)
else
local gotten_biome = minetest.get_biome_data(pos)
if not gotten_biome then
return
end
gotten_biome = mt_get_biome_name(gotten_biome.biome)
--minetest.log ("biome: " .. dump(gotten_biome))
return gotten_biome
end
if mcl_mobs.custom_biomecheck then return mcl_mobs.custom_biomecheck(pos) end
local gotten_biome = minetest.get_biome_data(pos)
return gotten_biome and mt_get_biome_name(gotten_biome.biome)
end
local function spawn_check(pos, spawn_def)
if not spawn_def or not pos then return end
dbg_spawn_attempts = dbg_spawn_attempts + 1
local dimension = mcl_worlds.pos_to_dimension(pos)
local mob_def = minetest.registered_entities[spawn_def.name]
local mob_type = mob_def.type
local gotten_node = get_node(pos).name
if not gotten_node then return end
local biome_name = get_biome_name(pos)
if not biome_name then return end
local is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0
if not is_ground then
if spawn_def.dimension ~= dimension then return end -- wrong dimension
-- find ground node below spawn position
local node_name = get_node(pos).name
local node_def = registered_nodes[node_name]
if node_def and not node_def.groups.solid then -- try node one below instead
pos.y = pos.y - 1
gotten_node = get_node(pos).name
is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0
node_name = get_node(pos).name
node_def = registered_nodes[node_name]
end
if not node_def or not node_def.groups then return end
-- do not spawn on bedrock
if node_name == "mcl_core:bedrock" then return end
pos.y = pos.y + 1
local is_water = get_item_group(gotten_node, "water") ~= 0
local is_lava = get_item_group(gotten_node, "lava") ~= 0
local is_leaf = get_item_group(gotten_node, "leaves") ~= 0
local is_bedrock = gotten_node == "mcl_core:bedrock"
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
-- check spawn height
if pos.y < spawn_def.min_height or pos.y > spawn_def.max_height then return end
mcl_log("spawn_check#1 position checks passed")
if pos.y >= spawn_def.min_height
and pos.y <= spawn_def.max_height
and spawn_def.dimension == dimension
and biome_check(spawn_def.biomes, biome_name) then
-- do not spawn ground mobs on leaves
if spawn_def.type_of_spawning == "ground" and (not node_def.groups.solid or node_def.groups.leaves) then return end
-- water mobs only on water
if spawn_def.type_of_spawning == "water" and not node_def.groups.water then return end
-- lava mobs only on lava
if spawn_def.type_of_spawning == "lava" and not node_def.groups.lava then return end
-- farm animals on grass only
if is_farm_animal(spawn_def.name) and not node_def.groups.grass_block then return end
mcl_log("Spawn level 1 check - Passed")
if (is_ground or spawn_def.type_of_spawning ~= "ground")
and (spawn_def.type_of_spawning ~= "ground" or not is_leaf)
and (not is_farm_animal(spawn_def.name) or is_grass)
and (spawn_def.type_of_spawning ~= "water" or is_water)
and not is_bedrock
and has_room(mob_def,pos)
and (spawn_def.check_position and spawn_def.check_position(pos) or spawn_def.check_position == nil)
and ( not spawn_protected or not minetest.is_protected(pos, "") ) then
---- More expensive calls:
-- check the biome
if spawn_def.biomes and not biome_check(spawn_def.biomes, get_biome_name(pos)) then return end
-- check if there is enough room
local mob_def = minetest.registered_entities[spawn_def.name]
if not has_room(mob_def,pos) then return end
-- additional checks (slime etc.)
if spawn_def.check_position and not spawn_def.check_position(pos) then return end
if spawn_protected and minetest.is_protected(pos, "") then return end
mcl_log("spawn_check#2 advanced checks passed")
mcl_log("Spawn level 2 check - Passed")
local gotten_light = get_node_light(pos)
-- check light thresholds
local gotten_light = get_node_light(pos)
-- old lighting
if not modern_lighting then return gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light end
if modern_lighting then
local my_node = get_node(pos)
local sky_light = minetest.get_natural_light(pos)
local art_light = minetest.get_artificial_light(my_node.param1)
if mob_def.spawn_check then
return mob_def.spawn_check(pos, gotten_light, art_light, sky_light)
elseif mob_type == "monster" then
if dimension == "nether" then
if art_light <= nether_threshold then
return true
end
elseif dimension == "end" then
if art_light <= end_threshold then
return true
end
elseif dimension == "overworld" then
if art_light <= overworld_threshold and sky_light <= overworld_sky_threshold then
return true
end
end
else
-- passive threshold is apparently the same in all dimensions ...
if gotten_light > overworld_passive_threshold then
return true
end
end
else
if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then
return true
end
local sky_light = minetest.get_natural_light(pos)
local art_light = minetest.get_artificial_light(get_node(pos).param1)
if mob_def.spawn_check then
return mob_def.spawn_check(pos, gotten_light, art_light, sky_light)
end
if mob_def.type == "monster" then
if dimension == "nether" then
if art_light <= nether_threshold then
return true
end
elseif dimension == "end" then
if art_light <= end_threshold then
return true
end
elseif dimension == "overworld" then
if art_light <= overworld_threshold and sky_light <= overworld_sky_threshold then
return true
end
end
return false
end
return false
-- passive threshold is apparently the same in all dimensions ...
return gotten_light > overworld_passive_threshold
end
function mcl_mobs.spawn(pos,id)
if not pos or not id then return false end
local def = minetest.registered_entities[id] or minetest.registered_entities["mobs_mc:"..id] or minetest.registered_entities["extra_mobs:"..id]
if not def or (def.can_spawn and not def.can_spawn(pos)) or not def.is_mob then
return false
end
if not dbg_spawn_counts[def.name] then
dbg_spawn_counts[def.name] = 1
else
dbg_spawn_counts[def.name] = dbg_spawn_counts[def.name] + 1
end
if not def or not def.is_mob or (def.can_spawn and not def.can_spawn(pos)) then return false end
if not has_room(def, pos) then return false end
return minetest.add_entity(pos, def.name)
end
local function spawn_group(p,mob,spawn_on,amount_to_spawn)
local nn= minetest.find_nodes_in_area_under_air(vector.offset(p,-5,-3,-5),vector.offset(p,5,3,5),spawn_on)
local o
@ -1238,7 +1097,6 @@ end
minetest.register_chatcommand("mobstats",{
privs = { debug = true },
func = function(n,param)
--minetest.chat_send_player(n,dump(dbg_spawn_counts))
local pos = minetest.get_player_by_name(n):get_pos()
minetest.chat_send_player(n,"mobs: within 32 radius of player/total loaded :"..count_mobs(pos,MOB_CAP_INNER_RADIUS) .. "/" .. count_mobs_total())
minetest.chat_send_player(n,"spawning attempts since server start:" .. dbg_spawn_succ .. "/" .. dbg_spawn_attempts)

View File

@ -72,18 +72,24 @@ local axolotl = {
fly = true,
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
breathes_in_water = true,
jump = true,
jump = false, -- would get them out of the water too often
damage = 2,
reach = 2,
attack_type = "dogfight",
attack_animals = true,
specific_attack = {
"extra_mobs_cod",
"extra_mobs_glow_squid",
"extra_mobs_salmon",
"extra_mobs_tropical_fish",
"mobs_mc_squid"
},
"mobs_mc:cod",
"mobs_mc:glow_squid",
"mobs_mc:salmon",
"mobs_mc:tropical_fish",
"mobs_mc:squid",
"mobs_mc:zombie", -- todo: only drowned?
"mobs_mc:baby_zombie",
"mobs_mc:husk",
"mobs_mc:baby_husk",
"mobs_mc:guardian_elder",
"mobs_mc:guardian",
},
runaway = true,
}

View File

@ -1,5 +1,5 @@
name = mobs_mc
author = maikerumine
description = Adds Minecraft-like monsters and animals.
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core, mcl_util
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core, mcl_util, mcl_entity_invs
optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, doc_items, mcl_worlds

View File

@ -103,6 +103,7 @@ local skeleton = {
return true
end,
ignited_by_sunlight = true,
floats = 0,
view_range = 16,
fear_height = 4,
attack_type = "dogshoot",

View File

@ -94,6 +94,7 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", {
dogshoot_switch = 1,
dogshoot_count_max =0.5,
fear_height = 4,
floats = 0,
harmed_by_heal = true,
fire_resistant = true,
dealt_effect = {

View File

@ -1,112 +1,31 @@
--License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc")
local MAPBLOCK_SIZE = 16
local seed = minetest.get_mapgen_setting("seed")
local slime_chunk_match
local MAPBLOCK_SIZE = 16 -- size for slime chunk logic
local SEED_OFFSET = 362 -- module specific seed
local world_seed = (minetest.get_mapgen_setting("seed") + SEED_OFFSET) % 4294967296
-- slime density, where default N=10 is every 10th chunk
local slime_ratio = tonumber(minetest.settings:get("slime_ratio")) or 10
-- use 3D chunking instead of 2d chunks
local slime_3d_chunks = minetest.settings:get_bool("slime_3d_chunks", false)
-- maximum light level, for slimes in caves only, not magma/swamps
local slime_max_light = (tonumber(minetest.settings:get("slime_max_light")) or minetest.LIGHT_MAX) + 1
-- maximum light level for swamp spawning
local swamp_light_max = 7
-- maximum height to spawn in slime chunks
local slime_chunk_spawn_max = mcl_worlds.layer_to_y(40)
local x_modifier
local z_modifier
local function split_by_char (inputstr, sep, limit)
if sep == nil then
sep = "%d"
end
local t = {}
local i = 0
for str in string.gmatch(inputstr, "(["..sep.."])") do
i = i --+ 1
table.insert(t, tonumber(str))
if limit and i >= limit then
break
end
end
return t
end
--Seed: "16002933932875202103" == random seed
--Seed: "1807191622654296300" == cheese
--Seed: "1" = 1
local function process_seed (seed)
--minetest.log("seed: " .. seed)
local split_chars = split_by_char(tostring(seed), nil, 10)
slime_chunk_match = split_chars[1]
x_modifier = split_chars[2]
z_modifier = split_chars[3]
--minetest.log("x_modifier: " .. tostring(x_modifier))
--minetest.log("z_modifier: " .. tostring(z_modifier))
--minetest.log("slime_chunk_match: " .. tostring(slime_chunk_match))
end
local processed = process_seed (seed)
local function convert_to_chunk_value (co_ord, modifier)
local converted = math.floor(math.abs(co_ord) / MAPBLOCK_SIZE)
if modifier then
converted = (converted + modifier)
end
converted = converted % 10
--minetest.log("co_ord: " .. co_ord)
--minetest.log("converted: " .. converted)
return converted
end
assert(convert_to_chunk_value(-16) == 1, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(-15) == 0, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(-1) == 0, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(0) == 0, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(1) == 0, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(15) == 0, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(16) == 1, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(31) == 1, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(32) == 2, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(1599) == 9, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(1600) == 0, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(0,9) == 9, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(16,5) == 6, "Incorrect convert_to_chunk_value result")
assert(convert_to_chunk_value(1599,4) == 3, "Incorrect convert_to_chunk_value result")
local function calculate_chunk_value (pos, x_mod, z_mod)
local chunk_val = math.abs(convert_to_chunk_value(pos.x, x_mod) - convert_to_chunk_value(pos.z, z_mod)) % 10
return chunk_val
end
assert(calculate_chunk_value(vector.new(0,0,0)) == 0, "calculate_chunk_value failed")
assert(calculate_chunk_value(vector.new(0,0,0), 1, 1) == 0, "calculate_chunk_value failed")
assert(calculate_chunk_value(vector.new(0,0,0), 2, 1) == 1, "calculate_chunk_value failed")
assert(calculate_chunk_value(vector.new(64,0,16)) == (4-1), "calculate_chunk_value failed")
assert(calculate_chunk_value(vector.new(16,0,64)) == (3), "calculate_chunk_value failed")
assert(calculate_chunk_value(vector.new(-160,0,-160)) == 0, "calculate_chunk_value failed")
local floor = math.floor
local max = math.max
local function is_slime_chunk(pos)
if not pos then return end
local chunk_val = calculate_chunk_value (pos, x_modifier, z_modifier)
local slime_chunk = chunk_val == slime_chunk_match
--minetest.log("x: " ..pos.x .. ", z:" .. pos.z)
--minetest.log("seed slime_chunk_match: " .. tostring(slime_chunk_match))
--minetest.log("chunk_val: " .. tostring(chunk_val))
--minetest.log("Is slime chunk: " .. tostring(slime_chunk))
return slime_chunk
if not pos then return end -- no position given
if slime_ratio == 0 then return end -- no slime chunks
if slime_ratio <= 1 then return true end -- slime everywhere
local bpos = vector.new(floor(pos.x / MAPBLOCK_SIZE), slime_3d_chunks and floor(pos.y / MAPBLOCK_SIZE) or 0, floor(pos.z / MAPBLOCK_SIZE))
return PcgRandom(minetest.hash_node_position(bpos) + world_seed):next(0,1e9)/1e9 * slime_ratio < 1
end
local check_position = function (pos)
return is_slime_chunk(pos)
end
-- Returns a function that spawns children in a circle around pos.
-- To be used as on_die callback.
-- self: mob reference
@ -116,19 +35,15 @@ end
-- eject_speed: Initial speed of child mob away from "mother" mob
local spawn_children_on_die = function(child_mob, spawn_distance, eject_speed)
return function(self, pos)
local posadd, newpos, dir
if not eject_speed then
eject_speed = 1
end
eject_speed = eject_speed or 1
local mndef = minetest.registered_nodes[minetest.get_node(pos).name]
local mother_stuck = mndef and mndef.walkable
local angle = math.random() * math.pi * 2
local children = {}
local spawn_count = math.random(2, 4)
for i = 1, spawn_count do
dir = vector.new(math.cos(angle), 0, math.sin(angle))
posadd = vector.normalize(dir) * spawn_distance
newpos = pos + posadd
local dir = vector.new(math.cos(angle), 0, math.sin(angle))
local newpos = pos + dir * spawn_distance
-- If child would end up in a wall, use position of the "mother", unless
-- the "mother" was stuck as well
if not mother_stuck then
@ -138,12 +53,14 @@ local spawn_children_on_die = function(child_mob, spawn_distance, eject_speed)
eject_speed = eject_speed * 0.5
end
end
local mob = minetest.add_entity(newpos, child_mob)
if not mother_stuck then
mob:set_velocity(dir * eject_speed)
local mob = mcl_mobs.spawn(newpos, child_mob)
if mob then
if not mother_stuck then
mob:set_velocity(dir * eject_speed)
end
mob:set_yaw(angle - math.pi/2)
table.insert(children, mob)
end
mob:set_yaw(angle - math.pi/2)
table.insert(children, mob)
angle = angle + (math.pi*2) / spawn_count
end
-- If mother was murdered, children attack the killer after 1 second
@ -162,16 +79,12 @@ local spawn_children_on_die = function(child_mob, spawn_distance, eject_speed)
end
end
local swamp_light_max = 7
-- two different rules, underground slime chunks and regular swamp spawning
local function slime_spawn_check(pos, environmental_light, artificial_light, sky_light)
local maxlight = swamp_light_max
if pos.y <= slime_chunk_spawn_max and is_slime_chunk(pos) then
maxlight = minetest.LIGHT_MAX + 1
return max(artificial_light, sky_light) <= slime_max_light
end
return math.max(artificial_light, sky_light) <= maxlight
return max(artificial_light, sky_light) <= swamp_light_max
end
-- Slime
@ -322,13 +235,13 @@ mcl_mobs:spawn_specific(
"ground",
cave_biomes,
0,
minetest.LIGHT_MAX+1,
slime_max_light,
30,
1000,
4,
cave_min,
cave_max,
nil, nil, check_position)
nil, nil, is_slime_chunk)
mcl_mobs:spawn_specific(
"mobs_mc:slime_tiny",
@ -349,13 +262,13 @@ mcl_mobs:spawn_specific(
"ground",
cave_biomes,
0,
minetest.LIGHT_MAX+1,
slime_max_light,
30,
1000,
4,
cave_min,
cave_max,
nil, nil, check_position)
nil, nil, is_slime_chunk)
mcl_mobs:spawn_specific(
"mobs_mc:slime_small",
@ -376,13 +289,13 @@ mcl_mobs:spawn_specific(
"ground",
cave_biomes,
0,
minetest.LIGHT_MAX+1,
slime_max_light,
30,
1000,
4,
cave_min,
cave_max,
nil, nil, check_position)
nil, nil, is_slime_chunk)
mcl_mobs:spawn_specific(
"mobs_mc:slime_big",
@ -559,3 +472,4 @@ mcl_mobs:non_spawn_specific("mobs_mc:magma_cube_big","overworld",0, minetest.LIG
mcl_mobs.register_egg("mobs_mc:slime_big", S("Slime"), "#52a03e", "#7ebf6d")
-- FIXME: add spawn eggs for small and tiny slimes and magma cubes

View File

@ -67,6 +67,7 @@ local spider = {
curiosity = 10,
head_yaw="z",
collisionbox = {-0.7, -0.01, -0.7, 0.7, 0.89, 0.7},
spawnbox = {-1.2, -0.01, -1.2, 1.2, 0.89, 1.2},
visual = "mesh",
mesh = "mobs_mc_spider.b3d",
textures = {

View File

@ -7,12 +7,13 @@ local S = minetest.get_translator("mobs_mc")
--###################
local function get_texture(self)
local on_name = self.standing_on
local function get_texture(self, prev)
local standing_on = minetest.registered_nodes[self.standing_on]
-- TODO: we do not have access to param2 here (color palette index) yet
local texture
local texture_suff = ""
if on_name and on_name ~= "air" then
local tiles = minetest.registered_nodes[on_name].tiles
if standing_on and (standing_on.walkable or standing_on.groups.liquid) then
local tiles = standing_on.tiles
if tiles then
local tile = tiles[1]
local color
@ -25,7 +26,7 @@ local function get_texture(self)
texture = tile
end
if not color then
color = minetest.colorspec_to_colorstring(minetest.registered_nodes[on_name].color)
color = minetest.colorspec_to_colorstring(standing_on.color)
end
if color then
texture_suff = "^[multiply:" .. color .. "^[hsl:0:0:20"
@ -33,14 +34,19 @@ local function get_texture(self)
end
end
if not texture or texture == "" then
-- try to keep last texture when, e.g., falling
if prev and (not (not self.attack)) == (string.find(prev, "vl_mobs_stalker_overlay_angry.png") ~= nil) then
return prev
end
texture = "vl_stalker_default.png"
end
texture = texture:gsub("([\\^:\\[])","\\%1") -- escape texture modifiers
texture = "([combine:16x24:0,0=(" .. texture .. "):0,16=(" .. texture ..")".. texture_suff
if self.attack then
texture = texture .. ")^vl_mobs_stalker_overlay_angry.png"
else
texture = texture .. ")^vl_mobs_stalker_overlay.png"
texture = texture:gsub("([\\^:\\[])", "\\%1") -- escape texture modifiers
texture = "(vl_stalker_default.png^[combine:16x24:0,0=(" .. texture .. "):0,16=(" .. texture .. ")" .. texture_suff .. ")"
end
if self.attack then
texture = texture .. "^vl_mobs_stalker_overlay_angry.png"
else
texture = texture .. "^vl_mobs_stalker_overlay.png"
end
return texture
end
@ -132,7 +138,7 @@ mcl_mobs.register_mob("mobs_mc:stalker", {
self:boom(mcl_util.get_object_center(self.object), self.explosion_strength)
end
end
local new_texture = get_texture(self)
local new_texture = get_texture(self, self._stalker_texture)
if self._stalker_texture ~= new_texture then
self.object:set_properties({textures={new_texture, "mobs_mc_empty.png"}})
self._stalker_texture = new_texture

View File

@ -818,7 +818,7 @@ local function find_closest_bed (self)
if (owned_by and owned_by == self._id) then
mcl_log("Clear as already owned by me.")
bed_meta:set_string("villager", nil)
bed_meta:set_string("villager", "")
owned_by = nil
end
@ -1049,14 +1049,18 @@ local function has_summon_participants(self)
end
local function summon_golem(self)
vector.offset(self.object:get_pos(),-10,-10,-10)
local nn = minetest.find_nodes_in_area_under_air(vector.offset(self.object:get_pos(),-10,-10,-10),vector.offset(self.object:get_pos(),10,10,10),{"group:solid","group:water"})
table.shuffle(nn)
for _,n in pairs(nn) do
local up = minetest.find_nodes_in_area(vector.offset(n,0,1,0),vector.offset(n,0,3,0),{"air"})
if up and #up >= 3 then
local pos = self.object:get_pos()
local p1 = vector.offset(pos, -10, -10, -10)
local p2 = vector.offset(pos, 10, 10, 10)
local nn = minetest.find_nodes_in_area_under_air(p1, p2,{"group:solid","group:water"})
while #nn > 0 do
local n = table.remove_random_element(nn)
n.y = n.y + 1
local summon = mcl_mobs.spawn(n, "mobs_mc:iron_golem")
if summon then
minetest.sound_play("mcl_portals_open_end_portal", {pos=n, gain=0.5, max_hear_distance = 16}, true)
return minetest.add_entity(vector.offset(n,0,1,0),"mobs_mc:iron_golem")
return summon
end
end
end
@ -1279,7 +1283,7 @@ local function validate_jobsite(self)
mcl_log("Jobsite far, so resettle: " .. tostring(resettle))
if resettle then
local m = minetest.get_meta(self._jobsite)
m:set_string("villager", nil)
m:set_string("villager", "")
remove_job (self)
return false
end
@ -1421,7 +1425,7 @@ local function validate_bed(self)
mcl_log("Bed far, so resettle: " .. tostring(resettle))
if resettle then
mcl_log("Resettled. Ditch bed.")
m:set_string("villager", nil)
m:set_string("villager", "")
self._bed = nil
bed_valid = false
return false
@ -1431,7 +1435,7 @@ local function validate_bed(self)
mcl_log("Player owner: " .. owned_by_player)
if owned_by_player ~= "" then
mcl_log("Player owns this. Villager won't take this.")
m:set_string("villager", nil)
m:set_string("villager", "")
self._bed = nil
bed_valid = false
return false
@ -2300,13 +2304,13 @@ mcl_mobs.register_mob("mobs_mc:villager", {
local bed = self._bed
if bed then
local bed_meta = minetest.get_meta(bed)
bed_meta:set_string("villager", nil)
bed_meta:set_string("villager", "")
mcl_log("Died, so bye bye bed")
end
local jobsite = self._jobsite
if jobsite then
local jobsite_meta = minetest.get_meta(jobsite)
jobsite_meta:set_string("villager", nil)
jobsite_meta:set_string("villager", "")
mcl_log("Died, so bye bye jobsite")
end

View File

@ -55,14 +55,16 @@ mcl_mobs.register_mob("mobs_mc:evoker", {
basepos.y = basepos.y + 1
for i=1, r do
local spawnpos = vector.add(basepos, minetest.yaw_to_dir(pr:next(0,360)))
local vex = minetest.add_entity(spawnpos, "mobs_mc:vex")
local ent = vex:get_luaentity()
local vex = mcl_mobs.spawn(spawnpos, "mobs_mc:vex")
if vex then
local ent = vex:get_luaentity()
-- Mark vexes as summoned and start their life clock (they take damage it reaches 0)
ent._summoned = true
ent._lifetimer = pr:next(33, 108)
-- Mark vexes as summoned and start their life clock (they take damage it reaches 0)
ent._summoned = true
ent._lifetimer = pr:next(33, 108)
table.insert(spawned_vexes[self],ent)
table.insert(spawned_vexes[self],ent)
end
end
end,
passive = false,

View File

@ -134,6 +134,7 @@ mcl_mobs.register_mob("mobs_mc:villager_zombie", {
end,
sunlight_damage = 2,
ignited_by_sunlight = true,
floats = 0,
view_range = 16,
fear_height = 4,
harmed_by_heal = true,

View File

@ -96,6 +96,7 @@ local zombie = {
},
ignited_by_sunlight = true,
sunlight_damage = 2,
floats = 0,
view_range = 16,
attack_type = "dogfight",
harmed_by_heal = true,

View File

@ -19,7 +19,6 @@ local set_node = minetest.set_node
local sound_play = minetest.sound_play
local add_particlespawner = minetest.add_particlespawner
local after = minetest.after
local add_entity = minetest.add_entity
local get_objects_inside_radius = minetest.get_objects_inside_radius
local get_item_group = minetest.get_item_group
@ -165,7 +164,7 @@ function lightning.strike_func(pos, pos2, objects)
-- Events caused by the lightning strike: Fire, damage, mob transformations, rare skeleton spawn
pos2.y = pos2.y + 1/2
pos2.y = pos2.y + 1
local skeleton_lightning = false
if rng:next(1,100) <= 3 then
skeleton_lightning = true
@ -174,14 +173,14 @@ function lightning.strike_func(pos, pos2, objects)
if get_node(pos2).name == "air" then
-- Low chance for a lightning to spawn skeleton horse + skeletons
if skeleton_lightning then
add_entity(pos2, "mobs_mc:skeleton_horse")
mcl_mobs.spawn(pos2, "mobs_mc:skeleton_horse")
local angle, posadd
angle = math.random() * math.pi * 2
for i=1,3 do
posadd = { x=math.cos(angle),y=0,z=math.sin(angle) }
posadd = vector.normalize(posadd)
local mob = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton")
local mob = mcl_mobs.spawn(vector.add(pos2, posadd), "mobs_mc:skeleton")
if mob then
mob:set_yaw(angle-math.pi/2)
end

View File

@ -1,4 +1,4 @@
name = mcl_void_damage
author = Wuzzy
description = Deal damage to entities stuck in the deep void
depends = mcl_worlds
depends = mcl_worlds, mcl_spawn

View File

@ -60,13 +60,15 @@ end
-- set skybox based on time (uses skycolor api)
function mcl_weather.rain.set_sky_box()
if mcl_weather.state == "rain" then
mcl_weather.skycolor.add_layer(
"weather-pack-rain-sky",
{{r=0, g=0, b=0},
{r=85, g=86, b=98},
{r=135, g=135, b=151},
{r=85, g=86, b=98},
{r=0, g=0, b=0}})
if mcl_weather.skycolor.current_layer_name() ~= "weather-pack-rain-sky" then
mcl_weather.skycolor.add_layer(
"weather-pack-rain-sky",
{{r=0, g=0, b=0},
{r=85, g=86, b=98},
{r=135, g=135, b=151},
{r=85, g=86, b=98},
{r=0, g=0, b=0}})
end
mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#5D5D5FE8"})
@ -155,6 +157,7 @@ function mcl_weather.rain.clear()
mcl_weather.rain.remove_sound(player)
mcl_weather.rain.remove_player(player)
mcl_weather.remove_spawners_player(player)
player:set_clouds({color="#FFF0EF"})
end
end

View File

@ -2,6 +2,7 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local NIGHT_VISION_RATIO = 0.45
local DEBUG = false
-- Settings
local minimum_update_interval = { 250e3 }
@ -190,8 +191,8 @@ end
function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
-- Clamp current_val to valid range
current_val = math.min(minval, current_val)
current_val = math.max(maxval, current_val)
current_val = math.max(minval, current_val)
current_val = math.min(maxval, current_val)
-- Rescale current_val from a number between minval and maxval to a number between 1 and #colors
local scaled_value = (current_val - minval) / (maxval - minval) * (#colors - 1) + 1.0
@ -199,7 +200,7 @@ function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
-- Get the first color's values
local index1 = math.floor(scaled_value)
local color1 = colors[index1]
local frac1 = scaled_value - index1
local frac1 = 1.0 - (scaled_value - index1)
-- Get the second color's values
local index2 = math.min(index1 + 1, #colors) -- clamp to maximum color index (will occur if index1 == #colors)
@ -207,11 +208,32 @@ function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
local color2 = colors[index2]
-- Interpolate between color1 and color2
return {
local res = {
r = math.floor(frac1 * color1.r + frac2 * color2.r),
g = math.floor(frac1 * color1.g + frac2 * color2.g),
b = math.floor(frac1 * color1.b + frac2 * color2.b),
}
if DEBUG then
minetest.log(dump({
minval = minval,
maxval = maxval,
current_val = current_val,
colors = colors,
res = res,
scaled_value = scaled_value,
frac1 = frac1,
index1 = index1,
color1 = color1,
frac2 = frac2,
index2 = index2,
color2 = color2,
}))
end
return res
end
-- Simple getter. Either returns user given players list or get all connected players if none provided

View File

@ -40,18 +40,21 @@ function dimension_handlers.overworld(player, sky_data)
end
-- Use overworld defaults
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.15)
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27)
local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1)
sky_data.sky = {
type = "regular",
sky_color = {
day_sky = day_color,
day_horizon = day_color,
dawn_sky = dawn_color,
dawn_horizon = dawn_color,
night_sky = night_color,
night_horizon = night_color,
day_sky = day_color or "#7BA4FF",
day_horizon = day_color or "#C0D8FF",
dawn_sky = dawn_color or "7BA4FF",
dawn_horizon = dawn_color or "#C0D8FF",
night_sky = night_color or "000000",
night_horizon = night_color or "4A6790",
fog_sun_tint = "#ff5f33",
fog_moon_tint = nil,
fog_tint_type = "custom",
},
clouds = true,
}
@ -75,18 +78,15 @@ function dimension_handlers.overworld(player, sky_data)
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75)
local night_color = mcl_weather.skycolor.get_sky_layer_color(0)
sky_data.sky = {
type = "regular",
sky_color = {
day_sky = day_color,
day_horizon = day_color,
dawn_sky = dawn_color,
dawn_horizon = dawn_color,
night_sky = night_color,
night_horizon = night_color,
},
clouds = true,
}
table.update(sky_data.sky.sky_color,{
day_sky = day_color or "#7BA4FF",
day_horizon = day_color or "#C0D8FF",
dawn_sky = dawn_color or "7BA4FF",
dawn_horizon = dawn_color or "#C0D8FF",
night_sky = night_color or "000000",
night_horizon = night_color or "4A6790",
fog_tint_type = "default",
})
sky_data.sun = {visible = false, sunrise_visible = false}
sky_data.moon = {visible = false}
sky_data.stars = {visible = false}
@ -164,7 +164,8 @@ function dimension_handlers.nether(player, sky_data)
end
function dimension_handlers.void(player, sky_data)
sky_data.sky = { type = "plain",
sky_data.sky = {
type = "plain",
base_color = "#000000",
clouds = false,
}

View File

@ -75,13 +75,15 @@ function mcl_weather.has_snow(pos)
end
function mcl_weather.snow.set_sky_box()
mcl_weather.skycolor.add_layer(
"weather-pack-snow-sky",
{{r=0, g=0, b=0},
{r=85, g=86, b=86},
{r=135, g=135, b=135},
{r=85, g=86, b=86},
{r=0, g=0, b=0}})
if mcl_weather.skycolor.current_layer_name() ~= "weather-pack-snow-sky" then
mcl_weather.skycolor.add_layer(
"weather-pack-snow-sky",
{{r=0, g=0, b=0},
{r=85, g=86, b=86},
{r=135, g=135, b=135},
{r=85, g=86, b=86},
{r=0, g=0, b=0}})
end
mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#ADADADE8"})

View File

@ -23,13 +23,15 @@ minetest.register_globalstep(function(dtime)
mcl_weather.rain.make_weather()
if mcl_weather.thunder.init_done == false then
mcl_weather.skycolor.add_layer("weather-pack-thunder-sky", {
{r=0, g=0, b=0},
{r=40, g=40, b=40},
{r=85, g=86, b=86},
{r=40, g=40, b=40},
{r=0, g=0, b=0},
})
if mcl_weather.skycolor.current_layer_name() ~= "weather-pack-thunder-sky" then
mcl_weather.skycolor.add_layer("weather-pack-thunder-sky", {
{r=0, g=0, b=0},
{r=40, g=40, b=40},
{r=85, g=86, b=86},
{r=40, g=40, b=40},
{r=0, g=0, b=0},
})
end
mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#3D3D3FE8"})

View File

@ -1,4 +1,4 @@
name = mcl_death_messages
author = 4Evergreen4
description = Shows messages in chat when a player dies.
depends = mcl_colors
depends = mcl_colors, mcl_damage

View File

@ -1,8 +1,10 @@
## mcl_info
An api to make custom entries in the mcl2 debug hud.
An API to make custom entries in the VL debug hud.
### mcl_info.register_debug_field(name,defintion)
Debug field defintion example:
```
{
level = 3,
--show with debug level 3 and upwards
@ -13,6 +15,7 @@ Debug field defintion example:
-- It should output a string and determines
-- the content of the debug field.
}
```
### mcl_info.registered_debug_fields
Table the debug definitions are stored in. Do not modify this directly. If you need to overwrite a field just set it again with mcl_info.register_debug_field().

View File

@ -32,4 +32,5 @@ mcl_inventory.register_survival_inventory_tab({
-- Returns true by default
access = function(player)
end,
})
```

View File

@ -418,6 +418,18 @@ minetest.register_on_joinplayer(function(player)
end
end)
---@param player mt.PlayerObjectRef
local function is_touch_enabled(playername)
-- Minetest < 5.7.0 support
if not minetest.get_player_window_information then
return false
end
local window = minetest.get_player_window_information(playername)
-- Always return a boolean (not nil) to avoid false-negatives when
-- comparing to a boolean later.
return window and window.touch_controls or false
end
---@param player mt.PlayerObjectRef
function mcl_inventory.set_creative_formspec(player)
local playername = player:get_player_name()
@ -566,8 +578,10 @@ function mcl_inventory.set_creative_formspec(player)
bg_img = "crafting_creative_inactive" .. button_bg_postfix[this_tab] .. ".png"
end
return table.concat({
"style[" .. this_tab .. ";border=false;bgimg=;bgimg_pressed=;noclip=true]",
"image[" .. offset[this_tab] .. ";1.5,1.44;" .. bg_img .. "]",
"style[" .. this_tab .. ";border=false;bgimg=;bgimg_pressed=]",
"style[" .. this_tab .. "_outer;border=false;bgimg=" .. bg_img ..
";bgimg_pressed=" .. bg_img .. "]",
"button[" .. offset[this_tab] .. ";1.5,1.44;" .. this_tab .. "_outer;]",
"item_image_button[" .. boffset[this_tab] .. ";1,1;" .. tab_icon[this_tab] .. ";" .. this_tab .. ";]",
})
end
@ -577,11 +591,21 @@ function mcl_inventory.set_creative_formspec(player)
caption = "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, filtername[name])) .. "]"
end
local touch_enabled = is_touch_enabled(playername)
players[playername].last_touch_enabled = touch_enabled
local formspec = table.concat({
"formspec_version[6]",
"size[13,8.75]",
-- Original formspec height was 8.75, increased to include tab buttons.
-- This avoids tab buttons going off-screen with high scaling values.
"size[13,11.43]",
-- Use as much space as possible on mobile - the tab buttons are a lot
-- of padding already.
touch_enabled and "padding[-0.015,-0.015]" or "",
"style_type[image;noclip=true]",
"no_prepend[]", mcl_vars.gui_nonbg, mcl_vars.gui_bg_color,
"background9[0,1.34;13,8.75;mcl_base_textures_background9.png;;7]",
"container[0,1.34]",
-- Hotbar
mcl_formspec.get_itemslot_bg_v4(0.375, 7.375, 9, 1),
@ -638,6 +662,7 @@ function mcl_inventory.set_creative_formspec(player)
"set_focus[search;true]",
})
end
formspec = formspec .. "container_end[]"
if pagenum then formspec = formspec .. "p" .. tostring(pagenum) end
player:set_inventory_formspec(formspec)
end
@ -655,54 +680,54 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
local name = player:get_player_name()
if fields.blocks then
if fields.blocks or fields.blocks_outer then
if players[name].page == "blocks" then return end
set_inv_page("blocks", player)
page = "blocks"
elseif fields.deco then
elseif fields.deco or fields.deco_outer then
if players[name].page == "deco" then return end
set_inv_page("deco", player)
page = "deco"
elseif fields.redstone then
elseif fields.redstone or fields.redstone_outer then
if players[name].page == "redstone" then return end
set_inv_page("redstone", player)
page = "redstone"
elseif fields.rail then
elseif fields.rail or fields.rail_outer then
if players[name].page == "rail" then return end
set_inv_page("rail", player)
page = "rail"
elseif fields.misc then
elseif fields.misc or fields.misc_outer then
if players[name].page == "misc" then return end
set_inv_page("misc", player)
page = "misc"
elseif fields.nix then
elseif fields.nix or fields.nix_outer then
set_inv_page("all", player)
page = "nix"
elseif fields.food then
elseif fields.food or fields.food_outer then
if players[name].page == "food" then return end
set_inv_page("food", player)
page = "food"
elseif fields.tools then
elseif fields.tools or fields.tools_outer then
if players[name].page == "tools" then return end
set_inv_page("tools", player)
page = "tools"
elseif fields.combat then
elseif fields.combat or fields.combat_outer then
if players[name].page == "combat" then return end
set_inv_page("combat", player)
page = "combat"
elseif fields.mobs then
elseif fields.mobs or fields.mobs_outer then
if players[name].page == "mobs" then return end
set_inv_page("mobs", player)
page = "mobs"
elseif fields.brew then
elseif fields.brew or fields.brew_outer then
if players[name].page == "brew" then return end
set_inv_page("brew", player)
page = "brew"
elseif fields.matr then
elseif fields.matr or fields.matr_outer then
if players[name].page == "matr" then return end
set_inv_page("matr", player)
page = "matr"
elseif fields.inv then
elseif fields.inv or fields.inv_outer then
if players[name].page == "inv" then return end
page = "inv"
elseif fields.search == "" and not fields.creative_next and not fields.creative_prev then
@ -818,3 +843,19 @@ minetest.register_on_player_inventory_action(function(player, action, inventory,
player:get_inventory():set_stack("main", inventory_info.index, stack)
end
end)
-- This is necessary because get_player_window_information may return nil in
-- on_joinplayer.
-- (Also, Minetest plans to add support for toggling touchscreen mode in-game.)
minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
if minetest.is_creative_enabled(name) then
local touch_enabled = is_touch_enabled(name)
if touch_enabled ~= players[name].last_touch_enabled then
mcl_inventory.set_creative_formspec(player)
end
end
end
end)

View File

@ -8,7 +8,7 @@ Show a hud message of `type` to player `player` with `data` as params.
The element will stay for the per-player param `stay` or `data.stay` (in gametick which is 1/20 second).
Here is a usage exemple:
Here is a usage example:
```lua
--show a title in the HUD with minecraft color "gold"
@ -35,7 +35,7 @@ Basicaly run `mcl_title.remove(player, type)` for every type.
## mcl_title.params_set(player, params)
Allow mods to set `stay` and upcomming `fadeIn`/`fadeOut` params.
Allow mods to set `stay` and upcoming `fadeIn`/`fadeOut` params.
```lua
mcl_title.params_set(player, {stay = 600}) --elements with no 'data.stay' field will stay during 30s (600/20)
@ -43,8 +43,8 @@ mcl_title.params_set(player, {stay = 600}) --elements with no 'data.stay' field
## mcl_title.params_get(player)
Get `stay` and upcomming `fadeIn` and `fadeOut` params of a player as a table.
Get `stay` and upcoming `fadeIn` and `fadeOut` params of a player as a table.
```lua
mcl_title.params_get(player)
```
```

View File

@ -1,4 +1,4 @@
name = mcl_title
description = Add an API to add in HUD title
depends = mcl_colors
description = Add an API to add in HUD title
depends = mcl_colors, mcl_util
author = AFCMS

View File

@ -1,3 +1,3 @@
name = mesecons_button
depends = mesecons
depends = mesecons, mesecons_mvps
optional_depends = doc

View File

@ -119,7 +119,7 @@ mcl_armor.register_set({
end,
},
--this is used to generate automaticaly armor crafts based on each element type folowing the regular minecraft pattern
--this is used to generate automaticaly armor crafts based on each element type following the regular minecraft pattern
--if set to nil no craft will be added
craft_material = "mcl_mobitems:leather",

View File

@ -5,9 +5,6 @@
--- Copyright (C) 2022 - 2023, Michieal. See License.txt
-- CONSTS
local DOUBLE_DROP_CHANCE = 8
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
-- "BAMBOO" goes here.
local BAMBOO = "mcl_bamboo:bamboo"
local BAMBOO_ENDCAP_NAME = "mcl_bamboo:bamboo_endcap"
local BAMBOO_PLANK = BAMBOO .. "_plank"
@ -16,7 +13,7 @@ local BAMBOO_PLANK = BAMBOO .. "_plank"
local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname)
local node_sound = mcl_sounds.node_sound_wood_defaults()
local pr = PseudoRandom((os.time() + 15766) * 12) -- switched from math.random() to PseudoRandom because the random wasn't very random.
local pr = PseudoRandom((os.time() + 15766) * 12)
local on_rotate
if minetest.get_modpath("screwdriver") then
@ -31,38 +28,16 @@ local bamboo_def = {
paramtype = "light",
groups = {handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3},
sounds = node_sound,
drop = {
max_items = 1,
-- From the API:
-- max_items: Maximum number of item lists to drop.
-- The entries in 'items' are processed in order. For each:
-- Item filtering is applied, chance of drop is applied, if both are
-- successful the entire item list is dropped.
-- Entry processing continues until the number of dropped item lists
-- equals 'max_items'.
-- Therefore, entries should progress from low to high drop chance.
items = {
-- Examples:
{
-- 1 in DOUBLE_DROP_CHANCE chance of dropping.
-- Default rarity is '1'.
rarity = DOUBLE_DROP_CHANCE,
items = {BAMBOO .. " 2"},
},
{
-- 1 in 1 chance of dropping. (Note: this means that it will drop 100% of the time.)
-- Default rarity is '1'.
rarity = 1,
items = {BAMBOO},
},
},
},
drop = BAMBOO,
inventory_image = "mcl_bamboo_bamboo_shoot.png",
wield_image = "mcl_bamboo_bamboo_shoot.png",
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
return mcl_bamboo.grow_bamboo(pos, true)
end,
node_box = {
type = "fixed",
fixed = {
@ -86,7 +61,6 @@ local bamboo_def = {
on_rotate = on_rotate,
on_place = function(itemstack, placer, pointed_thing)
if not pointed_thing then
return itemstack
end
@ -241,9 +215,6 @@ local bamboo_def = {
if node_above and ((bamboo_node and bamboo_node > 0) or node_above.name == BAMBOO_ENDCAP_NAME) then
minetest.remove_node(new_pos)
minetest.sound_play(node_sound.dug, sound_params, true)
if pr:next(1, DOUBLE_DROP_CHANCE) == 1 then
minetest.add_item(new_pos, istack)
end
minetest.add_item(new_pos, istack)
end
end,
@ -253,10 +224,12 @@ minetest.register_node(BAMBOO, bamboo_def)
local bamboo_top = table.copy(bamboo_def)
bamboo_top.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3}
bamboo_top.tiles = {"mcl_bamboo_endcap.png"}
bamboo_top.drawtype = "plantlike_rooted" --"plantlike"
--bamboo_top.paramtype2 = "meshoptions"
--bamboo_top.param2 = 2
-- bamboo_top.waving = 2
-- bamboo_top.drawtype = "plantlike_rooted" --"plantlike"
bamboo_top.drawtype = "plantlike"
bamboo_top.paramtype2 = "meshoptions"
bamboo_top.param2 = 2
bamboo_top.waving = 2
bamboo_top.special_tiles = {{name = "mcl_bamboo_endcap.png"}}
bamboo_top.nodebox = nil
bamboo_top.selection_box = nil

View File

@ -9,8 +9,6 @@ local SIDE_SCAFFOLDING = false
local SIDE_SCAFFOLD_NAME = "mcl_bamboo:scaffolding_horizontal"
-- ---------------------------------------------------------------------------
local SCAFFOLDING_NAME = "mcl_bamboo:scaffolding"
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
-- "BAMBOO" goes here.
local BAMBOO = "mcl_bamboo:bamboo"
local BAMBOO_PLANK = BAMBOO .. "_plank"

View File

@ -44,6 +44,10 @@ mcl_bamboo.bamboo_index = {
"mcl_bamboo:bamboo_2",
"mcl_bamboo:bamboo_3",
}
mcl_bamboo.bamboo_set = {}
for _,key in pairs(mcl_bamboo.bamboo_index) do
mcl_bamboo.bamboo_set[key] = true
end
function mcl_bamboo.is_bamboo(node_name)
local index = table.indexof(mcl_bamboo.bamboo_index, node_name)
@ -74,7 +78,7 @@ function mcl_bamboo.break_orphaned(pos)
local node_name = node_below.name
-- short circuit checks.
if mcl_bamboo.is_dirt(node_name) or mcl_bamboo.is_bamboo(node_name) or mcl_bamboo.is_bamboo(minetest.get_node(pos).name) == false then
if node_name == "ignore" or mcl_bamboo.is_dirt(node_name) or mcl_bamboo.is_bamboo(node_name) or mcl_bamboo.is_bamboo(minetest.get_node(pos).name) == false then
return
end
@ -94,172 +98,84 @@ end
--]]
function mcl_bamboo.grow_bamboo(pos, bonemeal_applied)
local log = mcl_bamboo.mcl_log
local node_above = minetest.get_node(vector.offset(pos, 0, 1, 0))
mcl_bamboo.mcl_log("Grow bamboo called; bonemeal: " .. tostring(bonemeal_applied))
log("Grow bamboo called; bonemeal: " .. tostring(bonemeal_applied))
if not bonemeal_applied and mcl_bamboo.is_bamboo(node_above.name) ~= false then
return false -- short circuit this function if we're trying to grow (std) the bamboo and it's not the top shoot.
if not bonemeal_applied then
-- Only allow natural growth at the top of the bamboo
if mcl_bamboo.is_bamboo(node_above.name) ~= false then return false end
-- Don't perform natual growth in low light
if minetest.get_node_light(pos) < 8 then return false end
end
if minetest.get_node_light(pos) < 8 then
-- Determine the location of soil
local soil_pos
soil_pos,a,b = mcl_util.trace_nodes(pos, -1, mcl_bamboo.bamboo_set, BAMBOO_MAX_HEIGHT - 1)
-- No soil found, return false so that bonemeal isn't used
if not soil_pos then return false end
log("Grow bamboo; soil found. ")
-- Find the first bamboo shoot and retrieve data about it
local first_shoot = vector.offset(soil_pos, 0, 1, 0)
local first_shoot_meta = minetest.get_meta(first_shoot)
-- Get or initialize bamboo height
local height = (first_shoot_meta and first_shoot_meta:get_int("height", -1)) or -1
if height == -1 then
height = rand(BAM_MAX_HEIGHT_STPCHK + 1, BAM_MAX_HEIGHT_TOP + 1)
first_shoot_meta:set_int("height", height)
end
log("Grow bamboo; height: " .. height)
-- Locate the bamboo tip
local bamboo_tip,actual_height,bamboo_tip_node = mcl_util.trace_nodes(first_shoot, 1, mcl_bamboo.bamboo_set, height - 1)
log("Current height: "..tostring(actual_height))
-- Short circuit growth if the bamboo is already finished growing
if not bamboo_tip or not actual_height or actual_height >= height then
log("Bamboo is already as large as it can grow")
return false
end
-- variables used in more than one spot.
local first_shoot
local chk_pos
local soil_pos
local node_name = ""
local dist = 0
local node_below
-- -------------------
-- Now that we are actually going to add nodes, initialize some more information
local first_shoot_node_name = minetest.get_node(first_shoot).name
mcl_bamboo.mcl_log("Grow bamboo; checking for soil: ")
-- the soil node below the bamboo.
for py = -1, BAMBOO_SOIL_DIST, -1 do
chk_pos = vector.offset(pos, 0, py, 0)
node_name = minetest.get_node(chk_pos).name
if mcl_bamboo.is_dirt(node_name) then
soil_pos = chk_pos
break
end
if mcl_bamboo.is_bamboo(node_name) == false then
break
end
end
-- requires knowing where the soil node is.
if soil_pos == nil then
return false -- returning false means don't use up the bonemeal.
end
mcl_bamboo.mcl_log("Grow bamboo; soil found. ")
local grow_amount = rand(1, GROW_DOUBLE_CHANCE)
grow_amount = rand(1, GROW_DOUBLE_CHANCE)
grow_amount = rand(1, GROW_DOUBLE_CHANCE) -- because yeah, not truly random, or even a good prng.
grow_amount = rand(1, GROW_DOUBLE_CHANCE)
local init_height = rand(BAM_MAX_HEIGHT_STPCHK + 1, BAM_MAX_HEIGHT_TOP + 1)
mcl_bamboo.mcl_log("Grow bamboo; random height: " .. init_height)
node_name = ""
-- update: add randomized max height to first node's meta data.
first_shoot = vector.offset(soil_pos, 0, 1, 0)
local meta = minetest.get_meta(first_shoot)
node_below = minetest.get_node(first_shoot).name
mcl_bamboo.mcl_log("Grow bamboo; checking height meta ")
-- check the meta data for the first node, to see how high to make the stalk.
if not meta then
-- if no metadata, set the metadata!!!
meta:set_int("height", init_height)
end
local height = meta:get_int("height", -1)
mcl_bamboo.mcl_log("Grow bamboo; meta-height: " .. height)
if height <= 10 then
height = init_height
meta:set_int("height", init_height)
end
mcl_bamboo.mcl_log("Grow bamboo; height: " .. height)
-- Bonemeal: Grows the bamboo by 1-2 stems. (per the minecraft wiki.)
-- If applying bonemeal, randomly grow two segments instead of one
local grow_amount = 1
if bonemeal_applied then
-- handle applying bonemeal.
for py = 1, BAM_MAX_HEIGHT_TOP do
-- find the top node of bamboo.
chk_pos = vector.offset(pos, 0, py, 0)
node_name = minetest.get_node(chk_pos).name
dist = vector.distance(soil_pos, chk_pos)
if mcl_bamboo.is_bamboo(node_name) == false or node_name == BAMBOO_ENDCAP_NAME then
break
end
end
mcl_bamboo.mcl_log("Grow bamboo; dist: " .. dist)
if node_name == BAMBOO_ENDCAP_NAME then
-- prevent overgrowth
return false
end
-- check to see if we have a full stalk of bamboo.
if dist >= height - 1 then
if dist == height - 1 then
-- equals top of the stalk before the cap
if node_name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; Placing endcap")
minetest.set_node(vector.offset(chk_pos, 0, 1, 0), { name = BAMBOO_ENDCAP_NAME })
return true -- returning true means use up the bonemeal.
else
return false
end
else
-- okay, we're higher than the end cap, fail out.
return false -- returning false means don't use up the bonemeal.
end
end
-- and now, the meat of the section... add bamboo to the stalk.
-- at this point, we should be lower than the generated maximum height. ~ about height -2 or lower.
if dist <= height - 2 then
if node_name == "air" then
-- here we can check to see if we can do up to 2 bamboo shoots onto the stalk
mcl_bamboo.mcl_log("Grow bamboo; Placing bamboo.")
minetest.set_node(chk_pos, { name = node_below })
-- handle growing a second node.
if grow_amount == 2 then
chk_pos = vector.offset(chk_pos, 0, 1, 0)
if minetest.get_node(chk_pos).name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; OOOH! It's twofer day!")
minetest.set_node(chk_pos, { name = node_below })
end
end
return true -- exit out with a success. We've added 1-2 nodes, per the wiki.
end
local rng = PcgRandom(minetest.hash_node_position(pos) + minetest.get_us_time())
if rng:next(1, GROW_DOUBLE_CHANGE) == 1 then
grow_amount = 2
end
end
log("Growing up to "..grow_amount.." segments")
-- Non-Bonemeal growth.
for py = 1, BAM_MAX_HEIGHT_TOP do
-- Find the topmost node above the stalk, and check it for "air"
chk_pos = vector.offset(pos, 0, py, 0)
node_below = minetest.get_node(pos).name
node_name = minetest.get_node(chk_pos).name
dist = vector.distance(soil_pos, chk_pos)
if node_name ~= "air" and mcl_bamboo.is_bamboo(node_name) == false then
break
-- Perform bamboo growth
for i = 1,grow_amount do
-- Check for air to grow into
local bamboo_tip_node = minetest.get_node(bamboo_tip)
if not bamboo_tip_node or bamboo_tip_node.name ~= "air" then
-- Something is blocking growth, stop and signal that use bonemeal has been used if at least on segment has grown
return i ~= 1
end
-- stop growing check. ie, handle endcap placement.
if dist >= height - 1 then
local above_node_name = minetest.get_node(vector.offset(chk_pos, 0, 1, 0)).name
if node_name == "air" and above_node_name == "air" then
if height - 1 == dist then
mcl_bamboo.mcl_log("Grow bamboo; Placing endcap")
minetest.set_node(chk_pos, { name = BAMBOO_ENDCAP_NAME })
end
end
break
if actual_height + 1 == height then
-- This is the end cap
minetest.set_node(bamboo_tip, { name = BAMBOO_ENDCAP_NAME })
return true
else
-- This isn't the end cap, add a bamboo segment
minetest.set_node(bamboo_tip, { name = first_shoot_node_name })
actual_height = actual_height + 1
end
-- handle regular node placement.
-- find the air node above the top shoot. place a node. And then, if short enough,
-- check for second node placement.
if node_name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; dist: " .. dist)
mcl_bamboo.mcl_log("Grow bamboo; Placing bamboo.")
minetest.set_node(chk_pos, { name = node_below })
-- handle growing a second node. (1 in 32 chance.)
if grow_amount == 2 and dist <= height - 2 then
chk_pos = vector.offset(chk_pos, 0, 1, 0)
if minetest.get_node(chk_pos).name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; OOOH! It's twofer day!")
minetest.set_node(chk_pos, { name = node_below })
end
end
break
end
bamboo_tip = vector.offset(bamboo_tip, 0, 1, 0)
end
return true
end
-- Add Groups function, courtesy of Warr1024.

View File

@ -7,8 +7,6 @@
-- LOCALS
local modname = minetest.get_current_modname()
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
-- "BAMBOO" goes here.
local BAMBOO = "mcl_bamboo:bamboo"
mcl_bamboo = {}

View File

@ -5,8 +5,6 @@
--- These are all of the fuel recipes and all of the crafting recipes, consolidated into one place.
--- Copyright (C) 2022 - 2023, Michieal. See License.txt
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
-- "BAMBOO" goes here.
local BAMBOO = "mcl_bamboo:bamboo"
local BAMBOO_PLANK = BAMBOO .. "_plank"
-- Craftings

View File

@ -2,4 +2,4 @@ name = mcl_beds
author = BlockMen
description =
depends = playerphysics
optional_depends = mcl_sounds, mcl_worlds, mcl_wool, mcl_dye, mcl_explosions, mcl_weather, mcl_spawn, doc, mesecons
optional_depends = mcl_sounds, mcl_worlds, mcl_wool, mcl_dye, mcl_explosions, mcl_weather, mcl_spawn, doc, mesecons, mesecons_mvps

View File

@ -0,0 +1,76 @@
# Bone meal API
Bonemealing callbacks and particle functions.
## _on_bone_meal(itemstack, placer, pointed_thing)
The bone meal API provides a callback definition that nodes can use to
register a handler that is executed when a bone meal item is used on it.
Nodes that wish to use the bone meal API should in their node registration
define a callback handler named `_on_bone_meal`.
Note that by registering the callback handler, the node declares that bone
meal can be used on it and as a result, when the user is not in creative
mode, the used bone meal is spent and taken from the itemstack passed to
the `on_place()` handler of the bone meal item used regardless of whether
the bone meal had an effect on the node and regardless of the result of
the callback handler.
It is for all intents and purposes up to the callback defined in the node to
decide how to handle the specific effect that bone meal has on that node.
The `_on_bone_meal` callback handler is a
`function(itemstack, placer, pointed_thing)`
Its arguments are:
* `itemstack`: the stack of bonem eal being applied
* `placer`: ObjectRef of the player who aplied the bone meal, can be nil!
* `pointed_thing`: exact pointing location (see Minetest API), where the
bone meal is applied
The return value of the handler function indicates if the bonemealing had
its intended effect. If `true`, 'bone meal particles' are spawned at the
position of the bonemealed node.
The `on_place` code in the bone meal item will spawn bone meal particles and
decrease the bone meal itemstack if the handler returned `true` and the
`placer` is not in creative mode.
## mcl_bone_meal.add_bone_meal_particle(pos, def)
Spawns standard or custom bone meal particles.
* `pos`: position, is ignored if you define def.minpos and def.maxpos
* `def`: (optional) particle definition; see minetest.add_particlespawner()
for more details.
## mcl_bone_meal.use_bone_meal(itemstack, placer, pointed_thing)
For use in on_rightclick handlers that need support bone meal processing in addition
to other behaviors. Before calling, verify that the player is wielding bone meal.
* `itemstack`: The stack of bone meal being used
* `placer`: ObjectRef of the player who aplied the bone meal, can be nil!
* `pointed_thing`: exact pointing location (see Minetest API), where the
bone meal is applied
Returns itemstack with one bone meal consumed if not in creative mode.
# Legacy API
The bone meal API also provides a legacy compatibility function. This
function is not meant to be continued and callers should migrate to the
newer bonemealing API.
## mcl_bone_meal.register_on_bone_meal_apply(function(pointed_thing, placer))
Called when the bone meal is applied anywhere.
* `pointed_thing`: exact pointing location (see Minetest API), where the
bone meal is applied
* `placer`: ObjectRef of the player who aplied the bone meal, can be nil!
This function is deprecated and will be removed at some time in the future.
Bone meal is not consumed unless the provided function returns true.
## mcl_dye.add_bone_meal_particle(pos, def)
## mcl_dye.register_on_bone_meal_apply(function(pointed_thing, user))
These shims in mcl_dye that point to corresponding legacy compatibility
functions in mcl_bone_meal remain for legacy callers that have not yet been
updated to the new API. These shims will be removed at some time in the
future.

View File

@ -0,0 +1,156 @@
local S = minetest.get_translator(minetest.get_current_modname())
local longdesc = S(
"Bone meal is a white dye and also useful as a fertilizer to " ..
"speed up the growth of many plants."
)
local usagehelp = S(
"Rightclick a sheep to turn its wool white. Rightclick a plant " ..
"to speed up its growth. Note that not all plants can be " ..
"fertilized like this. When you rightclick a grass block, tall " ..
"grass and flowers will grow all over the place."
)
mcl_bone_meal = {}
-- Bone meal particle API:
--- Spawns bone meal particles.
-- pos: where the particles spawn
-- def: particle spawner parameters, see minetest.add_particlespawner() for
-- details on these parameters.
--
function mcl_bone_meal.add_bone_meal_particle(pos, def)
def = def or {}
minetest.add_particlespawner({
amount = def.amount or 10,
time = def.time or 0.1,
minpos = def.minpos or vector.subtract(pos, 0.5),
maxpos = def.maxpos or vector.add(pos, 0.5),
minvel = def.minvel or vector.new(-0.01, 0.01, -0.01),
maxvel = def.maxvel or vector.new(0.01, 0.01, 0.01),
minacc = def.minacc or vector.new(0, 0, 0),
maxacc = def.maxacc or vector.new(0, 0, 0),
minexptime = def.minexptime or 1,
maxexptime = def.maxexptime or 4,
minsize = def.minsize or 0.7,
maxsize = def.maxsize or 2.4,
texture = "mcl_particles_bonemeal.png^[colorize:#00EE00:125",
glow = def.glow or 1,
})
end
-- Begin legacy bone meal API.
--
-- Compatibility code for legacy users of the old bone meal API.
-- This code will be removed at some time in the future.
--
mcl_bone_meal.bone_meal_callbacks = {}
-- Shims for the old API are still available in mcl_dye and defer to
-- the real functions in mcl_bone_meal.
--
function mcl_bone_meal.register_on_bone_meal_apply(func)
minetest.log("warning", "register_on_bone_meal_apply(func) is deprecated. Read mcl_bone_meal/API.md!")
local lines = string.split(debug.traceback(),"\n")
for _,line in ipairs(lines) do
minetest.log("warning",line)
end
table.insert(mcl_bone_meal.bone_meal_callbacks, func)
end
-- Legacy registered users of the old API are handled through this function.
--
local function legacy_apply_bone_meal(pointed_thing, placer)
-- Legacy API support
local callbacks = mcl_bone_meal.bone_meal_callbacks
for i = 1,#callbacks do
if callbacks[i](pointed_thing, placer) then
return true
end
end
return false
end
-- End legacy bone meal API
function mcl_bone_meal.use_bone_meal(itemstack, placer, pointed_thing)
local positions = {pointed_thing.under, pointed_thing.above}
for i = 1,2 do
local pos = positions[i]
-- Check protection
if mcl_util.check_area_protection(pos, pointed_thing.above, placer) then return false end
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
local success = false
local consume
-- If the pointed node can be bonemealed, let it handle the processing.
if ndef and ndef._on_bone_meal then
success = ndef._on_bone_meal(itemstack, placer, {under = pos, above = vector.offset(pos, 0, 1, 0)})
consume = true
else
-- Otherwise try the legacy API.
success = legacy_apply_bone_meal(pointed_thing, placer)
consume = success
end
-- Take the item
if consume then
-- Particle effects
mcl_bone_meal.add_bone_meal_particle(pos)
if not placer or not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
return itemstack
end
if success then return itemstack end
end
return itemstack
end
minetest.register_craftitem("mcl_bone_meal:bone_meal", {
description = S("Bone Meal"),
_tt_help = S("Speeds up plant growth"),
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = usagehelp,
inventory_image = "mcl_bone_meal.png",
groups = {craftitem=1},
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
-- Use pointed node's on_rightclick function first, if present.
if placer and not placer:get_player_control().sneak then
if ndef and ndef.on_rightclick then
local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing)
if new_stack and new_stack ~= itemstack then return new_stack end
end
end
return mcl_bone_meal.use_bone_meal(itemstack, placer, pointed_thing)
end,
_on_dispense = function(itemstack, pos, droppos, dropnode, dropdir)
local pointed_thing
if dropnode.name == "air" then
pointed_thing = {above = droppos, under = vector.offset(droppos, 0, -1 ,0)}
else
pointed_thing = {above = pos, under = droppos}
end
return mcl_bone_meal.use_bone_meal(itemstack, nil, pointed_thing)
end,
_dispense_into_walkable = true
})
minetest.register_craft({
output = "mcl_bone_meal:bone_meal 3",
recipe = {{"mcl_mobitems:bone"}},
})

View File

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Knochenmehl
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Knochenmehl ist ein weißer Farbstoff und auch nützlich als Dünger, um das Wachstum vieler Pflanzen zu beschleunigen.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Rechtsklicken Sie auf ein Schaf, um die Wolle weiß einzufärben. Rechtsklicken Sie auf eine Pflanze, um ihr Wachstum zu beschleunigen. Beachten Sie, dass nicht alle Pflanzen darauf ansprechen. Benutzen Sie es auf einem Grasblock, wächst viel hohes Gras und vielleicht auch ein paar Blumen.
Speeds up plant growth=Beschleunigt Pflanzenwachstum

View File

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Harina de hueso
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=La harina de hueso es un tinte blanco y también es útil como fertilizante para acelerar el crecimiento de muchas plantas.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=RHaga clic derecho en una oveja para volver su lana blanca. Haga clic derecho en una planta para acelerar su crecimiento. Tenga en cuenta que no todas las plantas pueden ser fertilizadas de esta manera. Cuando haces clic derecho en un bloque de hierba, crecerán hierba alta y flores por todo el lugar.
Speeds up plant growth=Acelera el crecimiento de las plantas

View File

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Farine d'Os
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=La farine d'os est une teinture blanche et est également utile comme engrais pour accélérer la croissance de nombreuses plantes.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Cliquez avec le bouton droit sur un mouton pour blanchir sa laine. Cliquez avec le bouton droit sur une plante pour accélérer sa croissance. Cependant, toutes les plantes ne peuvent pas être fertilisées de cette manière. Lorsque vous cliquez avec le bouton droit sur un bloc d'herbe, les hautes herbes et les fleurs poussent autour.
Speeds up plant growth=Accélère la croissance des plantes

View File

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Mączka kostna
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Mączka kostna to biała farba i przydatny nawóz, który przyspiesza rośnięcie wielu roślin.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Kliknij prawym na owcę, aby wybielić jej wełnę. Kliknij prawym na roślinę aby przyspieszyć jej wzrost. Zważ, że nie na wszystkie rośliny to tak działa. Gdy klikniesz prawym na blok trawy, wysoka trawa wyrośnie wokół.
Speeds up plant growth=Przyspiesza wzrost roślin

View File

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Костная мука
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Костная мука является белым красителем. Она также полезна в качестве удобрения, чтобы увеличить скорость роста многих растений.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Кликните правой по овце, чтобы сделать её шерсть белой. Кликните правой по растению, чтобы ускорить его рост. Имейте в виду, что не все растения можно удобрять таким способом. Если вы кликнете по травяному блоку, то на этом месте вырастет высокая трава и цветы.
Speeds up plant growth=Ускоряет рост растений

View File

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=骨粉
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=骨粉是一種白色染料,也可作為肥料,加速許多植物的生長。
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=右鍵點擊一隻羊,使其羊毛變白。右鍵點擊一株植物以加快其生長速度。注意,不是所有的植物都能像這樣施肥。當你右鍵點擊一個草方時,高高的草和花會到處生長。
Speeds up plant growth=加速植物生長

View File

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=
Speeds up plant growth=

View File

@ -0,0 +1,3 @@
name = mcl_bone_meal
description = Bone meal can be used as a fertilizer and as a dye.
author = kabou, teknomunk

View File

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 165 B

View File

@ -257,10 +257,10 @@ function ARROW_ENTITY.on_step(self, dtime)
mcl_burning.set_on_fire(obj, 5)
end
if not self._in_player and not self._blocked then
obj:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups={fleshy=self._damage},
}, self.object:get_velocity())
mcl_util.deal_damage(obj, self._damage, {type = "arrow", source = self._shooter, direct = self.object})
if self._extra_hit_func then
self._extra_hit_func(obj)
end
if obj:is_player() then
if not mcl_shields.is_blocking(obj) then
local placement

View File

@ -168,7 +168,8 @@ S("The speed and damage of the arrow increases the longer you charge. The regula
itemstack:get_meta():set_string("active", "true")
return itemstack
end,
groups = {weapon=1,weapon_ranged=1,bow=1,enchantability=1},
groups = {weapon=1,weapon_ranged=1,bow=1,cannot_block=1,enchantability=1},
touch_interaction = "short_dig_long_place",
_mcl_uses = 385,
})
@ -216,7 +217,7 @@ for level=0, 2 do
wield_scale = mcl_vars.tool_wield_scale,
stack_max = 1,
range = 0, -- Pointing range to 0 to prevent punching with bow :D
groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, enchantability=1},
groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, cannot_block=1, enchantability=1},
-- Trick to disable digging as well
on_use = function() return end,
on_drop = function(itemstack, dropper, pos)
@ -235,6 +236,7 @@ for level=0, 2 do
on_place = function(itemstack)
return itemstack
end,
touch_interaction = "short_dig_long_place",
_mcl_uses = 385,
})
end

View File

@ -158,7 +158,8 @@ S("The speed and damage of the arrow increases the longer you charge. The regula
itemstack:get_meta():set_string("active", "true")
return itemstack
end,
groups = {weapon=1,weapon_ranged=1,crossbow=1,enchantability=1},
groups = {weapon=1,weapon_ranged=1,crossbow=1,cannot_block=1,enchantability=1},
touch_interaction = "short_dig_long_place",
_mcl_uses = 326,
})
@ -193,7 +194,8 @@ S("The speed and damage of the arrow increases the longer you charge. The regula
itemstack:get_meta():set_string("active", "true")
return itemstack
end,
groups = {weapon=1,weapon_ranged=1,crossbow=1,enchantability=1,not_in_creative_inventory=1},
groups = {weapon=1,weapon_ranged=1,crossbow=1,cannot_block=1,enchantability=1,not_in_creative_inventory=1},
touch_interaction = "short_dig_long_place",
_mcl_uses = 326,
})
@ -238,7 +240,7 @@ for level=0, 2 do
wield_scale = mcl_vars.tool_wield_scale,
stack_max = 1,
range = 0, -- Pointing range to 0 to prevent punching with bow :D
groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, enchantability=1},
groups = {not_in_creative_inventory=1, not_in_craft_guide=1, cannot_block=1, bow=1, enchantability=1},
-- Trick to disable digging as well
on_use = function() return end,
on_drop = function(itemstack, dropper, pos)
@ -257,6 +259,7 @@ for level=0, 2 do
on_place = function(itemstack)
return itemstack
end,
touch_interaction = "short_dig_long_place",
_mcl_uses = 385,
})
end

View File

@ -1,25 +1,28 @@
# mcl_buckets
Add an API to register buckets to mcl
Adds an API to register buckets to VL
## mcl_buckets.register_liquid(def)
Register a new liquid
Accept folowing params:
* source_place: a string or function.
* string: name of the node to place
* function(pos): will returns name of the node to place with pos being the placement position
* source_take: table of liquid source node names to take
* bucketname: itemstring of the new bucket item
* inventory_image: texture of the new bucket item (ignored if itemname == nil)
* name: user-visible bucket description
* longdesc: long explanatory description (for help)
* usagehelp: short usage explanation (for help)
* tt_help: very short tooltip help
* extra_check(pos, placer): (optional) function(pos)
* groups: optional list of item groups
Register a new liquid.
Accepts the following parameters:
* `source_place`: a string or a function
* `string`: name of the node to place
* `function(pos)`: will return name of the node to place with pos being the placement position
* `source_take`: table of liquid source node names to take
* `bucketname`: itemstring of the new bucket item
* `inventory_image`: texture of the new bucket item (ignored if itemname == nil)
* `name`: user-visible bucket description
* `longdesc`: long explanatory description (for help)
* `usagehelp`: short usage explanation (for help)
* `tt_help`: very short tooltip help
* `extra_check(pos, placer)`: (optional) additional check before liquid placement (return 2 booleans: (1) whether to place the liquid source and (2) whether to empty the bucket)
* `groups`: optional list of item groups
**Usage exemple:**
**Usage example:**
```lua
mcl_buckets.register_liquid({
bucketname = "dummy:bucket_dummy",
@ -39,7 +42,7 @@ mcl_buckets.register_liquid({
tt_help = S("Places a dummy liquid source"),
extra_check = function(pos, placer)
--pos = pos where the liquid should be placed
--placer people who tried to place the bucket (can be nil)
--placer who tried to place the bucket (can be nil)
--no liquid node will be placed
--the bucket will not be emptied
@ -51,4 +54,4 @@ mcl_buckets.register_liquid({
end,
groups = { dummy_group = 123 },
})
```
```

View File

@ -39,9 +39,9 @@ local function drop_items(pos, node, oldmeta)
if food_entity:get_luaentity().name == "mcl_campfires:food_entity" then
food_entity:remove()
for i = 1, 4 do
meta:set_string("food_x_"..tostring(i), nil)
meta:set_string("food_y_"..tostring(i), nil)
meta:set_string("food_z_"..tostring(i), nil)
meta:set_string("food_x_"..tostring(i), "")
meta:set_string("food_y_"..tostring(i), "")
meta:set_string("food_z_"..tostring(i), "")
end
end
end
@ -135,9 +135,9 @@ function mcl_campfires.cook_item(pos, elapsed)
if cooked then
if food_entity then
food_entity:remove() -- Remove visual food entity
meta:set_string("food_x_"..tostring(i), nil)
meta:set_string("food_y_"..tostring(i), nil)
meta:set_string("food_z_"..tostring(i), nil)
meta:set_string("food_x_"..tostring(i), "")
meta:set_string("food_y_"..tostring(i), "")
meta:set_string("food_z_"..tostring(i), "")
minetest.add_item(pos, cooked.item) -- Drop Cooked Item
-- Throw some Experience Points because why not?
-- Food is cooked, xp is deserved for using this unique cooking method. Take that Minecraft ;)

View File

@ -5,9 +5,9 @@ animations are achieved by giving each chest node an entity, as Minetest (as of
5.8.1) doesn't support giving nodes animated meshes, only static ones.
Because of that, a lot of parameters passed through the exposed functions are
be related to nodes and entities.
related to nodes and entities.
Please refer to [Minetest documentation](http://api.minetest.net/) and the code
Please refer to the [Minetest documentation](http://api.minetest.net/) and code
comments in `api.lua`.

View File

@ -79,7 +79,7 @@ minetest.register_lbm({
local node_name = node.name
node.name = node_name .. "_small"
minetest.swap_node(pos, node)
select_and_spawn_entity(pos, node)
mcl_chests.select_and_spawn_entity(pos, node)
if node_name == "mcl_chests:trapped_chest_on" then
minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " .. minetest.pos_to_string(pos))
mcl_chests.chest_update_after_close(pos)

View File

@ -2,29 +2,34 @@ local S = minetest.get_translator(minetest.get_current_modname())
mcl_cocoas = {}
-- Place cocoa
local function cocoa_place(itemstack, placer, pt, plantname)
--- Place a cocoa pod.
-- Attempt to place a cocoa pod on a jungle tree. Checks if attachment
-- point is a jungle tree and sets the correct orientation of the stem.
--
function mcl_cocoas.place(itemstack, placer, pt, plantname)
-- check if pointing at a node
if not pt or pt.type ~= "node" then
return
end
local under = minetest.get_node(pt.under)
local node = minetest.get_node(pt.under)
-- return if any of the nodes are not registered
if not minetest.registered_nodes[under.name] then
local def = minetest.registered_nodes[node.name]
if not def then
return
end
-- Am I right-clicking on something that has a custom on_rightclick set?
if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[under.name] and minetest.registered_nodes[under.name].on_rightclick then
return minetest.registered_nodes[under.name].on_rightclick(pt.under, under, placer, itemstack) or itemstack
if def and def.on_rightclick then
local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pt)
if new_stack and new_stack ~= itemstack then return new_stack end
end
end
-- Check if pointing at jungle tree
if under.name ~= "mcl_core:jungletree"
if node.name ~= "mcl_core:jungletree"
or minetest.get_node(pt.above).name ~= "air" then
return
end
@ -39,9 +44,7 @@ local function cocoa_place(itemstack, placer, pt, plantname)
-- Add the node, set facedir and remove 1 item from the itemstack
minetest.set_node(pt.above, {name = plantname, param2 = minetest.dir_to_facedir(clickdir)})
minetest.sound_play("default_place_node", {pos = pt.above, gain = 1.0}, true)
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
@ -49,111 +52,119 @@ local function cocoa_place(itemstack, placer, pt, plantname)
return itemstack
end
-- Attempts to grow a cocoa at pos, returns true when grown, returns false if there's no cocoa
-- or it is already at full size
--- Grows cocoa pod one size larger.
-- Attempts to grow a cocoa at pos, returns true when grown, returns false
-- if there's no cocoa or it is already at full size.
--
function mcl_cocoas.grow(pos)
local node = minetest.get_node(pos)
if node.name == "mcl_cocoas:cocoa_1" then
minetest.set_node(pos, {name = "mcl_cocoas:cocoa_2", param2 = node.param2})
elseif node.name == "mcl_cocoas:cocoa_2" then
minetest.set_node(pos, {name = "mcl_cocoas:cocoa_3", param2 = node.param2})
return true
else
return false
end
return false
return true
end
-- Cocoa definition
-- 1st stage
local crop_def = {
description = S("Premature Cocoa Pod"),
_doc_items_create_entry = true,
_doc_items_longdesc = S("Cocoa pods grow on the side of jungle trees in 3 stages."),
drawtype = "mesh",
mesh = "mcl_cocoas_cocoa_stage_0.obj",
tiles = {"mcl_cocoas_cocoa_stage_0.png"},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",
walkable = true,
drop = "mcl_cocoas:cocoa_beans",
collision_box = {
type = "fixed",
fixed = {
{-0.125, -0.0625, 0.1875, 0.125, 0.25, 0.4375}, -- Pod
-- only caller was mcl_dye, consider converting these into local functions.
local cocoa_place = mcl_cocoas.place
local cocoa_grow = mcl_cocoas.grow
-- Cocoa pod variant definitions.
--[[ TODO: Use a mesh for cocoas for perfect texture compability. ]]
local podinfo = {
{ desc = S("Premature Cocoa Pod"),
longdesc = S("Cocoa pods grow on the side of jungle trees in 3 stages."),
tiles = {
"mcl_cocoas_cocoa_stage_0.png",
},
n_box = {-0.125, -0.0625, 0.1875, 0.125, 0.25, 0.4375},
s_box = {-0.125, -0.0625, 0.1875, 0.125, 0.5, 0.5 },
},
selection_box = {
type = "fixed",
fixed = {
{-0.125, -0.0625, 0.1875, 0.125, 0.5, 0.5}, -- Pod
{ desc = S("Medium Cocoa Pod"),
tiles = {
"mcl_cocoas_cocoa_stage_1.png",
},
n_box = {-0.1875, -0.1875, 0.0625, 0.1875, 0.25, 0.4375},
s_box = {-0.1875, -0.1875, 0.0625, 0.1875, 0.5, 0.5 },
},
groups = {
handy = 1, axey = 1,
dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1,
attached_node_facedir=1,
not_in_creative_inventory=1,
cocoa=1
},
sounds = mcl_sounds.node_sound_wood_defaults(),
on_rotate = false,
_mcl_blast_resistance = 3,
_mcl_hardness = 0.2,
}
-- 2nd stage
minetest.register_node("mcl_cocoas:cocoa_1", table.copy(crop_def))
crop_def.description = S("Medium Cocoa Pod")
crop_def._doc_items_create_entry = false
crop_def.groups.cocoa = 2
crop_def.mesh = "mcl_cocoas_cocoa_stage_1.obj"
crop_def.tiles = {"mcl_cocoas_cocoa_stage_1.png"}
crop_def.collision_box = {
type = "fixed",
fixed = {
{-0.1875, -0.1875, 0.0625, 0.1875, 0.25, 0.4375}, -- Pod
},
}
crop_def.selection_box = {
type = "fixed",
fixed = {
{-0.1875, -0.1875, 0.0625, 0.1875, 0.5, 0.5},
{ desc = S("Mature Cocoa Pod"),
longdesc = S("A mature cocoa pod grew on a jungle tree to its full size and it is ready to be harvested for cocoa beans. It won't grow any further."),
tiles = {
"mcl_cocoas_cocoa_stage_2.png",
},
n_box = {-0.25, -0.3125, -0.0625, 0.25, 0.25, 0.4375},
s_box = {-0.25, -0.3125, -0.0625, 0.25, 0.5, 0.5 },
},
}
minetest.register_node("mcl_cocoas:cocoa_2", table.copy(crop_def))
for i = 1, 3 do
local def = {
description = podinfo[i].desc,
_doc_items_create_entry = true,
_doc_items_longdesc = podinfo[i].longdesc,
paramtype = "light",
paramtype2 = "facedir",
drawtype = "nodebox",
tiles = podinfo[i].tiles,
use_texture_alpha = "clip",
node_box = {
type = "fixed",
fixed = {
podinfo[i].n_box, -- Pod
-- FIXME: This has a thickness of 0. Is this OK in Minetest?
{ 0, 0.25, 0.25, 0, 0.5, 0.5 }, }, -- Stem
},
collision_box = {
type = "fixed",
fixed = podinfo[i].n_box
},
selection_box = {
type = "fixed",
fixed = podinfo[i].s_box
},
groups = {
handy = 1, axey = 1, attached_node_facedir = 1,
dig_by_water = 1, destroy_by_lava_flow = 1, dig_by_piston = 1,
cocoa = i, not_in_creative_inventory = 1,
},
sunlight_propagates = true,
walkable = true,
drop = "mcl_cocoas:cocoa_beans",
sounds = mcl_sounds.node_sound_wood_defaults(),
on_rotate = false,
_mcl_blast_resistance = 3,
_mcl_hardness = 0.2,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
return cocoa_grow(pos)
end,
}
-- Final stage
crop_def.description = S("Mature Cocoa Pod")
crop_def._doc_items_longdesc = S("A mature cocoa pod grew on a jungle tree to its full size and it is ready to be harvested for cocoa beans. It won't grow any further.")
crop_def._doc_items_create_entry = true
crop_def.groups.cocoa = 3
crop_def.mesh = "mcl_cocoas_cocoa_stage_2.obj"
crop_def.tiles = {"mcl_cocoas_cocoa_stage_2.png"}
crop_def.collision_box = {
type = "fixed",
fixed = {
{-0.25, -0.3125, -0.0625, 0.25, 0.25, 0.4375}, -- Pod
},
}
crop_def.selection_box = {
type = "fixed",
fixed = {
{-0.25, -0.3125, -0.0625, 0.25, 0.5, 0.5},
},
}
crop_def.drop = "mcl_cocoas:cocoa_beans 3"
minetest.register_node("mcl_cocoas:cocoa_3", table.copy(crop_def))
if i == 2 then
def._doc_items_longdesc = nil
def._doc_items_create_entry = false
end
if i == 3 then
def.drop = "mcl_cocoas:cocoa_beans 3"
def._on_bone_mealing = nil
end
minetest.register_node("mcl_cocoas:cocoa_" .. i, table.copy(def))
end
minetest.register_craftitem("mcl_cocoas:cocoa_beans", {
description = S("Cocoa Beans"),
inventory_image = "mcl_cocoa_beans.png",
_tt_help = S("Grows at the side of jungle trees"),
_doc_items_longdesc = S("Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye."),
_doc_items_usagehelp = S("Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa."),
inventory_image = "mcl_cocoas_cocoa_beans.png",
groups = {craftitem = 1, compostability = 65},
_doc_items_longdesc = S("Cocoa beans can be used to plant cocoa, bake cookies or cract brown dye."),
_doc_items_usagehelp = S("Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa."),
description = S("Cocoa Beans"),
stack_max = 64,
groups = {
craftitem = 1, compostability = 65,
},
on_place = function(itemstack, placer, pointed_thing)
return cocoa_place(itemstack, placer, pointed_thing, "mcl_cocoas:cocoa_1")
end,

View File

@ -2,7 +2,7 @@
Cocoa Beans=Kakaobohnen
Grows at the side of jungle trees=Wächst an der Seite von Dschungelbäumen
Cocoa beans can be used to plant cocoa pods, bake chocolate cookies or craft brown dye.=Kakaobohnen können benutzt werden, um Kakao anzupflanzen, Kekse zu backen oder braune Farbstoffe herzustellen.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Rechtsklicken Sie an die Seite eines Dschungelbaumstamms (Dschungelholz), um eine junge Kakaoschote zu pflanzen.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Rechtsklicken Sie auf ein Schaf, um die Wolle braun einzufärben. Rechtsklicken Sie an die Seite eines Dschungelbaumstamms (Dschungelholz), um eine junge Kakaoschote zu pflanzen.
Premature Cocoa Pod=Junge Kakaoschote
Cocoa pods grow on the side of jungle trees in 3 stages.=Kakaoschoten wachsen an der Seite von Dschungelbäumen in 3 Stufen.
Medium Cocoa Pod=Mittelgroße Kakaoschote

View File

@ -2,7 +2,7 @@
Cocoa Beans=Granos de cacao
Grows at the side of jungle trees=Crece al lado de los árboles de la jungla
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Los granos de cacao se pueden usar para plantar cacao, hornear galletas o hacer tintes marrones.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Haga clic derecho en el costado del tronco de un árbol de la jungla para plantar un cacao joven.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Haga clic derecho en una oveja para convertir su lana en marrón. Haga clic derecho en el costado del tronco de un árbol de la jungla para plantar un cacao joven.
Premature Cocoa Pod=Vaina de cacao prematura
Cocoa pods grow on the side of jungle trees in 3 stages.=Las vainas de cacao crecen al lado de los árboles de jungla en 3 etapas.
Medium Cocoa Pod=Vaina de cacao mediana

View File

@ -2,7 +2,7 @@
Cocoa Beans=Fèves de Cacao
Grows at the side of jungle trees=Pousse à côté des arbres de la jungle
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Les fèves de cacao peuvent être utilisées pour planter du cacao, faire des biscuits ou fabriquer de la teinture brune.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Clic droit sur le côté d'un tronc d'arbre de la jungle (Bois Acajou) pour planter un jeune cacaoyer.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Faites un clic droit sur un mouton pour brunir sa laine. Clic droit sur le côté d'un tronc d'arbre de la jungle (Bois Acajou) pour planter un jeune cacao.
Premature Cocoa Pod=Gousse de cacao prématurée
Cocoa pods grow on the side of jungle trees in 3 stages.=Les cabosses de cacao poussent sur le côté des arbres d'Acajou en 3 étapes.
Medium Cocoa Pod=Gousse de cacao moyenne

View File

@ -2,7 +2,7 @@
Cocoa Beans=Ziarna kakaowe
Grows at the side of jungle trees=Rośnie na boku tropikalnych drzew
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Ziarna kakaowe mogą być używane do sadzenia kakao, pieczenia ciasteczek lub robienia brązowego barwnika.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym aby zafarbować wełnę owcy na brązowo. Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao.
Premature Cocoa Pod=Niedojrzała roślina kakao
Cocoa pods grow on the side of jungle trees in 3 stages.=Roślina kakao rośnie na bokach tropikalnych drzew w 3 etapach
Medium Cocoa Pod=Średnio-dojrzała roślina kakao

View File

@ -2,7 +2,7 @@
Cocoa Beans=Какао-бобы
Grows at the side of jungle trees=Растут на стволах тропических деревьев
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Какао-бобы можно использовать для посадки какао, выпечки печенья или изготовления коричневого красителя.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по боковой части ствола тропического дерева, чтобы посадить молодое какао.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по овце, чтобы сделать её шерсть коричневой. Кликните правой по боковой части ствола тропического дерева, чтобы посадить молодое какао.
Premature Cocoa Pod=Молодой стручок какао
Cocoa pods grow on the side of jungle trees in 3 stages.=Стручки какао растут на деревьях джунглей в 3 этапа.
Medium Cocoa Pod=Средний стручок какао

View File

@ -2,7 +2,7 @@
Cocoa Beans=可可豆
Grows at the side of jungle trees=在叢林木側生長
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=可可豆可用於種植可可、烘烤餅乾或製作棕色染料。
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=右鍵點擊叢林木的一側,可以種植一個可可。
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=右鍵點擊一隻羊,使其羊毛變成褐色。右鍵點擊叢林木的一側,可以種植一個可可。
Premature Cocoa Pod=成長中的可可豆莢第1階段
Cocoa pods grow on the side of jungle trees in 3 stages.=可可莢果分3個階段生長在叢林樹的側面。
Medium Cocoa Pod=成長中的可可豆莢第2階段

View File

@ -2,7 +2,7 @@
Cocoa Beans=
Grows at the side of jungle trees=
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=
Premature Cocoa Pod=
Cocoa pods grow on the side of jungle trees in 3 stages.=
Medium Cocoa Pod=

View File

@ -1,4 +1,4 @@
name = mcl_cocoas
description = Cocoa pods which grow at jungle trees. Does not include cocoa beans.
depends = mcl_sounds, mcl_core
optional_depends = doc
depends = mcl_sounds, mcl_core, mcl_util
optional_depends = doc

View File

@ -11,7 +11,7 @@ local composter_description = S(
"Composter"
)
local composter_longdesc = S(
"Composters can convert various organic items into bonemeal."
"Composters can convert various organic items into bone meal."
)
local composter_usagehelp = S(
"Use organic items on the composter to fill it with layers of compost. " ..
@ -48,6 +48,41 @@ local vector_offset = vector.offset
local is_protected = minetest.is_protected
local record_protection_violation = minetest.record_protection_violation
--- Math and node swap during compost progression
---@param pos Vector Position of the node
---@param node node
---@param chance integer Value of "compostability" group of inserted item
local function composter_progress_chance(pos, node, chance)
-- calculate leveling up chance
local rand = math.random(0,100)
if chance >= rand then
-- get current compost level
local level = registered_nodes[node.name]["_mcl_compost_level"]
-- spawn green particles above new layer
mcl_bone_meal.add_bone_meal_particle(vector_offset(pos, 0, level/8, 0))
-- update composter block
if level < 7 then
level = level + 1
else
level = "ready"
end
swap_node(pos, {name = "mcl_composters:composter_" .. level})
minetest.sound_play({name="default_grass_footstep", gain=0.4}, {
pos = pos,
gain= 0.4,
max_hear_distance = 16,
}, true)
-- a full composter becomes ready for harvest after one second
-- the block will get updated by the node timer callback set in node reg def
if level == 7 then
local timer = get_node_timer(pos)
if not timer:is_started() then
timer:start(1)
end
end
end
end
--- Fill the composter when rightclicked.
--
-- `on_rightclick` handler for composter blocks of all fill levels except
@ -86,41 +121,6 @@ local function composter_add_item(pos, node, player, itemstack, pointed_thing)
return itemstack
end
--- Math and node swap during compost progression
---@param pos Vector Position of the node
---@param node node
---@param chance integer Value of "compostability" group of inserted item
function composter_progress_chance(pos, node, chance)
-- calculate leveling up chance
local rand = math.random(0,100)
if chance >= rand then
-- get current compost level
local level = registered_nodes[node.name]["_mcl_compost_level"]
-- spawn green particles above new layer
mcl_dye.add_bone_meal_particle(vector_offset(pos, 0, level/8, 0))
-- update composter block
if level < 7 then
level = level + 1
else
level = "ready"
end
swap_node(pos, {name = "mcl_composters:composter_" .. level})
minetest.sound_play({name="default_grass_footstep", gain=0.4}, {
pos = pos,
gain= 0.4,
max_hear_distance = 16,
}, true)
-- a full composter becomes ready for harvest after one second
-- the block will get updated by the node timer callback set in node reg def
if level == 7 then
local timer = get_node_timer(pos)
if not timer:is_started() then
timer:start(1)
end
end
end
end
--- Update a full composter block to ready for harvesting.
--
-- `on_timer` handler. The timer is set in function 'composter_add_item'
@ -203,7 +203,7 @@ end
--
minetest.register_node("mcl_composters:composter", {
description = composter_description,
_tt_help = S("Converts organic items into bonemeal"),
_tt_help = S("Converts organic items into bone meal"),
_doc_items_longdesc = composter_longdesc,
_doc_items_usagehelp = composter_usagehelp,
paramtype = "light",

View File

@ -4,4 +4,4 @@ Composters can convert various organic items into bonemeal.=Les composteurs peuv
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=Utiliser des objets organiques sur le composteur pour le remplir de couches de compost. Chaque fois qu'un objet est mis dans le composteur, il y a une chance d'ajouter une nouvelle couche de compost au composteur. Certains objets ont une plus grande chance que d'autres d'ajouter une couche supplémentaire. Après l'avoir rempli de 7 couches de compost, le composteur est plein. Après un délai d'approximativement une seconde, le composteur est prêt et on peut récupérer la farine d'os. Cliquer droit le composteur permet de récupérer la farine d'os et de vider le composteur.
filled=rempli
ready for harvest=prêt pour la récolte
Converts organic items into bonemeal=Convertit les objets organiques en farine d'os.
Converts organic items into bone meal=Convertit les objets organiques en farine d'os.

View File

@ -4,4 +4,4 @@ Composters can convert various organic items into bonemeal.=コンポスター
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter."=コンポスターに有機物を入れて、堆肥の層を作りましょう。コンポスターに有機物を入れるたびに、次の堆肥の層が追加されるチャンスが起きます。 追加される確率がより高くなっているアイテムもいくつかあります。 7層分の堆肥が充填されると、コンポスターは満杯となります。その約1秒後に、骨粉を取り出せる準備が完了します。右クリックして骨粉を取り出すと、コンポスターは空になります。
filled=充足
ready for harvest=収穫可能
Converts organic items into bonemeal=有機物を骨粉に変える
Converts organic items into bone meal=有機物を骨粉に変える

View File

@ -4,4 +4,4 @@ Composters can convert various organic items into bonemeal.=Компостер
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=Используйте органические предметы на компостере, чтобы заполнить его слоями перегноя. Каждый раз когда в компостер попадает предмет, есть шанс что в компостере появится новый слой перегноя. Некоторые предметы имеют больший шанс на появление нового слоя. После заполнения 7 слоями перегноя, компостер можно опустошить, забрав из него костную муку. После задержки в одну секунду компостер будет готов и костная мука будет извлечена из него. Правым кликом по компостеру чтобы забрать костную муку.
filled=заполнен
ready for harvest=готов к сбору
Converts organic items into bonemeal=Перерабатывает органику в костную муку
Converts organic items into bone meal=Перерабатывает органику в костную муку

View File

@ -1,7 +1,7 @@
# textdomain: mcl_composters
Composter=
Composters can convert various organic items into bonemeal.=
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=
Composters can convert various organic items into bone meal.=
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=
filled=
ready for harvest=
Converts organic items into bonemeal=
Converts organic items into bone meal=

View File

@ -1,5 +1,5 @@
name = mcl_composters
author = kabou
description = Composters can convert various organic items into bonemeal.
depends = mcl_core, mcl_sounds, mcl_dye, mcl_hoppers
depends = mcl_core, mcl_sounds, mcl_bone_meal, mcl_hoppers
optional_depends = doc

File diff suppressed because it is too large Load Diff

View File

@ -280,6 +280,14 @@ function mcl_core.register_sapling(subname, description, longdesc, tt_help, text
nn == "mcl_core:podzol" or nn == "mcl_core:podzol_snow" or
nn == "mcl_core:dirt" or nn == "mcl_core:mycelium" or nn == "mcl_core:coarse_dirt"
end),
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
-- Saplings: 45% chance to advance growth stage
if math.random(1,100) <= 45 then
return mcl_core.grow_sapling(pos, n)
end
end,
node_placement_prediction = "",
_mcl_blast_resistance = 0,
_mcl_hardness = 0,

View File

@ -5,6 +5,8 @@ local modpath = minetest.get_modpath(modname)
-- by debiankaios
-- adapted for mcl2 by cora
local MAXIMUM_VINE_HEIGHT = 25
local wood_slab_groups = {handy = 1, axey = 1, material_wood = 1, wood_slab = 1}
local wood_stair_groups = {handy = 1, axey = 1, material_wood = 1, wood_stairs = 1}
@ -16,21 +18,36 @@ function generate_crimson_tree(pos)
minetest.place_schematic(pos,modpath.."/schematics/crimson_fungus_1.mts","random",nil,false,"place_center_x,place_center_z")
end
function grow_vines(pos, moreontop ,vine, dir)
function grow_vines(pos, moreontop, vine, dir)
-- Sanity checks
if dir == nil then dir = 1 end
local n
repeat
pos = vector.offset(pos,0,dir,0)
n = minetest.get_node(pos)
if n.name == "air" then
for i=0,math.max(moreontop,1) do
if minetest.get_node(pos).name == "air" then
minetest.set_node(vector.offset(pos,0,i*dir,0),{name=vine})
end
end
break
end
until n.name ~= "air" and n.name ~= vine
if not moreontop or moreontop < 1 then return false end
local allowed_nodes = {}
allowed_nodes[vine] = true
-- Find the root, tip and calculate height
local root,_,root_node = mcl_util.trace_nodes(pos, -dir, allowed_nodes, MAXIMUM_VINE_HEIGHT)
if not root then return false end
local tip,height,tip_node = mcl_util.trace_nodes(vector.offset(root, 0, dir, 0), dir, allowed_nodes, MAXIMUM_VINE_HEIGHT)
if not tip then return false end
local res = false
for i = 1,moreontop do
-- Check if we can grow into this position
if height >= MAXIMUM_VINE_HEIGHT then return res end
if tip_node.name ~= "air" then return res end
-- Update world map data
minetest.set_node(tip, {name = vine})
-- Move to the next position and flag that growth has occured
tip = vector.offset(tip, 0, dir, 0)
tip_node = minetest.get_node(tip)
height = height + 1
res = true
end
return res
end
local nether_plants = {
@ -83,17 +100,20 @@ minetest.register_node("mcl_crimson:warped_fungus", {
light_source = 1,
sounds = mcl_sounds.node_sound_leaves_defaults(),
node_placement_prediction = "",
on_rightclick = function(pos, node, pointed_thing, player, itemstack)
if pointed_thing:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
local nodepos = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
if nodepos.name == "mcl_crimson:warped_nylium" or nodepos.name == "mcl_nether:netherrack" then
local random = math.random(1, 5)
if random == 1 then
minetest.remove_node(pos)
generate_warped_tree(pos)
end
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local nodepos = minetest.get_node(vector.offset(pos, 0, -1, 0))
if nodepos.name == "mcl_crimson:warped_nylium" or nodepos.name == "mcl_nether:netherrack" then
local random = math.random(1, 5)
if random == 1 then
minetest.remove_node(pos)
generate_warped_tree(pos)
return true
end
end
return false
end,
_mcl_blast_resistance = 0,
})
@ -102,6 +122,12 @@ mcl_flowerpots.register_potted_flower("mcl_crimson:warped_fungus", {
name = "warped_fungus",
desc = S("Warped Fungus"),
image = "mcl_crimson_warped_fungus.png",
_on_bone_meal = function(itemstack, placer, pointed_thing)
local n = has_nylium_neighbor(pointed_thing.under)
if n then
minetest.set_node(pointed_thing.under,n)
end
end,
})
minetest.register_node("mcl_crimson:twisting_vines", {
@ -121,6 +147,9 @@ minetest.register_node("mcl_crimson:twisting_vines", {
fixed = { -3/16, -0.5, -3/16, 3/16, 0.5, 3/16 },
},
node_placement_prediction = "",
_on_bone_meal = function(itemstack, placer, pointed_thing)
return grow_vines(pointed_thing.under, math.random(1, 3),"mcl_crimson:twisting_vines")
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local pn = clicker:get_player_name()
if clicker:is_player() and minetest.is_protected(vector.offset(pos,0,1,0), pn or "") then
@ -141,26 +170,28 @@ minetest.register_node("mcl_crimson:twisting_vines", {
end
elseif clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
if not minetest.is_creative_enabled(clicker:get_player_name()) then
itemstack:take_item()
end
grow_vines(pos, math.random(1, 3),"mcl_crimson:twisting_vines")
return mcl_bone_meal.use_bone_meal(itemstack, clicker, {under=pos, above=pos})
end
return itemstack
end,
on_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under
local above = pointed_thing.above
local unode = minetest.get_node(under)
local unode_def = minetest.registered_nodes[unode.name]
local above = pointed_thing.above
local anode = minetest.get_node(above)
local anode_def = minetest.registered_nodes[anode.name]
if under.y < above.y then
minetest.set_node(above, {name = "mcl_crimson:twisting_vines"})
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
else
if unode.name == "mcl_crimson:twisting_vines" then
return minetest.registered_nodes[unode.name].on_rightclick(under, unode, placer, itemstack, pointed_thing)
end
elseif unode_def and unode_def.on_rightclick then
return unode_def.on_rightclick(under, unode, placer, itemstack, pointed_thing)
elseif anode_def and anode_def.on_rightclick then
return unode_def.on_rightclick(above, anode, placer, itemstack, pointed_thing)
end
return itemstack
end,
@ -168,7 +199,7 @@ minetest.register_node("mcl_crimson:twisting_vines", {
local above = vector.offset(pos,0,1,0)
local abovenode = minetest.get_node(above)
minetest.node_dig(pos, node, digger)
if abovenode.name == node.name and (not mcl_core.check_vines_supported(above, abovenode)) then
if abovenode.name == node.name then
minetest.registered_nodes[node.name].on_dig(above, node, digger)
end
end,
@ -211,6 +242,9 @@ minetest.register_node("mcl_crimson:weeping_vines", {
fixed = { -3/16, -0.5, -3/16, 3/16, 0.5, 3/16 },
},
node_placement_prediction = "",
_on_bone_meal = function(itemstack, placer, pointed_thing)
return grow_vines(pointed_thing.under, math.random(1, 3),"mcl_crimson:weeping_vines", -1)
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local pn = clicker:get_player_name()
if clicker:is_player() and minetest.is_protected(vector.offset(pos,0,1,0), pn or "") then
@ -231,26 +265,28 @@ minetest.register_node("mcl_crimson:weeping_vines", {
end
elseif clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
if not minetest.is_creative_enabled(clicker:get_player_name()) then
itemstack:take_item()
end
grow_vines(pos, math.random(1, 3),"mcl_crimson:weeping_vines", -1)
return mcl_bone_meal.use_bone_meal(itemstack, clicker, {under=pos, above=pos})
end
return itemstack
end,
on_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under
local above = pointed_thing.above
local unode = minetest.get_node(under)
local unode_def = minetest.registered_nodes[unode.name]
local above = pointed_thing.above
local anode = minetest.get_node(above)
local anode_def = minetest.registered_nodes[anode.name]
if under.y > above.y then
minetest.set_node(above, {name = "mcl_crimson:weeping_vines"})
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
else
if unode.name == "mcl_crimson:weeping_vines" then
return minetest.registered_nodes[unode.name].on_rightclick(under, unode, placer, itemstack, pointed_thing)
end
elseif unode_def and unode_def.on_rightclick then
return unode_def.on_rightclick(under, unode, placer, itemstack, pointed_thing)
elseif anode_def and anode_def.on_rightclick then
return unode_def.on_rightclick(above, anode, placer, itemstack, pointed_thing)
end
return itemstack
end,
@ -258,7 +294,7 @@ minetest.register_node("mcl_crimson:weeping_vines", {
local below = vector.offset(pos,0,-1,0)
local belownode = minetest.get_node(below)
minetest.node_dig(pos, node, digger)
if belownode.name == node.name and (not mcl_core.check_vines_supported(below, belownode)) then
if belownode.name == node.name then
minetest.registered_nodes[node.name].on_dig(below, node, digger)
end
end,
@ -393,6 +429,11 @@ minetest.register_node("mcl_crimson:warped_nylium", {
_mcl_hardness = 0.4,
_mcl_blast_resistance = 0.4,
_mcl_silk_touch_drop = true,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local node = minetest.get_node(pointed_thing.under)
spread_nether_plants(pointed_thing.under,node)
return true
end,
})
--Stem bark, stripped stem and bark
@ -525,17 +566,21 @@ minetest.register_node("mcl_crimson:crimson_fungus", {
fixed = { -3/16, -0.5, -3/16, 3/16, -2/16, 3/16 },
},
node_placement_prediction = "",
on_rightclick = function(pos, node, pointed_thing, player)
if pointed_thing:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
local nodepos = minetest.get_node(vector.offset(pos, 0, -1, 0))
if nodepos.name == "mcl_crimson:crimson_nylium" or nodepos.name == "mcl_nether:netherrack" then
local random = math.random(1, 5)
if random == 1 then
minetest.remove_node(pos)
generate_crimson_tree(pos)
end
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local nodepos = minetest.get_node(vector.offset(pos, 0, -1, 0))
if nodepos.name == "mcl_crimson:crimson_nylium" or nodepos.name == "mcl_nether:netherrack" then
local random = math.random(1, 5)
if random == 1 then
minetest.remove_node(pos)
generate_crimson_tree(pos)
return true
end
end
-- Failed to spread nylium
return false
end,
_mcl_blast_resistance = 0,
})
@ -682,6 +727,11 @@ minetest.register_node("mcl_crimson:crimson_nylium", {
_mcl_hardness = 0.4,
_mcl_blast_resistance = 0.4,
_mcl_silk_touch_drop = true,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local node = minetest.get_node(pointed_thing.under)
spread_nether_plants(pointed_thing.under,node)
return true
end,
})
minetest.register_craft({
@ -723,19 +773,6 @@ minetest.register_craft({
mcl_stairs.register_stair("crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", wood_stair_groups, false, S("Crimson Stair"))
mcl_stairs.register_slab("crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", wood_slab_groups, false, S("Crimson Slab"))
mcl_dye.register_on_bone_meal_apply(function(pt,user)
if not pt.type == "node" then return end
local node = minetest.get_node(pt.under)
if node.name == "mcl_nether:netherrack" then
local n = has_nylium_neighbor(pt.under)
if n then
minetest.set_node(pt.under,n)
end
elseif node.name == "mcl_crimson:warped_nylium" or node.name == "mcl_crimson:crimson_nylium" then
spread_nether_plants(pt.under,node)
end
end)
minetest.register_abm({
label = "Turn Crimson Nylium and Warped Nylium below solid block into Netherrack",
nodenames = {"mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium"},

View File

@ -1,3 +1,3 @@
name = mcl_crimson
author = debiankaios, Exhale
depends = mcl_core, mcl_stairs, mobs_mc, mcl_util, mcl_dye, mcl_flowerpots
depends = mcl_core, mcl_fences, mcl_stairs, mobs_mc, mcl_util, mcl_dye, mcl_flowerpots, mcl_doors

View File

@ -111,7 +111,7 @@ for _, p in pairs(deepslate_ores) do
end
if copper_mod then
register_deepslate_ore("Copper", "mcl_copper:raw_copper", "mcl_copper:copper_ingot", 4, 4)
register_deepslate_ore("Copper", "mcl_copper:raw_copper", "mcl_copper:copper_ingot", 3, 4)
end
local redstone_timer = 68.28

View File

@ -25,7 +25,7 @@ end
-- Registers a door
-- name: The name of the door
-- def: a table with the folowing fields:
-- def: a table with the following fields:
-- description
-- inventory_image
-- groups

View File

@ -1,14 +0,0 @@
# mcl_dye
# Bone meal API
Callback and particle functions.
## mcl_dye.add_bone_meal_particle(pos, def)
Spawns standard or custom bone meal particles.
* `pos`: position, is ignored if you define def.minpos and def.maxpos
* `def`: (optional) particle definition
## mcl_dye.register_on_bone_meal_apply(function(pointed_thing, user))
Called when the bone meal is applied anywhere.
* `pointed_thing`: exact pointing location (see Minetest API), where the bone meal is applied
* `user`: ObjectRef of the player who aplied the bone meal, can be nil!

View File

@ -15,7 +15,6 @@ mcl_dye = {}
local S = minetest.get_translator(minetest.get_current_modname())
local math = math
local string = string
-- Base color groups:
@ -115,328 +114,23 @@ for _, row in pairs(dyes) do
})
end
-- Bone meal code to be moved into its own mod.
-- Legacy support for things now in mcl_bone_meal.
-- These shims will at some time in the future be removed.
--
function mcl_dye.add_bone_meal_particle(pos, def)
if not def then
def = {}
minetest.log("warning", "mcl_dye.add_bone_meal_particles() is deprecated. Read mcl_bone_meal/API.md!")
local lines = string.split(debug.traceback(),"\n")
for _,line in ipairs(lines) do
minetest.log("warning",line)
end
minetest.add_particlespawner({
amount = def.amount or 10,
time = def.time or 0.1,
minpos = def.minpos or vector.subtract(pos, 0.5),
maxpos = def.maxpos or vector.add(pos, 0.5),
minvel = def.minvel or vector.new(-0.01, 0.01, -0.01),
maxvel = def.maxvel or vector.new(0.01, 0.01, 0.01),
minacc = def.minacc or vector.new(0, 0, 0),
maxacc = def.maxacc or vector.new(0, 0, 0),
minexptime = def.minexptime or 1,
maxexptime = def.maxexptime or 4,
minsize = def.minsize or 0.7,
maxsize = def.maxsize or 2.4,
texture = "mcl_particles_bonemeal.png^[colorize:#00EE00:125", -- TODO: real MC color
glow = def.glow or 1,
})
mcl_bone_meal.add_bone_meal_particle(pos, def)
end
mcl_dye.bone_meal_callbacks = {}
function mcl_dye.register_on_bone_meal_apply(func)
table.insert(mcl_dye.bone_meal_callbacks, func)
minetest.log("warning", "mcl_dye.register_on_bone_meal_apply() is deprecated. Read mcl_bone_meal/API.md!")
mcl_bone_meal.register_on_bone_meal_apply(func)
end
local function apply_bone_meal(pointed_thing, user)
-- Bone meal currently spawns all flowers found in the plains.
local flowers_table_plains = {
"mcl_flowers:dandelion",
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
"mcl_flowers:oxeye_daisy",
"mcl_flowers:tulip_orange",
"mcl_flowers:tulip_red",
"mcl_flowers:tulip_white",
"mcl_flowers:tulip_pink",
"mcl_flowers:azure_bluet",
}
local flowers_table_simple = {
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
}
local flowers_table_swampland = {
"mcl_flowers:blue_orchid",
}
local flowers_table_flower_forest = {
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
"mcl_flowers:oxeye_daisy",
"mcl_flowers:tulip_orange",
"mcl_flowers:tulip_red",
"mcl_flowers:tulip_white",
"mcl_flowers:tulip_pink",
"mcl_flowers:azure_bluet",
"mcl_flowers:allium",
}
local pos = pointed_thing.under
local n = minetest.get_node(pos)
if n.name == "" then return false end
if mcl_util.check_area_protection(pos, pointed_thing.above, user) then
return false
end
for _, func in pairs(mcl_dye.bone_meal_callbacks) do
if func(pointed_thing, user) then
return true
end
end
if minetest.get_item_group(n.name, "sapling") >= 1 then
mcl_dye.add_bone_meal_particle(pos)
-- Saplings: 45% chance to advance growth stage
if math.random(1, 100) <= 45 then
if n.name == "mcl_cherry_blossom:cherrysapling" then
return mcl_cherry_blossom.generate_cherry_tree(pos) -- If cherry blossom sapling, run that callback instead.
else
return mcl_core.grow_sapling(pos, n)
end
end
elseif minetest.get_item_group(n.name, "mushroom") == 1 then
mcl_dye.add_bone_meal_particle(pos)
-- Try to grow huge mushroom
-- Must be on a dirt-type block
local below = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
if below.name ~= "mcl_core:mycelium" and below.name ~= "mcl_core:dirt" and minetest.get_item_group(below.name, "grass_block") ~= 1 and below.name ~= "mcl_core:coarse_dirt" and below.name ~= "mcl_core:podzol" then
return false
end
-- Select schematic
local schematic, offset, height
if n.name == "mcl_mushrooms:mushroom_brown" then
schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_brown.mts"
offset = { x = -3, y = -1, z = -3 }
height = 8
elseif n.name == "mcl_mushrooms:mushroom_red" then
schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_red.mts"
offset = { x = -2, y = -1, z = -2 }
height = 8
else
return false
end
-- 40% chance
if math.random(1, 100) <= 40 then
-- Check space requirements
for i=1,3 do
local cpos = vector.add(pos, {x=0, y=i, z=0})
if minetest.get_node(cpos).name ~= "air" then
return false
end
end
local yoff = 3
local minp, maxp = {x=pos.x-3, y=pos.y+yoff, z=pos.z-3}, {x=pos.x+3, y=pos.y+yoff+(height-3), z=pos.z+3}
local diff = vector.subtract(maxp, minp)
diff = vector.add(diff, {x=1,y=1,z=1})
local totalnodes = diff.x * diff.y * diff.z
local goodnodes = minetest.find_nodes_in_area(minp, maxp, {"air", "group:leaves"})
if #goodnodes < totalnodes then
return false
end
-- Place the huge mushroom
minetest.remove_node(pos)
local place_pos = vector.add(pos, offset)
local ok = minetest.place_schematic(place_pos, schematic, 0, nil, false)
return ok ~= nil
end
return false
-- Wheat, Potato, Carrot, Pumpkin Stem, Melon Stem: Advance by 2-5 stages
elseif string.find(n.name, "mcl_farming:wheat_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_wheat", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:potato_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_potato", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:carrot_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_carrot", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:pumpkin_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_pumpkin_stem", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:melontige_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_melon_stem", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:beetroot_") then
mcl_dye.add_bone_meal_particle(pos)
-- Beetroot: 75% chance to advance to next stage
if math.random(1, 100) <= 75 then
return mcl_farming:grow_plant("plant_beetroot", pos, n, 1, true)
end
elseif string.find(n.name, "mcl_farming:sweet_berry_bush_") then
mcl_dye.add_bone_meal_particle(pos)
if n.name == "mcl_farming:sweet_berry_bush_3" then
return minetest.add_item(vector.offset(pos,math.random()-0.5,math.random()-0.5,math.random()-0.5),"mcl_farming:sweet_berry")
else
return mcl_farming:grow_plant("plant_sweet_berry_bush", pos, n, 0, true)
end
elseif n.name == "mcl_cocoas:cocoa_1" or n.name == "mcl_cocoas:cocoa_2" then
mcl_dye.add_bone_meal_particle(pos)
-- Cocoa: Advance by 1 stage
mcl_cocoas.grow(pos)
return true
elseif minetest.get_item_group(n.name, "grass_block") == 1 then
-- Grass Block: Generate tall grass and random flowers all over the place
for i = -7, 7 do
for j = -7, 7 do
for y = -1, 1 do
pos = vector.offset(pointed_thing.above, i, y, j)
n = minetest.get_node(pos)
local n2 = minetest.get_node(vector.offset(pos, 0, -1, 0))
if n.name ~= "" and n.name == "air" and (minetest.get_item_group(n2.name, "grass_block_no_snow") == 1) then
-- Randomly generate flowers, tall grass or nothing
if math.random(1, 100) <= 90 / ((math.abs(i) + math.abs(j)) / 2)then
-- 90% tall grass, 10% flower
mcl_dye.add_bone_meal_particle(pos, {amount = 4})
if math.random(1,100) <= 90 then
local col = n2.param2
minetest.add_node(pos, {name="mcl_flowers:tallgrass", param2=col})
else
local flowers_table
if mg_name == "v6" then
flowers_table = flowers_table_plains
else
local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome)
if biome == "Swampland" or biome == "Swampland_shore" or biome == "Swampland_ocean" or biome == "Swampland_deep_ocean" or biome == "Swampland_underground" then
flowers_table = flowers_table_swampland
elseif biome == "FlowerForest" or biome == "FlowerForest_beach" or biome == "FlowerForest_ocean" or biome == "FlowerForest_deep_ocean" or biome == "FlowerForest_underground" then
flowers_table = flowers_table_flower_forest
elseif biome == "Plains" or biome == "Plains_beach" or biome == "Plains_ocean" or biome == "Plains_deep_ocean" or biome == "Plains_underground" or biome == "SunflowerPlains" or biome == "SunflowerPlains_ocean" or biome == "SunflowerPlains_deep_ocean" or biome == "SunflowerPlains_underground" then
flowers_table = flowers_table_plains
else
flowers_table = flowers_table_simple
end
end
minetest.add_node(pos, {name=flowers_table[math.random(1, #flowers_table)]})
end
end
end
end
end
end
return true
-- Double flowers: Drop corresponding item
elseif n.name == "mcl_flowers:rose_bush" or n.name == "mcl_flowers:rose_bush_top" then
mcl_dye.add_bone_meal_particle(pos)
minetest.add_item(pos, "mcl_flowers:rose_bush")
return true
elseif n.name == "mcl_flowers:peony" or n.name == "mcl_flowers:peony_top" then
mcl_dye.add_bone_meal_particle(pos)
minetest.add_item(pos, "mcl_flowers:peony")
return true
elseif n.name == "mcl_flowers:lilac" or n.name == "mcl_flowers:lilac_top" then
mcl_dye.add_bone_meal_particle(pos)
minetest.add_item(pos, "mcl_flowers:lilac")
return true
elseif n.name == "mcl_flowers:sunflower" or n.name == "mcl_flowers:sunflower_top" then
mcl_dye.add_bone_meal_particle(pos)
minetest.add_item(pos, "mcl_flowers:sunflower")
return true
elseif n.name == "mcl_flowers:tallgrass" then
mcl_dye.add_bone_meal_particle(pos)
-- Tall Grass: Grow into double tallgrass
local toppos = { x=pos.x, y=pos.y+1, z=pos.z }
local topnode = minetest.get_node(toppos)
if minetest.registered_nodes[topnode.name].buildable_to then
minetest.set_node(pos, { name = "mcl_flowers:double_grass", param2 = n.param2 })
minetest.set_node(toppos, { name = "mcl_flowers:double_grass_top", param2 = n.param2 })
return true
end
--[[
Here for when Bonemeal becomes an api, there's code if needed for handling applying to bamboo.
-- Handle applying bonemeal to bamboo.
elseif mcl_bamboo.is_bamboo(n.name) then
local success = mcl_bamboo.grow_bamboo(pos, true)
if success then
mcl_dye.add_bone_meal_particle(pos)
end
return success
--]]
elseif n.name == "mcl_flowers:fern" then
mcl_dye.add_bone_meal_particle(pos)
-- Fern: Grow into large fern
local toppos = { x=pos.x, y=pos.y+1, z=pos.z }
local topnode = minetest.get_node(toppos)
if minetest.registered_nodes[topnode.name].buildable_to then
minetest.set_node(pos, { name = "mcl_flowers:double_fern", param2 = n.param2 })
minetest.set_node(toppos, { name = "mcl_flowers:double_fern_top", param2 = n.param2 })
return true
end
end
return false
end
mcl_dye.apply_bone_meal = apply_bone_meal
-- Bone meal item registration.
--
-- To be moved into its own mod.
--
minetest.register_craftitem(":mcl_bone_meal:bone_meal", {
inventory_image = "mcl_bone_meal_bone_meal.png",
description = S("Bone Meal"),
_tt_help = S("Speeds up plant growth"),
_doc_items_longdesc = S("Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants."),
_doc_items_usagehelp = S("Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place."),
stack_max = 64,
on_place = function(itemstack, user, pointed_thing)
-- Use pointed node's on_rightclick function first, if present
local node = minetest.get_node(pointed_thing.under)
if user and not user:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack
end
end
-- Use the bone meal on the ground
if (apply_bone_meal(pointed_thing, user) and (not minetest.is_creative_enabled(user:get_player_name()))) then
itemstack:take_item()
end
return itemstack
end,
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
-- Apply bone meal, if possible
local pointed_thing
if dropnode.name == "air" then
pointed_thing = { above = droppos, under = { x=droppos.x, y=droppos.y-1, z=droppos.z } }
else
pointed_thing = { above = pos, under = droppos }
end
local success = apply_bone_meal(pointed_thing, nil)
if success then
stack:take_item()
end
return stack
end,
_dispense_into_walkable = true
})
minetest.register_craft({
output = "mcl_bone_meal:bone_meal 3",
recipe = {{"mcl_mobitems:bone"}},
})
-- Dye creation recipes.
--
minetest.register_craft({
@ -609,19 +303,16 @@ minetest.register_craft({
output = "mcl_dye:magenta 2",
recipe = {"mcl_dye:violet", "mcl_dye:pink"},
})
minetest.register_craft({
type = "shapeless",
output = "mcl_dye:pink 2",
recipe = {"mcl_dye:red", "mcl_dye:white"},
})
minetest.register_craft({
type = "shapeless",
output = "mcl_dye:cyan 2",
recipe = {"mcl_dye:blue", "mcl_dye:dark_green"},
})
minetest.register_craft({
type = "shapeless",
output = "mcl_dye:violet 2",

View File

@ -17,11 +17,3 @@ Magenta Dye=Magenta Farbstoff
Pink Dye=Rosa Farbstoff
This item is a dye which is used for dyeing and crafting.=Dieser Gegenstand ist ein Farbstoff, der zum Einfärben und in der Herstellung benutzt werden kann.
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Rechtsklicken Sie auf ein Schaf, um seine Wolle zu färben. Andere Dinge werden mit der Fertigung eingefärbt.
Bone Meal=Knochenmehl
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Knochenmehl ist ein weißer Farbstoff und auch nützlich als Dünger, um das Wachstum vieler Pflanzen zu beschleunigen.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Rechtsklicken Sie auf ein Schaf, um die Wolle weiß einzufärben. Rechtsklicken Sie auf eine Pflanze, um ihr Wachstum zu beschleunigen. Beachten Sie, dass nicht alle Pflanzen darauf ansprechen. Benutzen Sie es auf einem Grasblock, wächst viel hohes Gras und vielleicht auch ein paar Blumen.
Cocoa beans are a brown dye and can be used to plant cocoas.=Kakaobohnen sind ein brauner Farbstoff und werden benutzt, um Kakao anzupflanzen.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Rechtsklicken Sie auf ein Schaf, um die Wolle braun einzufärben. Rechtsklicken Sie an die Seite eines Dschungelbaumstamms (Dschungelholz), um eine junge Kakaoschote zu pflanzen.
Cocoa Beans=Kakaobohnen
Grows at the side of jungle trees=Wächst an der Seite von Dschungelbäumen
Speeds up plant growth=Beschleunigt Pflanzenwachstum

View File

@ -17,9 +17,3 @@ Magenta Dye=Tinte magenta
Pink Dye=Tinte rosado
This item is a dye which is used for dyeing and crafting.=Este artículo es un tinte que se utiliza para teñir y elaborar.
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Haga clic derecho sobre una oveja para teñir su lana. Otras cosas pueden ser teñidas mediante la elaboración.
Bone Meal=Harina de hueso
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=La harina de hueso es un tinte blanco y también es útil como fertilizante para acelerar el crecimiento de muchas plantas.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=RHaga clic derecho en una oveja para volver su lana blanca. Haga clic derecho en una planta para acelerar su crecimiento. Tenga en cuenta que no todas las plantas pueden ser fertilizadas de esta manera. Cuando haces clic derecho en un bloque de hierba, crecerán hierba alta y flores por todo el lugar.
Cocoa beans are a brown dye and can be used to plant cocoas.=Los granos de cacao son un tinte marrón y se pueden usar para plantar cacao.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Haga clic derecho en una oveja para convertir su lana en marrón. Haga clic derecho en el costado del tronco de un árbol de jungla para plantar un cacao joven.
Cocoa Beans=Granos de cacao

View File

@ -17,11 +17,3 @@ Magenta Dye=Teinture Magenta
Pink Dye=Teinture Rose
This item is a dye which is used for dyeing and crafting.=Cet objet est un colorant utilisé pour la teinture et l'artisanat.
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Clic droit sur un mouton pour teindre sa laine. D'autres choses sont teintes par l'artisanat.
Bone Meal=Farine d'Os
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=La farine d'os est une teinture blanche et également utile comme engrais pour accélérer la croissance de nombreuses plantes.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Cliquez avec le bouton droit sur un mouton pour blanchir sa laine. Cliquez avec le bouton droit sur une plante pour accélérer sa croissance. Notez que toutes les plantes ne peuvent pas être fertilisées comme ça. Lorsque vous cliquez avec le bouton droit sur un bloc d'herbe, les hautes herbes et les fleurs poussent partout.
Cocoa beans are a brown dye and can be used to plant cocoas.=Les fèves de cacao ont une teinture brune et peuvent être utilisées pour planter du cacao.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Faites un clic droit sur un mouton pour brunir sa laine. Clic droit sur le côté d'un tronc d'arbre de la jungle (Bois Acajou) pour planter un jeune cacao.
Cocoa Beans=Fèves de Cacao
Grows at the side of jungle trees=Pousse à côté des arbres de la jungle
Speeds up plant growth=Accélère la croissance des plantes

View File

@ -17,11 +17,3 @@ Magenta Dye=Karmazynowa farba
Pink Dye=Różowa farba
This item is a dye which is used for dyeing and crafting.=Ten przedmiot to farba wykorzystywana to farbowania i wytwarzania.
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Kliknij prawym na owcę aby zafarbować jej wełnę. Inne rzeczy mogą być zafarbowane przy wytwarzaniu.
Bone Meal=Mączka kostna
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Mączka kostna to biała farba i przydatny nawóz, który przyspiesza rośnięcie wielu roślin.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Kliknij prawym na owcę, aby wybielić jej wełnę. Kliknij prawym na roślinę aby przyspieszyć jej wzrost. Zważ, że nie na wszystkie rośliny to tak działa. Gdy klikniesz prawym na blok trawy, wysoka trawa wyrośnie wokół.
Cocoa beans are a brown dye and can be used to plant cocoas.=Ziarna kakaowe mogą być wykorzystane do sadzenia kakao.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym aby zafarbować wełnę owcy na brązowo. Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao.
Cocoa Beans=Ziarna kakaowe
Grows at the side of jungle trees=Rośnie na boku tropikalnych drzew
Speeds up plant growth=Przyspiesza wzrost roślin

View File

@ -22,6 +22,3 @@ Bone meal is a white dye and also useful as a fertilizer to speed up the growth
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Кликните правой по овце, чтобы сделать её шерсть белой. Кликните правой по растению, чтобы ускорить его рост. Имейте в виду, что не все растения можно удобрять таким способом. Если вы кликнете по травяному блоку, то на этом месте вырастет высокая трава и цветы.
Cocoa beans are a brown dye and can be used to plant cocoas.=Какао-бобы являются коричневым красителем. Их также можно использовать, чтобы посадить какао.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по овце, чтобы сделать её шерсть коричневой. Кликните правой по боковой части ствола тропического дерева, чтобы посадить молодое какао.
Cocoa Beans=Какао-бобы
Grows at the side of jungle trees=Растут на стволах тропических деревьев
Speeds up plant growth=Ускоряет рост растений

View File

@ -17,9 +17,3 @@ Magenta Dye=洋紅色染料
Pink Dye=粉紅色染料
This item is a dye which is used for dyeing and crafting.=這個物品是一種用於染色和合成的染料。
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=右鍵單擊綿羊以染它的毛。其他東西是通過合成染色的。
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=骨粉是一種白色染料,也可作為肥料,加速許多植物的生長。
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=右鍵點擊一隻羊,使其羊毛變白。右鍵點擊一株植物以加快其生長速度。注意,不是所有的植物都能像這樣施肥。當你右鍵點擊一個草方時,高高的草和花會到處生長。
Cocoa beans are a brown dye and can be used to plant cocoas.=可可豆是一種棕色染料,也可用於種植可可。
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=右鍵點擊一隻羊,使其羊毛變成褐色。右鍵點擊叢林木的一側,可以種植一個可可。
Grows at the side of jungle trees=在叢林木側生長
Speeds up plant growth=加速植物生長

View File

@ -17,11 +17,3 @@ Magenta Dye=
Pink Dye=
This item is a dye which is used for dyeing and crafting.=
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=
Bone Meal=
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=
Cocoa beans are a brown dye and can be used to plant cocoas.=
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=
Cocoa Beans=
Grows at the side of jungle trees=
Speeds up plant growth=

View File

@ -1,2 +1,3 @@
name = mcl_dye
depends = mcl_core, mcl_flowers, mcl_mobitems, mcl_cocoas
description = Adds color to your world!
depends = mcl_bone_meal, mcl_cocoas

View File

@ -691,7 +691,7 @@ mcl_enchanting.enchantments.soul_speed = {
disallow = {non_combat_armor = true},
incompatible = {frost_walker = true},
weight = 2,
description = S("Increases walking speed on soul sand."),
description = S("Increases walking speed on soul sand and soul soil."),
curse = false,
on_enchant = function() end,
requires_tool = false,

View File

@ -68,7 +68,7 @@ Mined blocks drop themselves.=Abgebaute Blöcke werfen sich selbst ab.
Smite=Qual
Increases damage to undead mobs.=Erhöht Schaden für untote Mobs.
Soul Speed=Schnelle Seele
Increases walking speed on soul sand.=Erhöht Gehgeschwindigkeit auf Seelensand.
Increases walking speed on soul sand and soul soil.=Erhöht Gehgeschwindigkeit auf Seelensand.
Sweeping Edge=Schwungklinge
Increases sweeping attack damage.=Erhöht Schwungangriffsschaden.
Thorns=Dornen

View File

@ -36,7 +36,7 @@ Increases mob loot.=Incrementa el botín de los enemigos.
Increases rate of good loot (enchanting books, etc.)=Incrementa la probabilidad de encontrar tesoros.
Increases sweeping attack damage.=Incrementa el daño de efecto area.
Increases underwater movement speed.=Incrementa la velocidad de nado bajo el agua.
Increases walking speed on soul sand.=Incrementa la velocidad al caminar sobre arena de Almas.
Increases walking speed on soul sand and soul soil.=Incrementa la velocidad al caminar sobre arena de Almas.
Infinity=Infinidad
Item destroyed on death.=El objeto se destruye tras tu muerte.
Knockback=Empuje

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