Compare commits

...

265 Commits

Author SHA1 Message Date
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
JoseDouglas26 38822aba0a Piglin brutes are not immune to fire and lava (#4378)
Thank you again WillConker

Reviewed-on: VoxeLibre/VoxeLibre#4378
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: JoseDouglas26 <josedouglas20002014@gmail.com>
Co-committed-by: JoseDouglas26 <josedouglas20002014@gmail.com>
2024-09-08 14:01:05 +02:00
kno10 d85febdb15 Cactus damage cleanup, drop redundant conditions (#4625)
Reviewed-on: VoxeLibre/VoxeLibre#4625
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-08 05:21:42 +02:00
Mikita Wiśniewski fb4a6b0e7b Fix old angled heads not being converted (#4627)
Reviewed-on: VoxeLibre/VoxeLibre#4627
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-08 04:26:51 +02:00
the-real-herowl dd4f3d21eb Merge pull request 'Alias creeper heads to stalker heads & Refactor mcl_heads (closes #4545)' (#4602) from goodspeed/VoxeLibre:stalker-head into master
Reviewed-on: VoxeLibre/VoxeLibre#4602
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-09-07 16:08:20 +02:00
William Goodspeed 2f25bc5277 Refactor head's `param2' to degrotate 2024-09-07 15:56:44 +02:00
William Goodspeed 5d0d93db0a Alias creeper heads to stalker heads
This solves the issue of creeper heads in the old version not getting
upgraded with newer VL reported in #4545.
2024-09-07 15:56:44 +02:00
kno10 ebee85db7e Fix incorrect usages of math.random (#4621)
random() does not support float arguments

Reviewed-on: VoxeLibre/VoxeLibre#4621
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-07 14:58:12 +02:00
kno10 593a095a5f Fix "generateImagePart" warning (#4624)
Placing the texture at -16 with width 16 means it is not used. At most -14 may be used (0 indexed, I believe) if you want to retain 2x2 pixels.

Reviewed-on: VoxeLibre/VoxeLibre#4624
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-05 09:31:03 +02:00
teknomunk e9bf509c85 Add crash guards against unknown items (#4623)
This adds defensive checks to guard against crashing when digging with an unknown item in hand.

Reviewed-on: VoxeLibre/VoxeLibre#4623
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-08-31 23:41:06 +02:00
kno10 444c491e14 Remove mcl_structures:structblocks (#4619)
As spawning happens via gennotify anyway, we can omit placing a
structblock right away.

This also avoids certain cases of holes in snow cover or water.
Plus, the code is simpler.

Isolated from the big mapgen overhaul, for the main branch.

Reviewed-on: VoxeLibre/VoxeLibre#4619
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-08-31 21:01:44 +02:00
the-real-herowl 05bfe5513f Merge pull request 'Convert stairs to nodebox and use world-aligned tiling (fixes #4578)' (#4588) from nodebox_stairs into master
Reviewed-on: VoxeLibre/VoxeLibre#4588
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
2024-08-31 19:54:02 +02:00
codiac 562a9d6d98 Convert stairs to nodebox 2024-08-31 19:52:41 +02:00
cora 0e4b8d9c27 Fix some cornerstairs missing textures 2024-08-31 19:52:41 +02:00
the-real-herowl 93165a042b Merge pull request 'Fix Honeycomb Right-click' (#4614) from fix-honeycomb into master
Reviewed-on: VoxeLibre/VoxeLibre#4614
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-08-31 19:43:41 +02:00
teknomunk 3e85736404 Change honeycomb to use same right-click logic recently added to buckets and bottles 2024-08-31 19:37:14 +02:00
teknomunk f10827d0d6 Rework code 2024-08-31 19:37:14 +02:00
teknomunk f9cd2500c0 Don't crash trying to right click unknown nodes while holding honeycomb 2024-08-31 19:37:14 +02:00
teknomunk 64c04a2f0a Fix #4613 2024-08-31 19:37:14 +02:00
kno10 ecfa42d51d Update railcorridors, enable chest minecarts (#4620)
Minecart chests seem to work by now.

Reviewed-on: VoxeLibre/VoxeLibre#4620
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-08-31 19:36:18 +02:00
kno10 2dadfda76b Drop old (and disabled by default) fallen logs. (#4618)
There are better ones enabled in mods/MAPGEN/mcl_terrain_features/init.lua

Reviewed-on: VoxeLibre/VoxeLibre#4618
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-08-31 19:35:16 +02:00
the-real-herowl d888e832ae Merge pull request 'Update German Translations' (#4529) from teknomunk/MineClone2:update-german-translations into master
Reviewed-on: VoxeLibre/VoxeLibre#4529
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
2024-08-31 19:25:58 +02:00
teknomunk 8e37f34b93 Fix swapped translations 2024-08-31 09:57:45 -05:00
teknomunk 88be86ab4b Remove stray merge conflict marking, add two additional empty translations to match template.txt 2024-08-31 16:39:43 +02:00
teknomunk 316d5bf197 Address review comments on translations/grammar 2024-08-31 16:39:43 +02:00
teknomunk bc00b8d11b Finish restoring inadvertently removed translations 2024-08-31 16:39:43 +02:00
teknomunk 0743112317 Remove extra line at end of file 2024-08-31 16:39:43 +02:00
teknomunk 0a83c73fe0 Restore inadvertantly removed translations 2024-08-31 16:39:43 +02:00
teknomunk 8a3ef9d4c8 Last three German translations for #4529 2024-08-31 16:39:43 +02:00
teknomunk 757d6761b2 Add German translations for mcl_crimson, update template.txt 2024-08-31 16:39:43 +02:00
teknomunk 15003b1c55 Fix orange->orange(r/s) where needed, synchronize mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.de.tr with template.txt 2024-08-31 16:39:43 +02:00
teknomunk 485bce3df6 Add German translations of for part of the item descriptions 2024-08-31 16:39:43 +02:00
teknomunk 66a3fcb33c Add corrections to existing German translations 2024-08-31 16:39:43 +02:00
teknomunk 38585154cd Make German translation of mcl_stairs match template.txt 2024-08-31 16:39:43 +02:00
teknomunk 161655e87c Add German translation for mcl_target 2024-08-31 16:39:43 +02:00
teknomunk b072557a6a Add German translation for Suspicious Stew 2024-08-31 16:39:43 +02:00
teknomunk 157d72b593 Add German translation for mcl_spyglass 2024-08-31 16:39:43 +02:00
teknomunk 76b28a4fc5 Add German translations to mesecons_button 2024-08-31 16:39:43 +02:00
teknomunk 92d823deaf Add German translations for Netherite Scrap/Ingot 2024-08-31 16:39:43 +02:00
teknomunk c65bd27ad8 Add German translation for mcl_lightning_rods 2024-08-31 16:39:43 +02:00
teknomunk 398eb35858 Add German translations for mcl_honey 2024-08-31 16:39:43 +02:00
teknomunk 763902a877 Add German translation for mcl_grindstone 2024-08-31 16:39:43 +02:00
teknomunk 140d9014a0 Add new German translations to mesecons_pressureplates 2024-08-31 16:39:43 +02:00
teknomunk 043dc4487c Add more German translations to mcl_raw_ores 2024-08-31 16:39:43 +02:00
teknomunk cf6ee14e13 Add more German translations to vl_hollow_logs 2024-08-31 16:39:43 +02:00
teknomunk be69fdef8d Add new german translations for mcl_copper 2024-08-31 16:39:43 +02:00
teknomunk 6935bc2a18 Make mcl_copper.de.tr match template.txt 2024-08-31 16:39:43 +02:00
teknomunk 37d6ba392c Add more german translations for bamboo nodes 2024-08-31 16:39:43 +02:00
teknomunk 07bebe6c46 Add the new german translations for crimson/warped 2024-08-31 16:39:43 +02:00
teknomunk 63036c8d41 Update german translation for crimson/warped nodes 2024-08-31 16:39:43 +02:00
teknomunk 45b8d36f73 Add german translations for cherry tree blocks 2024-08-31 16:39:43 +02:00
teknomunk a44d8f43db Add missing trim in translation list 2024-08-31 16:39:43 +02:00
teknomunk 55b5dee827 Convert spaces to tabs 2024-08-31 16:39:43 +02:00
teknomunk adf64e81cd Allow translating trim names, add some German translations of trims 2024-08-31 16:39:43 +02:00
teknomunk 2b44abbceb More translations 2024-08-31 16:39:43 +02:00
teknomunk e9632b5317 Start adding next round of German translations 2024-08-31 16:39:43 +02:00
teknomunk df42751ae6 Add last of this latest round of new German translations provided by Laudrin 2024-08-31 16:39:43 +02:00
teknomunk 576662d719 Add Spectre Membrane to localization template 2024-08-31 16:39:43 +02:00
teknomunk 6b13612318 Fix typo in translated string 2024-08-31 16:39:43 +02:00
teknomunk 8861ad935b More translations entered 2024-08-31 16:39:43 +02:00
teknomunk 66a6d213ba Add more German translations from Laudrin 2024-08-31 16:39:43 +02:00
teknomunk 7fc7758b62 Add translation support to mcl_compressed_blocks 2024-08-31 16:39:43 +02:00
teknomunk 7aa8a4dd11 Last of the translations provided that have existing translation code for translating strings 2024-08-31 16:39:43 +02:00
teknomunk ec56e4ec1b Enter more translations 2024-08-31 16:39:43 +02:00
teknomunk 3193bb5d93 Start installing the German translations from #4333 2024-08-31 16:39:43 +02:00
kno10 573269afab Bug fix in tooltips for unknown items (#4610)
Reviewed-on: VoxeLibre/VoxeLibre#4610
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-08-31 10:18:12 +02:00
kno10 12214c5bd6 Allow salmon, tropical fish, witch huts in rivers (#4605)
As witch huts use flag "liquid_surface", place_on only can be water. If we want on-shore witch huts, this needs to be solved differently.
Also, probably no witch huts in deep ocean swamp water?

Reviewed-on: VoxeLibre/VoxeLibre#4605
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-08-31 10:16:43 +02:00
the-real-herowl 6dad5afec5 Merge pull request 'Correct the names of pumpkins and carved pumpkins. Slightly update their descriptions.' (#3828) from fix_pumpkin_names into master
Reviewed-on: VoxeLibre/VoxeLibre#3828
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-08-30 18:27:16 +02:00
the-real-herowl 508811d3b3 Fixed Polish and German translations 2024-08-30 18:26:18 +02:00
SmokeyDope 411cb2b9b9 Correct the names of pumpins and carved pumpkins. Slightly update their descriptions. 2024-08-30 18:26:18 +02:00
kno10 8fd736e0fd Improve cactus drops and spawning (#4581)
- breaking cactus will drop randomly in x=-0.75..+0.75, z=-0.75..+0.75
- breaking cactus will have an initial velocity in this direction
- if a larger cactus break, they break into the same direction
- cactus growth rate reduced 4x, to debuff farm efficiency (will need a larger rebalancing)
- cactus only spawns when there is air surrounding it and above, so it does not immediately break
- slightly increase the frequency of cactus to counter this

The first changes make cactus farms possible.

Reviewed-on: VoxeLibre/VoxeLibre#4581
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-08-30 18:22:05 +02:00
kno10 d2b96b6142 Queue is not used anywhere (#4608)
Dead code.

Reviewed-on: VoxeLibre/VoxeLibre#4608
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-08-30 18:20:38 +02:00
the-real-herowl a3cc105fa1 Merge pull request 'Fix Cauldrons' (#4615) from fix-cauldrons into master
Reviewed-on: VoxeLibre/VoxeLibre#4615
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-08-30 16:12:55 +02:00
teknomunk 5b039f1855 Fix getting water back into bottle 2024-08-28 06:30:12 -05:00
teknomunk 7e832dc641 Fix adding water bottles and emptying full cauldrons 2024-08-28 06:17:53 -05:00
the-real-herowl 91cecca135 Merge pull request 'Fix for fortune drops in mcl_farming from MCLA' (#4594) from farming_fortune_fix into master
Reviewed-on: VoxeLibre/VoxeLibre#4594
Reviewed-by: teknomunk <teknomunk@protonmail.com>
2024-08-27 16:28:39 +02:00
JoseDouglas26 95653a0676 ipairs to pairs 2024-08-27 13:11:08 +02:00
JoseDouglas26 b141f7c0a4 new special field to solve drop bug 2024-08-27 13:11:08 +02:00
the-real-herowl cf9bbb0551 Merge pull request 'mcl_weather sky color refactor' (#4338) from teknomunk/MineClone2:skycolor-refactor into master
Reviewed-on: VoxeLibre/VoxeLibre#4338
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-08-19 03:34:59 +02:00
teknomunk aea9e6d182 Update comment according to VoxeLibre/VoxeLibre#4338 (comment) 2024-08-19 03:02:02 +02:00
teknomunk 09307292bc Make sure overworld always gets a sky update regardless of weather, add assert to enforce sky color gets set every update 2024-08-19 03:02:02 +02:00
teknomunk e407e2e290 Force has_mcl_potions to boolean 2024-08-19 03:02:02 +02:00
teknomunk 87a48270f5 Add mcl_util.to_bool 2024-08-19 03:02:02 +02:00
teknomunk 21a88be2b2 Remove boolean coersion 2024-08-19 03:02:02 +02:00
teknomunk 37ff699a23 Add line break 2024-08-19 03:02:02 +02:00
teknomunk 18266137b2 Make sure clouds don't disappear when entering water 2024-08-19 03:02:02 +02:00
teknomunk 3667feddd3 Address review comments 2024-08-19 03:02:02 +02:00
teknomunk dc074ff555 Remove debug logging 2024-08-19 03:02:02 +02:00
teknomunk 0e1a2cbc1e Correct conditions for water-air transition forced skycolor update 2024-08-19 03:02:02 +02:00
teknomunk cb097d9bcd Add minimum time between skycolor updates (default is 250ms, tracked per player) 2024-08-19 03:02:02 +02:00
Wbjitscool cd213b75f7 Update mods/ENVIRONMENT/mcl_weather/skycolor.lua
adds in sunray shader support for Minetest version 5.9.0
2024-08-19 03:02:02 +02:00
teknomunk ef58a9809a Remove empty else block, fix up mg_name and add mapgen check to water.lua 2024-08-19 03:02:02 +02:00
teknomunk 3b01fe20ba Remove debug commented out logging, remove extra zero in 24-hour time 2024-08-19 03:02:02 +02:00
teknomunk d34c804ebf Remove local mod = mcl_weather and replace accesses to variables thru mcl_weather with local variable equivalents 2024-08-19 03:02:02 +02:00
teknomunk 03faa7764d Fix variable name (caused crash) 2024-08-19 03:02:02 +02:00
teknomunk 207c86b813 Fix crash and rearrange code 2024-08-19 03:02:02 +02:00
teknomunk cf4b1dbd1d Remove END function comment 2024-08-19 03:02:02 +02:00
teknomunk 7811e23611 Convert to use mcl_playerinfo 2024-08-19 03:02:02 +02:00
teknomunk 24ff7347b2 Further cleanup 2024-08-19 03:02:02 +02:00
teknomunk 820848fb2e Address review comments 2024-08-19 03:02:02 +02:00
teknomunk f2a638f8e9 Fix random crash in darkness effect in mcl_potions, finish refactoring of mcl_weather.skycolor that also makes darkness effect more reliable 2024-08-19 03:02:02 +02:00
teknomunk 161dd7d379 Start refactor 2024-08-19 03:02:02 +02:00
the-real-herowl d0e8b4141d Merge pull request 'Merge mcla kelp growing' (#4474) from WillConker/VoxeLibre:kelp_make_source into master
Reviewed-on: VoxeLibre/VoxeLibre#4474
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-08-18 21:47:46 +02:00
cora 15fa3ff775 Fix crash when growing kelp into water logged mangrove roots 2024-08-18 19:21:19 +02:00
WillConker 11168f226a Revert "WaterLoggedRootsKelpFix (#3994)"
This reverts commit a425d359f5.
2024-08-18 19:21:19 +02:00
teknomunk 2ad59c6df9 Stop lightning striking positions that don't have rain (#4386)
Stops lighting from being able to strike in locations where rain doesn't occur, but allows lightning in adjacent areas where is allowed.

Reviewed-on: VoxeLibre/VoxeLibre#4386
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-08-18 12:05:35 +02:00
the-real-herowl 948da34755 Readded missing stairs and slabs (#4601)
Also *probably* fixed their blast res and hardness

Reviewed-on: VoxeLibre/VoxeLibre#4601
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: the-real-herowl <wiktor_t-i@proton.me>
Co-committed-by: the-real-herowl <wiktor_t-i@proton.me>
2024-08-18 08:45:49 +02:00
WillConker 406e0e8169 Made soul speed and depth strider speed boosts additive instead of exclusive (#4422)
Reviewed-on: VoxeLibre/VoxeLibre#4422
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: WillConker <waj01@joanes.net>
Co-committed-by: WillConker <waj01@joanes.net>
2024-08-18 06:25:04 +02:00
the-real-herowl 09aba760cf Merge pull request 'Minor fixes on potion behavior on damage disabled servers (closes 4586)' (#4599) from goodspeed/VoxeLibre:potion-hud into master
Reviewed-on: VoxeLibre/VoxeLibre#4599
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-08-18 05:49:44 +02:00
William Goodspeed a6136ad158 Removing absorption bar on damage disabled servers
The absorption effect won't work on damage disabled servers and the
health bar and hunger bar is also hidden leaving the absorption bar
alone which makes it look not good. So not initializing it on those
servers might be a good idea.
2024-08-18 05:48:37 +02:00
William Goodspeed 77bcf6cff3 Allowing `hb.change_bar' called with hudbar uninitialized
Calling `hb.change_bar' with hunger bar on damage disabled server
will crash the server. To not overload other functions to check
`enable_damage' over and over, simply make `hb.change_bar' able to be
called with uninitialized identifiers. #4586
2024-08-18 05:48:37 +02:00
WillConker 293eb6d021 Stop tnt colliding with entities (#4476)
Reviewed-on: VoxeLibre/VoxeLibre#4476
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: WillConker <waj01@joanes.net>
Co-committed-by: WillConker <waj01@joanes.net>
2024-08-18 05:40:25 +02:00
the-real-herowl 1c5f7d05fe Merge pull request 'More hardness and blast resistance fixes' (#3952) from hardness_blast_res_fixes into master
Reviewed-on: VoxeLibre/VoxeLibre#3952
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-08-18 04:52:39 +02:00
seventeenthShulker f8fcd9954f Add back *some* changes that I reverted; and fix typo "Cherry Gate" 2024-08-18 04:47:19 +02:00
seventeenthShulker 8b9666137d All wood-type and nether-type fences now match material's blast resistance 2024-08-18 04:47:19 +02:00
seventeenthShulker b3087118fa Fix Gilded Blackstone blast res. (now 6) 2024-08-18 04:47:19 +02:00
seventeenthShulker b79a19f4d6 Add crimson/warped planks (_hyphae_wood) blast res
Relates to (#4414)
2024-08-18 04:47:19 +02:00
seventeenthShulker b0b5cc1265 Remaining stairs/slabs inherit properties instead of hardcoding
- Fix smooth quartz attributes
- Alternative recipes for (red) sandstone, quartz, purpur slabs/stairs have been added explicitly
2024-08-18 04:47:19 +02:00
seventeenthShulker b237c4642d Revert "Forgot about blackstone"
I left it in from another branch, didn't want to force push.

This reverts commit 58d2f59192.

Revert "Walls use `source` parameter for default hardness and blast resistance"
I left it in from another branch, didn't want to force push.

This reverts commit e8944cc145.

Revert "Fix prismarine bricks and dark variant blast res."
I left it in from another branch, didn't want to force push.

This reverts commit 6125d625bc.

Revert "Un-hardcode blast resistance, hardness for walls,"
I left it in from another branch, didn't want to force push.

This reverts commit 26e8737031.

Revert "All wood-type and nether-type fences now match material's blast resistance"
I left it in from another branch, didn't want to force push.

This reverts commit a1e20f2916.
2024-08-18 04:47:19 +02:00
seventeenthShulker 49b2491b70 Fix the other bed node 2024-08-18 04:47:19 +02:00
seventeenthShulker 0408f9c3d8 Update hardness and blast res for value not matching the wiki
- Notably, smooth sandstone (and red) is much more durable than other sandstone variants
- Ender chest isn't actually more explosion resistant than obsidian, hmm
2024-08-18 04:47:12 +02:00
seventeenthShulker cbafdfa585 Make monster eggs' hardness consistent with MC
Change blast resistance to 0.75, add an optional hardness override parameter, because cobble is unique here

(Still instant-minable, this is a separate issue)
2024-08-18 04:46:19 +02:00
seventeenthShulker 2312989503 Fix several hardness and blast resistance values 2024-08-18 04:46:19 +02:00
seventeenthShulker 1471ad7181 Un-hardcode most slabs and stairs 2024-08-18 04:46:19 +02:00
seventeenthShulker 38d7609173 Forgot about blackstone 2024-08-18 04:46:19 +02:00
seventeenthShulker 5bce56cdd6 Walls use `source` parameter for default hardness and blast resistance
If no `source` given, fallbacks are 2 and 6 respectively
2024-08-18 04:46:19 +02:00
seventeenthShulker 7a05c32198 Fix prismarine bricks and dark variant blast res.
Should be 6 like regular prismarine
2024-08-18 04:46:19 +02:00
seventeenthShulker ff386e395f Un-hardcode blast resistance, hardness for walls,
now only based on their material
2024-08-18 04:46:19 +02:00
the-real-herowl a687ef19f6 Merge pull request 'Solving ladder placement issues' (#4596) from goodspeed/VoxeLibre:ladder-logic into master
Reviewed-on: VoxeLibre/VoxeLibre#4596
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-08-18 01:40:42 +02:00
William Goodspeed c03f9abd18 Fix the placement check of ladder
The old code takes the first return val of `minetest.item_place_node'
which is `itemstack'. Therefore, the variable `success' in the old code
is always true. The new code takes the second val which will be nil if
an invalid node placement occured.

This check is necessary since the ladder may be placed in the front of
pointed block while there is a node with hole (slabs, fences etc.) at
the same place resulting an invalid placement and sound played when
it shouldn't be played.
2024-08-17 18:38:01 +02:00
William Goodspeed 9657c9d8bb Make ladder placable on any solid block 2024-08-17 18:38:01 +02:00
blitzdoughnuts 95aadd40b9 Add charcoal blocks as an item (#4589)
Co-authored-by: blitzdoughnuts <NOEMAIL@localhost>
Reviewed-on: VoxeLibre/VoxeLibre#4589
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: blitzdoughnuts <doughnutsblitz@disroot.org>
Co-committed-by: blitzdoughnuts <doughnutsblitz@disroot.org>
2024-08-16 22:28:08 +02:00
THE-NERD2 86e3446407 Update mount.lua to fix horse riding problem (#4580)
Previously, horses would continue to move even after the movement key was released. This was because mcl_mobs.drive was returning before stopping the horse. This commit makes mcl_mobs.drive stop the horse before returning.

Reviewed-on: VoxeLibre/VoxeLibre#4580
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: THE-NERD2 <pdp9729@gmail.com>
Co-committed-by: THE-NERD2 <pdp9729@gmail.com>
2024-08-16 22:21:18 +02:00
William Goodspeed ee4d1efaa5 Turn 8 snow layers stacked together into snow block (fixes #4483) (#4591)
Reviewed-on: VoxeLibre/VoxeLibre#4591
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: goodspeed <goodspeed@mailo.cat>
Co-committed-by: goodspeed <goodspeed@mailo.cat>
2024-08-16 22:03:01 +02:00
kno10 5e6e4967f0 Fix crying obsidian particles (#4583)
LUAs `math.random(a,b)` expects a and b to be integers. `size` was only randomized once.

Reviewed-on: VoxeLibre/VoxeLibre#4583
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-08-16 22:01:19 +02:00
kno10 df60ec947d Not all mangrove trees were post-processed (#4584)
Mangrove tree variants 4, 5 and bees nest were not post processed with root growth.

Reviewed-on: VoxeLibre/VoxeLibre#4584
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-08-16 21:58:04 +02:00
kno10 02cb0818a1 When chests explode due to TNT (and likely creepers), the game crashes (#4577)
because of an undefined variable.

Reviewed-on: VoxeLibre/VoxeLibre#4577
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-08-07 13:07:48 +02:00
kno10 77382d930e Typo in setting name, default should be false (#4492)
Reviewed-on: VoxeLibre/VoxeLibre#4492
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-08-03 17:52:51 +02:00
the-real-herowl 5e366a8916 Merge pull request 'Implement water freezing (mostly taken from mcla)' (#4478) from WillConker/VoxeLibre:water_freezing into master
Reviewed-on: VoxeLibre/VoxeLibre#4478
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-08-03 15:13:41 +02:00
WillConker 6c614d8376 Added line breaks in water freezing condition 2024-08-03 14:21:33 +02:00
WillConker a785be59d9 Changed node light check to artificial light so that water can freeze in the day 2024-08-03 14:21:33 +02:00
cora f23014005f Only freeze water under open air
and if light level < 10
2024-08-03 14:21:33 +02:00
cora c2098d777f Prevent water freezing and ice melting ABMs from fighting 2024-08-03 14:21:33 +02:00
cora dc07eea590 Freeze water in cold areas 2024-08-03 14:21:33 +02:00
tacotexmex 3460e27468 Update OpenCollective link (#4465)
Reviewed-on: VoxeLibre/VoxeLibre#4465
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: tacotexmex <tacotexmex@noreply.git.minetest.land>
Co-committed-by: tacotexmex <tacotexmex@noreply.git.minetest.land>
2024-08-03 12:47:37 +02:00
OgelGames 0012bdb71e Clear itemstring when picking up or merging items (#4530)
Prevents possible item duplication with other mods. Matches the behavior of the default `__builtin:item`.

See also https://github.com/mt-mods/pipeworks/issues/130

Reviewed-on: VoxeLibre/VoxeLibre#4530
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: OgelGames <ogelgames@noreply.git.minetest.land>
Co-committed-by: OgelGames <ogelgames@noreply.git.minetest.land>
2024-07-31 03:26:28 +02:00
kno10 b8d7139792 Fix iron golem attack animation (#4542)
C.f. MCLA

Reviewed-on: VoxeLibre/VoxeLibre#4542
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-07-31 03:18:53 +02:00
WillConker cddc1982be Fix first loot pool not being used in shipwrecks or ocean temples (#4523)
Reviewed-on: VoxeLibre/VoxeLibre#4523
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: WillConker <willconker@noreply.git.minetest.land>
Co-committed-by: WillConker <willconker@noreply.git.minetest.land>
2024-07-31 03:00:27 +02:00
kno10 9595b0df59 Inconsistent bed bouncyness, make top match bottom (#4495)
Reviewed-on: VoxeLibre/VoxeLibre#4495
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: kno10 <kno10@noreply.git.minetest.land>
Co-committed-by: kno10 <kno10@noreply.git.minetest.land>
2024-07-31 02:58:38 +02:00
WillConker ff21d1eab1 Make eggs spawn chicks when hitting entities (#4484)
Reviewed-on: VoxeLibre/VoxeLibre#4484
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: WillConker <willconker@noreply.git.minetest.land>
Co-committed-by: WillConker <willconker@noreply.git.minetest.land>
2024-07-31 02:57:20 +02:00
WillConker 9d5b46c28a Slow ender dragon regeneration (#4481)
Reviewed-on: VoxeLibre/VoxeLibre#4481
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: WillConker <waj01@joanes.net>
Co-committed-by: WillConker <waj01@joanes.net>
2024-07-31 02:56:33 +02:00
kno10 80a6a6efb0 Choose direction vectors uniformly for spawning (#4467)
The previous code was biased towards placing mobs on top or below the
player, because it chose the theta inclination angle uniformly,
but the sphere is more narrow at the top and bottom.

This code is also simpler.

Reviewed-on: VoxeLibre/VoxeLibre#4467
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-07-31 02:30:29 +02:00
the-real-herowl 32148262e1 Merge pull request 'Grand Chests Refactor (fixes #281)' (#4453) from mcl_chests_redo into master
Reviewed-on: VoxeLibre/VoxeLibre#4453
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-07-31 02:28:18 +02:00
Mikita Wiśniewski 567d112942 Fix deprecated get_metadata() usage
Items are instead written as a serialized string into ItemStackMetaRef, and read from there as well. Old itemstacks get converted to the new format automatically.
2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 347305eaea Fix ender chests rotate crash 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 508bc19f6a Remove nil fields from trapped chest definition 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski c1e9e4b1a2 Fix typos in API.md 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 7bf15642ca Resolve teknomunk's comments 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski f1fa6240bb Fix shift-clicking and a few luacheck warnings 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski c5bc6ff189 Cleanup comments (don't use \=, it's annoying) 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 70e903b716 Simplify double inventory inv logic 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 209b24a2fb Move LBMs out of init.lua and fix API.md 2024-07-31 02:27:26 +02:00
cora ac05f8bad6 Remove unused variables in chests example.lua 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 76cff76d91 Add an introduction text to API.md 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 49b6d09985 Add documentation (README.md, API.md) 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski a66c35a9ea Fix double chests once more (hoppers this time) 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski a28e55160f Make the chest opening/closing sound customizable + fix double chests 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 6bbb6b8dec Add title field for mcl_chests.register_chest 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski b4b5bf8391 Move some groups (api.lua → chests.lua) 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 16dd8694a6 Refactor mcl_chests.register_chest AGAIN + cleanup
Now you can define custom groups for the chests, as shown in the trapped
chests example (now they show up under "Mechanisms" tab in creative!).

I'm a bit suspicious of the new return-wrapped functions, as in *they
might break under some circumstances I didn't observe*. It will require
some heavy testing to make sure nothing crashes in the future.

Also, `on_rightclick` for double chests is something I really want to
return-wrap as well, but failed to do so. 🤷
2024-07-31 02:27:26 +02:00
Jürgen Rühle 7a5ee4e6e2 Better detection of properly serialized data
Remove entity if initialization data is missing. Downgrade message in that case
to a warning.
2024-07-31 02:27:26 +02:00
Jürgen Rühle d0d9600709 Fix invisible chests
Pass chest entity initialization data to on_activate as staticdata so
initialization is atomic, preventing premature deletion of chest entity
by concurrent server steps.
2024-07-31 02:27:26 +02:00
cora 709b73295c Fix meta:set_string being called with nil 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski 1d77017ca9 Refactor mcl_chests.register_chest and clean-up 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski d6d64d8837 Fix long doc strings 2024-07-31 02:27:26 +02:00
Mikita Wiśniewski e771f0e3ff Split ITEMS/mcl_chests/init.lua (fixes #281)
Shulker boxes can now be rotated.

The TODO will now be transferred to PR.
2024-07-31 02:27:26 +02:00
Mikita Wiśniewski b10bfe27ce Clean-up ITEMS/mcl_chests code, part 2
Chest tile management has been reorganized to use postfixes, some slight
formatting fixes applied here and there, and roughly marked down where
the new files should (ideally) begin and end.
2024-07-31 02:27:26 +02:00
Mikita Wiśniewski d5b3a6f658 Clean-up ITEMS/mcl_chests code, part 1
Amongst other changes:
- mcl_chests.register_chest function has been exposed. The API is still
  too terrible to call it quits though, I definitely want all these
  parameters passed to be part of a key-value table.
- Added a TODO list at the top of the file. Don't worry, I'll remove it
  once I'm done. It's more just for my convenience than anything.
2024-07-31 02:27:26 +02:00
JoseDouglas26 f7ee3b59d7 Changes on slab placement checks (#4317)
Fixed slab placement being not allowed when it should be allowed.

Reviewed-on: VoxeLibre/VoxeLibre#4317
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: JoseDouglas26 <josedouglas20002014@gmail.com>
Co-committed-by: JoseDouglas26 <josedouglas20002014@gmail.com>
2024-07-31 00:11:22 +02:00
the-real-herowl 1745b6d400 Merge pull request 'Add persistence to XP Orbs' (#4265) from teknomunk/MineClone2:persist-xp-orbs into master
Reviewed-on: VoxeLibre/VoxeLibre#4265
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-07-31 00:03:05 +02:00
teknomunk bb9ed4498b Address review comments 2024-06-26 06:52:26 -05:00
teknomunk 94981d9c09 Add return for get_staticdata 2024-06-26 12:23:30 +02:00
teknomunk 7ae05d9c06 Add persistence to XP orbs, cleanup xp_to_size 2024-06-26 12:23:30 +02:00
teknomunk 177e8f4b9d Code cleanup 2024-06-26 12:23:30 +02:00
the-real-herowl 026ea5940c Merge pull request 'release/0.87.2' (#4457) from release/0.87.2 into master
Reviewed-on: VoxeLibre/VoxeLibre#4457
2024-06-24 03:43:09 +02:00
the-real-herowl be9fece0d3 Post-hotfix reset version 0.88.0-SNAPSHOT 2024-06-24 03:41:37 +02:00
the-real-herowl 27f8a008c3 Update release notes for hotfix v0.87.2 2024-06-24 03:40:15 +02:00
the-real-herowl 8bbceddbc2 Updated release credits and set version for hotfix v0.87.2 2024-06-24 03:28:19 +02:00
the-real-herowl 6e70c760d6 Fix some formspecs on mobile (#4456)
This should allow renaming items on the anvil when using mobile. This also may improve mobile craftguide experience.

Reviewed-on: VoxeLibre/VoxeLibre#4456
Co-authored-by: the-real-herowl <wiktor_t-i@proton.me>
Co-committed-by: the-real-herowl <wiktor_t-i@proton.me>
2024-06-24 03:26:02 +02:00
the-real-herowl 53802b270d Merge pull request 'Prevent mob conversion code from crashing' (#4421) from teknomunk/MineClone2:fix-conversion-crash into master
Reviewed-on: VoxeLibre/VoxeLibre#4421
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
2024-06-24 03:07:19 +02:00
teknomunk 3928e12634 Fix two more crashes, stray space 2024-06-24 03:06:26 +02:00
teknomunk 304550d90c Fix parameter name 2024-06-24 03:06:26 +02:00
teknomunk 0a2336ad82 Handle conversion of mobs that were incorrectly converted 2024-06-24 03:06:26 +02:00
teknomunk 75a767a0ab Mob spawner conversion 2024-06-24 03:06:26 +02:00
teknomunk 7e0afd7e21 Remove debug logging 2024-06-24 03:06:26 +02:00
teknomunk 15fa925aae More fields to strip 2024-06-24 03:06:26 +02:00
teknomunk 4935f5fdda Add debug logging 2024-06-24 03:06:26 +02:00
teknomunk 41032ec999 Use correct variable name 2024-06-24 03:06:26 +02:00
teknomunk d64ee18f75 Strip some fields from the mob's staticdata on conversion 2024-06-24 03:06:26 +02:00
teknomunk 1942384fe5 Move object remove after position check 2024-06-24 03:06:26 +02:00
teknomunk 9b50dd6565 Update to use new_object instead of obj 2024-06-24 03:06:26 +02:00
teknomunk a88951ac6a More safety checks 2024-06-24 03:06:26 +02:00
teknomunk bc343769ee Add guard to prevent crash when converting old mobs and the minetest fails to create the new entity 2024-06-24 03:06:26 +02:00
seventeenthShulker 8aa65f85f2 Fix extra 'Stair' in Polished Blackstone Brick nodes (#4450)
Some of the longest block names were erroneous. Farewell, Polished Blackstone Brick Stair Stairs and Polished Blackstone Brick Stair Slab.

Reviewed-on: VoxeLibre/VoxeLibre#4450
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: seventeenthShulker <c545d588-7ff2-49b9-b537-0b3f769083ad@anonaddy.me>
Co-committed-by: seventeenthShulker <c545d588-7ff2-49b9-b537-0b3f769083ad@anonaddy.me>
2024-06-23 23:40:36 +02:00
qoheniac e27e70a91b fix wrong name for diorite stairs (#4359)
Reviewed-on: VoxeLibre/VoxeLibre#4359
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: qoheniac <qoheniac@noreply.git.minetest.land>
Co-committed-by: qoheniac <qoheniac@noreply.git.minetest.land>
2024-06-23 23:39:09 +02:00
JoseDouglas26 744b47088b Fixes flint and steel adding wear when not setting node on fire (#4368)
Reviewed-on: VoxeLibre/VoxeLibre#4368
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: JoseDouglas26 <josedouglas20002014@gmail.com>
Co-committed-by: JoseDouglas26 <josedouglas20002014@gmail.com>
2024-06-16 18:33:19 +02:00
Mikita Wiśniewski 6654c86fb2 Update issue and PR templates (#4440)
Reviewed-on: VoxeLibre/VoxeLibre#4440
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-06-16 18:00:16 +02:00
the-real-herowl 72435933e4 Add defensive check (#4437)
This fixes #4436 and possible other unnoticed crashes by adding a defensive check.

Reviewed-on: VoxeLibre/VoxeLibre#4437
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: the-real-herowl <wiktor_t-i@proton.me>
Co-committed-by: the-real-herowl <wiktor_t-i@proton.me>
2024-06-15 03:51:03 +02:00
the-real-herowl 35e14dd415 Potion conversion fix (#4426)
Reviewed-on: VoxeLibre/VoxeLibre#4426
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: the-real-herowl <wiktor_t-i@proton.me>
Co-committed-by: the-real-herowl <wiktor_t-i@proton.me>
2024-06-13 13:22:14 +02:00
the-real-herowl 173f8a0bca Effect loading fixes (#4425)
Reviewed-on: VoxeLibre/VoxeLibre#4425
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: the-real-herowl <wiktor_t-i@proton.me>
Co-committed-by: the-real-herowl <wiktor_t-i@proton.me>
2024-06-13 13:21:36 +02:00
teknomunk 1f32b47208 Fix crash while fighting whither (#4392)
Reviewed-on: VoxeLibre/VoxeLibre#4392
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-06-12 14:18:03 +02:00
SmokeyDope bf67fd52e1 Zombie texture improvements (#4260)
Reviewed-on: VoxeLibre/VoxeLibre#4260
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: SmokeyDope <smokey@tilde.team>
Co-committed-by: SmokeyDope <smokey@tilde.team>
2024-06-11 19:38:41 +02:00
WillConker fd4e1484af Fix crash on high levels of frost walker (#4423)
Reviewed-on: VoxeLibre/VoxeLibre#4423
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-06-11 19:17:12 +02:00
teknomunk 1b0deae026 Fix crash when bonemealing sweet berry bushes (#4419)
Reviewed-on: VoxeLibre/VoxeLibre#4419
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: teknomunk <teknomunk@protonmail.com>
Co-committed-by: teknomunk <teknomunk@protonmail.com>
2024-06-11 18:47:18 +02:00
teknomunk 313c1f558b Make all hollow logs breakable (#4418)
Reviewed-on: VoxeLibre/VoxeLibre#4418
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-06-11 18:43:33 +02:00
teknomunk 5cafa97dd1 Fix formspec code that reads strength button field (#4385)
Reviewed-on: VoxeLibre/VoxeLibre#4385
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-06-11 18:40:44 +02:00
teknomunk ddab68b87c Add instructions on how to eat to basic controls help entry (#4420)
Reviewed-on: VoxeLibre/VoxeLibre#4420
Reviewed-by: ancientmarinerdev <ancientmariner_dev@proton.me>
Co-authored-by: teknomunk <teknomunk@protonmail.com>
Co-committed-by: teknomunk <teknomunk@protonmail.com>
2024-06-10 19:44:30 +00:00
JoseDouglas26 2dafbae64b Hotfix for brewing stands rotation (#4371)
Reviewed-on: VoxeLibre/VoxeLibre#4371
Reviewed-by: teknomunk <teknomunk@protonmail.com>
Co-authored-by: JoseDouglas26 <josedouglas20002014@gmail.com>
Co-committed-by: JoseDouglas26 <josedouglas20002014@gmail.com>
2024-06-07 06:10:52 +00:00
244 changed files with 4912 additions and 4471 deletions

View File

@ -13,16 +13,17 @@ labels:
Thanks for taking the time to fill out this bug report!
Please follow our contributing guidelines first:
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests
https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests
By submitting this issue, you agree to follow our Code of Conduct:
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md
https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/CODE_OF_CONDUCT.md
-->
<!--
What version of VoxeLibre are you using? We do not provide support for outdated versions of VoxeLibre.
"/ver" command will output the version you're running.
Current latest version is listed here, at the top:
https://git.minetest.land/MineClone2/MineClone2/tags
https://git.minetest.land/VoxeLibre/VoxeLibre/tags
-->
VoxeLibre version:

View File

@ -1,7 +1,7 @@
---
name: "Feature request"
about: "File a feature request not in Minecraft"
about: "File a feature request"
labels:
- "non-Minecraft feature"
@ -10,17 +10,17 @@ labels:
---
<!--
Got a new non-Minecraft feature request? Explain to us why we should consider your idea.
Got a new feature request? Explain to us why we should consider your idea.
Please follow our contributing guidelines first:
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests
https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests
By submitting this issue, you agree to follow our Code of Conduct:
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md
https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/CODE_OF_CONDUCT.md
-->
### Feature
Tell us about your requested feature not in Minecraft!
Tell us about your requested feature!
### Why
Tell us why should we implement it!

View File

@ -1,25 +0,0 @@
---
name: "Missing Feature request"
about: "File a missing feature request in Minecraft but not in MineClone2"
labels:
- "missing feature"
---
<!--
Thanks for taking the time to fill out this missing feature request!
Please follow our contributing guidelines first:
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests
By submitting this issue, you agree to follow our Code of Conduct:
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md
-->
### Current feature in Minecraft
Tell us about the feature currently in Minecraft! What is it like on Minecraft?
### Current feature in VoxeLibre
Tell us about the feature currently in VoxeLibre! What is different?

View File

@ -8,13 +8,13 @@ labels:
<!--
Please follow our contributing guidelines first:
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#how-you-can-help-as-a-programmer
https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/CONTRIBUTING.md#how-you-can-help-as-a-programmer
By submitting this pull request, you agree to follow our Code of Conduct:
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md
https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/CODE_OF_CONDUCT.md
-->
Tell us about your pull request! Reference related issues, if necessary
Tell us about your pull request! Reference related issues, if necessary.
### Testing
Tell us how to test your changes!

View File

@ -20,10 +20,8 @@
* epCode
* chmodsayshello
* MrRar
* FossFanatic
* SmokeyDope
* Faerraven / Michieal
* Codiac
* rudzik8
* teknomunk
@ -36,6 +34,8 @@
* NO11
* SumianVoice
* PrairieWind
* FossFanatic
* Codiac
## Contributors
* RandomLegoBrick
@ -140,6 +140,7 @@
* SOS-Games
* Bram
* qoheniac
* WillConker
## Music
* Jordach for the jukebox music compilation from Big Freaking Dig

View File

@ -46,6 +46,9 @@ Armor trim models were created by Aeonix_Aeon
Source: <https://www.curseforge.com/minecraft/texture-packs/ozocraft-remix>
License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
Charcoal block texture was created by [blitzdoughnuts](https://gitlab.com/ApplemunchFromDaDead), based on the Pixel Perfection coal block.
License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)
The main menu images are released under: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
All other files, unless mentioned otherwise, fall under:

View File

@ -83,7 +83,7 @@ The VoxeLibre repository is hosted at Mesehub. To contribute or report issues, h
* Discord: <https://discord.gg/xE4z8EEpDC>
* YouTube: <https://www.youtube.com/channel/UClI_YcsXMF3KNeJtoBfnk9A>
* ContentDB: <https://content.minetest.net/packages/wuzzy/mineclone2/>
* OpenCollective: <https://opencollective.com/mineclone2>
* OpenCollective: <https://opencollective.com/voxelibre>
* Mastodon: <https://fosstodon.org/@VoxeLibre>
* Lemmy: <https://lemm.ee/c/voxelibre>
* Matrix space: <https://app.element.io/#/room/#voxelibre:matrix.org>

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)
@ -1103,3 +1117,17 @@ function mcl_util.is_it_christmas()
return false
end
end
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

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

@ -10,3 +10,14 @@ Rightclick on a water source to place the boat. Rightclick the boat to enter it.
Spruce Boat=Fichtenboot
Water vehicle=Wasserfahrzeug
Sneak to dismount=Zum Aussteigen schleichen
Obsidian Boat=Obsidianboot
Mangrove Boat=
Cherry Boat=Kirschholzboot
Oak Chest Boat=Eichentruhenboot
Spruce Chest Boat=
Birch Chest Boat=Birkentruhenboot
Jungle Chest Boat=Dschungeltruhenboot
Acacia Chest Boat=
Dark Oak Chest Boat=
Mangrove Chest Boat=
Cherry Chest Boat=

View File

@ -29,7 +29,7 @@ local function make_drop(pos, liquid, sound, interval, texture)
pt.expirationtime = t
pt.texture = "[combine:2x2:" ..
-math.random(1, 16) .. "," .. -math.random(1, 16) .. "=" .. texture
math.random(-14, 0) .. "," .. math.random(-14, 0) .. "=" .. texture
minetest.add_particle(pt)

View File

@ -136,6 +136,7 @@ local function try_object_pickup(player, inv, object, checkpos)
-- Destroy entity
-- This just prevents this section to be run again because object:remove() doesn't remove the item immediately.
le.target = checkpos
le.itemstring = ""
le._removed = true
-- Stop the object
@ -320,6 +321,7 @@ function minetest.handle_node_drops(pos, drops, digger)
if tool and nodedef._mcl_fortune_drop and enchantments.fortune then
local fortune_level = enchantments.fortune
local fortune_drop = nodedef._mcl_fortune_drop
local simple_drop = nodedef._mcl_fortune_drop.drop_without_fortune
if fortune_drop.discrete_uniform_distribution then
local min_count = fortune_drop.min_count
local max_count = fortune_drop.max_count + fortune_level * (fortune_drop.factor or 1)
@ -335,6 +337,12 @@ function minetest.handle_node_drops(pos, drops, digger)
local drop = get_fortune_drops(fortune_drop, fortune_level)
drops = get_drops(drop, tool:get_name(), dug_node.param2, nodedef.paramtype2)
end
if simple_drop then
for _, item in pairs(simple_drop) do
table.insert(drops, item)
end
end
end
if digger and mcl_experience.throw_xp and not silk_touch_drop then
@ -957,6 +965,7 @@ minetest.register_entity(":__builtin:item", {
self.random_velocity = 0
self:set_item(own_stack:to_string())
entity.itemstring = ""
entity._removed = true
object:remove()
return true

View File

@ -18,7 +18,7 @@ mcl_mobs.invis = {}
local remove_far = true
local mobs_debug = minetest.settings:get_bool("mobs_debug", false) -- Shows helpful debug info above each mob
local spawn_logging = minetest.settings:get_bool("mcl_logging_mobs_spawn",true)
local spawn_logging = minetest.settings:get_bool("mcl_logging_mobs_spawn", false)
local MAPGEN_LIMIT = mcl_vars.mapgen_limit
local MAPGEN_MOB_LIMIT = MAPGEN_LIMIT - 90
@ -150,6 +150,11 @@ function mob_class:mob_activate(staticdata, def, dtime)
local tmp = minetest.deserialize(staticdata)
if tmp then
-- Patch incorrectly converted mobs
if tmp.base_mesh ~= minetest.registered_entities[self.name].mesh then
mcl_mobs.strip_staticdata(tmp)
end
for _,stat in pairs(tmp) do
self[_] = stat
end
@ -383,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
@ -397,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
@ -497,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
@ -516,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

@ -105,7 +105,7 @@ end
-- Spawn a child
function mcl_mobs.spawn_child(pos, mob_type)
local child = minetest.add_entity(pos, mob_type)
local child = mcl_mobs.spawn(pos, mob_type)
if not child then
return
end
@ -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

@ -802,34 +802,37 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
end
-- alert others to the attack
local objs = minetest.get_objects_inside_radius(hitter:get_pos(), self.view_range)
local obj = nil
local alert_pos = hitter:get_pos()
if alert_pos then
local objs = minetest.get_objects_inside_radius(alert_pos, self.view_range)
local obj = nil
for n = 1, #objs do
for n = 1, #objs do
obj = objs[n]:get_luaentity()
obj = objs[n]:get_luaentity()
if obj then
-- only alert members of same mob or friends
if obj.group_attack
and obj.state ~= "attack"
and obj.owner ~= name then
if obj.name == self.name then
obj:do_attack(hitter)
elseif type(obj.group_attack) == "table" then
for i=1, #obj.group_attack do
if obj.group_attack[i] == self.name then
obj._aggro = true
obj:do_attack(hitter)
break
if obj then
-- only alert members of same mob or friends
if obj.group_attack
and obj.state ~= "attack"
and obj.owner ~= name then
if obj.name == self.name then
obj:do_attack(hitter)
elseif type(obj.group_attack) == "table" then
for i=1, #obj.group_attack do
if obj.group_attack[i] == self.name then
obj._aggro = true
obj:do_attack(hitter)
break
end
end
end
end
end
-- have owned mobs attack player threat
if obj.owner == name and obj.owner_loyal then
obj:do_attack(self.object)
-- have owned mobs attack player threat
if obj.owner == name and obj.owner_loyal then
obj:do_attack(self.object)
end
end
end
end

View File

@ -342,13 +342,33 @@ function mcl_mobs.register_mob(name, def)
minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta))
end -- END mcl_mobs.register_mob function
local STRIP_FIELDS = { "mesh", "base_size", "textures", "base_mesh", "base_texture" }
function mcl_mobs.strip_staticdata(unpacked_staticdata)
-- Strip select fields from the staticdata to prevent conversion issues
for i = 1,#STRIP_FIELDS do
unpacked_staticdata[STRIP_FIELDS[i]] = nil
end
end
function mcl_mobs.register_conversion(old_name, new_name)
minetest.register_entity(old_name, {
on_activate = function(self, staticdata, dtime)
local obj = minetest.add_entity(self.object:get_pos(), new_name, staticdata)
local hook = (obj:get_luaentity() or {})._on_after_convert
if hook then hook(obj) end
self.object:remove()
local unpacked_staticdata = minetest.deserialize(staticdata)
mcl_mobs.strip_staticdata(unpacked_staticdata)
staticdata = minetest.serialize(unpacked_staticdata)
local old_object = self.object
if not old_object then return end
local pos = old_object:get_pos()
if not pos then return end
old_object:remove()
local new_object = minetest.add_entity(pos, new_name, staticdata)
if not new_object then return end
local hook = (new_object:get_luaentity() or {})._on_after_convert
if hook then hook(new_object) end
end,
_convert_to = new_name,
})
@ -508,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}
@ -519,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
@ -531,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,
@ -541,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?
@ -551,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)
@ -572,26 +592,35 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
--minetest.log("min light: " .. mob_light_lvl[1])
--minetest.log("max light: " .. mob_light_lvl[2])
mcl_mobspawners.setup_spawner(pointed_thing.under, itemstack:get_name(), mob_light_lvl[1], mob_light_lvl[2])
-- Handle egg conversion
local convert_to = (minetest.registered_entities[mob_name] or {})._convert_to
if convert_to then mob_name = convert_to end
mcl_mobspawners.setup_spawner(pointed_thing.under, mob_name, mob_light_lvl[1], mob_light_lvl[2])
if not minetest.is_creative_enabled(name) then
itemstack:take_item()
end
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()
@ -622,5 +651,4 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
return itemstack
end,
})
end

View File

@ -258,6 +258,18 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end
end
-- Stop!
local s = get_sign(entity.v)
entity.v = entity.v - 0.02 * s
if s ~= get_sign(entity.v) then
entity.object:set_velocity({x = 0, y = 0, z = 0})
entity.v = 0
return
end
-- if not moving then set animation and return
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
@ -273,18 +285,6 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
mcl_mobs:set_animation(entity, moving_anim)
end
-- Stop!
local s = get_sign(entity.v)
entity.v = entity.v - 0.02 * s
if s ~= get_sign(entity.v) then
entity.object:set_velocity({x = 0, y = 0, z = 0})
entity.v = 0
return
end
-- enforce speed limit forward and reverse
local max_spd = entity.max_speed_reverse

View File

@ -362,7 +362,7 @@ function mob_class:env_danger_movement_checks(player_in_active_range)
self.state = "stand"
self:set_animation( "stand")
end
yaw = yaw + math.random(-0.5, 0.5)
yaw = yaw + math.random() - 0.5
yaw = self:set_yaw( yaw, 8)
return
end
@ -788,9 +788,9 @@ function mob_class:flop()
if self.object:get_velocity().y < 0.1 then
self:mob_sound("flop")
self.object:set_velocity({
x = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
x = (math.random()-0.5) * 2 * FLOP_HOR_SPEED,
y = FLOP_HEIGHT,
z = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED),
z = (math.random()-0.5) * 2 * FLOP_HOR_SPEED,
})
end
end
@ -920,7 +920,7 @@ function mob_class:do_states_walk()
-- Randomly turn
if math.random(1, 100) <= 30 then
yaw = yaw + math.random(-0.5, 0.5)
yaw = yaw + math.random() - 0.5
yaw = self:set_yaw( yaw, 8)
end
end
@ -929,7 +929,7 @@ function mob_class:do_states_walk()
-- otherwise randomly turn
elseif math.random(1, 100) <= 30 then
yaw = yaw + math.random(-0.5, 0.5)
yaw = yaw + math.random() - 0.5
yaw = self:set_yaw( yaw, 8)
end
@ -989,7 +989,7 @@ function mob_class:do_states_stand(player_in_active_range)
if lp.x > s.x then yaw = yaw +math.pi end
else
yaw = yaw + math.random(-0.5, 0.5)
yaw = yaw + math.random() - 0.5
end
yaw = self:set_yaw( yaw, 8)

View File

@ -692,14 +692,10 @@ function mob_class:do_env_damage()
local nodef3 = minetest.registered_nodes[self.standing_under]
-- rain
if self.rain_damage > 0 then
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
self.health = self.health - self.rain_damage
if self:check_for_death("rain", {type = "environment",
pos = pos, node = self.standing_in}) then
return true
end
if self.rain_damage > 0 and mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
self.health = self.health - self.rain_damage
if self:check_for_death("rain", {type = "environment", pos = pos, node = self.standing_in}) then
return true
end
end
@ -707,14 +703,10 @@ function mob_class:do_env_damage()
-- water damage
if self.water_damage > 0 and nodef.groups.water then
if self.water_damage ~= 0 then
self.health = self.health - self.water_damage
mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png", nil, nil, 1, nil)
if self:check_for_death("water", {type = "environment",
pos = pos, node = self.standing_in}) then
return true
end
self.health = self.health - self.water_damage
mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png", nil, nil, 1, nil)
if self:check_for_death("water", {type = "environment", pos = pos, node = self.standing_in}) then
return true
end
elseif self.lava_damage > 0 and (nodef.groups.lava) then
-- lava damage
@ -730,91 +722,69 @@ function mob_class:do_env_damage()
end
elseif self.fire_damage > 0 and (nodef2.groups.fire) then
-- magma damage
if self.fire_damage ~= 0 then
self.health = self.health - self.fire_damage
if self:check_for_death("fire", {type = "environment",
pos = pos, node = self.standing_in}) then
return true
end
self.health = self.health - self.fire_damage
if self:check_for_death("fire", {type = "environment", pos = pos, node = self.standing_in}) then
return true
end
elseif self.fire_damage > 0 and (nodef.groups.fire) then
-- fire damage
if self.fire_damage ~= 0 then
self.health = self.health - self.fire_damage
mcl_mobs.effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil)
mcl_burning.set_on_fire(self.object, 5)
if self:check_for_death("fire", {type = "environment",
pos = pos, node = self.standing_in}) then
return true
end
self.health = self.health - self.fire_damage
mcl_mobs.effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil)
mcl_burning.set_on_fire(self.object, 5)
if self:check_for_death("fire", {type = "environment", pos = pos, node = self.standing_in}) then
return true
end
elseif nodef.damage_per_second ~= 0 and not nodef.groups.lava and not nodef.groups.fire then
-- damage_per_second node check
self.health = self.health - nodef.damage_per_second
mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png")
if self:check_for_death("dps", {type = "environment",
pos = pos, node = self.standing_in}) then
if self:check_for_death("dps", {type = "environment", pos = pos, node = self.standing_in}) then
return true
end
end
-- Cactus damage
local near = minetest.find_node_near(pos, 1, "mcl_core:cactus", true)
if not near and near ~= nil then
near = find_node_near({x=pos.x, y=pos.y-1, z=pos.z}, 1, "mcl_core:cactus", true)
end
if near then
-- is mob touching the cactus?
local dist = vector.distance(pos, near)
local dist_feet = vector.distance({x=pos.x, y=pos.y-1, z=pos.z}, near)
local large_mob = false
local medium_mob = false
if self.name == "mobs_mc:ender_dragon" or
self.name == "mobs_mc:ghast" or
self.name == "mobs_mc:guardian_elder" or
self.name == "mobs_mc:slime_big" or
self.name == "mobs_mc:magma_cube_big" or
self.name == "mobs_mc:wither" then
large_mob = true
elseif self.name == "mobs_mc:hoglin" or
self.name == "mobs_mc:zoglin" or
self.name == "mobs_mc:horse" or
self.name == "mobs_mc:skeleton_horse" or
self.name == "mobs_mc:zombie_horse" or
self.name == "mobs_mc:donkey" or
self.name == "mobs_mc:mule" or
self.name == "mobs_mc:iron_golem" or
self.name == "mobs_mc:polar_bear" or
self.name == "mobs_mc:spider" or
self.name == "mobs_mc:cave_spider" or
self.name == "mobs_mc:strider" then
medium_mob = true
if self.standing_on == "mcl_core:cactus" or self.standing_in == "mcl_core:cactus" or self.standing_under == "mcl_core:cactus" then
self:damage_mob("cactus", 2)
if self:check_for_death("cactus", {type = "environment", pos = pos, node = self.standing_in}) then
return true
end
if (not large_mob and not medium_mob and (dist < 1.03 or dist_feet < 1.6)) or (medium_mob and (dist < 1.165 or dist_feet < 1.73)) or (large_mob and (dist < 1.25 or dist_feet < 1.9)) then
if self.health ~= 0 then
else
local near = minetest.find_node_near(pos, 1, "mcl_core:cactus")
if near then
-- is mob touching the cactus?
local dist = vector.distance(pos, near)
local threshold = 1.04 -- small mobs
-- medium mobs
if self.name == "mobs_mc:spider" or
self.name == "mobs_mc:iron_golem" or
self.name == "mobs_mc:horse" or
self.name == "mobs_mc:donkey" or
self.name == "mobs_mc:mule" or
self.name == "mobs_mc:polar_bear" or
self.name == "mobs_mc:cave_spider" or
self.name == "mobs_mc:skeleton_horse" or
self.name == "mobs_mc:zombie_horse" or
self.name == "mobs_mc:strider" or
self.name == "mobs_mc:hoglin" or
self.name == "mobs_mc:zoglin" then
threshold = 1.165
elseif self.name == "mobs_mc:slime_big" or
self.name == "mobs_mc:magma_cube_big" or
self.name == "mobs_mc:ghast" or
self.name == "mobs_mc:guardian_elder" or
self.name == "mobs_mc:wither" or
self.name == "mobs_mc:ender_dragon" then
threshold = 1.25
end
if dist < threshold then
self:damage_mob("cactus", 2)
if self:check_for_death("cactus", {type = "environment",
pos = pos, node = self.standing_in}) then
if self:check_for_death("cactus", {type = "environment", pos = pos, node = self.standing_in}) then
return true
end
end
end
end
-- is mob standing on the cactus?
if self.standing_on == "mcl_core:cactus" or self.standing_in == "mcl_core:cactus" or self.standing_under == "mcl_core:cactus" then
self:damage_mob("cactus", 2)
if self:check_for_death("cactus", {type = "environment",
pos = pos, node = self.standing_in}) then
return true
end
end
-- Drowning damage
if self.breath_max ~= -1 then
@ -957,7 +927,8 @@ end
-- falling and fall damage
-- returns true if mob died
function mob_class:falling(pos)
function mob_class:falling(pos, moveresult)
if moveresult and moveresult.touching_ground then return false end
if self.fly and self.state ~= "die" then
return

View File

@ -10,20 +10,22 @@ 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
local math_random = math.random
local math_floor = math.floor
local math_ceil = math.ceil
local math_cos = math.cos
local math_sin = math.sin
local math_round = function(x) return (x > 0) and math_floor(x + 0.5) or math_ceil(x - 0.5) end
local math_sqrt = math.sqrt
local math_abs = math.abs
local vector_distance = vector.distance
local vector_new = vector.new
@ -33,19 +35,15 @@ local table_copy = table.copy
local table_remove = table.remove
local pairs = pairs
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_spawning", false)
local function mcl_log (message, property)
if LOGGING_ON then
if property then
message = message .. ": " .. dump(property)
end
mcl_util.mcl_log (message, "[Mobs spawn]", true)
end
local logging = minetest.settings:get_bool("mcl_logging_mobs_spawn", false)
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
@ -54,8 +52,10 @@ local FIND_SPAWN_POS_RETRIES = 16
local FIND_SPAWN_POS_RETRIES_SUCCESS_RESPIN = 8
local MOB_SPAWN_ZONE_INNER = 24
local MOB_SPAWN_ZONE_INNER_SQ = MOB_SPAWN_ZONE_INNER^2 -- squared
local MOB_SPAWN_ZONE_MIDDLE = 32
local MOB_SPAWN_ZONE_OUTER = 128
local MOB_SPAWN_ZONE_OUTER_SQ = MOB_SPAWN_ZONE_OUTER^2 -- squared
-- range for mob count
local MOB_CAP_INNER_RADIUS = 32
@ -95,170 +95,6 @@ mcl_log("Percentage of hostile spawns are group: " .. hostile_group_percentage_s
--do mobs spawn?
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false
local logging = minetest.settings:get_bool("mcl_logging_mobs_spawn",true)
-- 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)
@ -287,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
@ -450,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
@ -601,71 +433,40 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_
spawn_dictionary[key]["check_position"] = check_position
end
-- Calculate the inverse of a piecewise linear function f(x). Line segments are represented as two
-- adjacent points specified as { x, f(x) }. At least 2 points are required. If there are most solutions,
-- the one with a lower x value will be chosen.
local function inverse_pwl(fx, f)
if fx < f[1][2] then
return f[1][1]
end
for i=2,#f do
local x0,fx0 = unpack(f[i-1])
local x1,fx1 = unpack(f[i ])
if fx < fx1 then
return (fx - fx0) * (x1 - x0) / (fx1 - fx0) + x0
end
end
return f[#f][1]
end
local SPAWN_DISTANCE_CDF_PWL = {
{0.000,0.00},
{0.083,0.40},
{0.416,0.75},
{1.000,1.00},
}
local two_pi = 2 * math.pi
local function get_next_mob_spawn_pos(pos)
-- Select a distance such that distances closer to the player are selected much more often than
-- those further away from the player.
local fx = (math_random(1,10000)-1) / 10000
local x = inverse_pwl(fx, SPAWN_DISTANCE_CDF_PWL)
local distance = x * (MOB_SPAWN_ZONE_OUTER - MOB_SPAWN_ZONE_INNER) + MOB_SPAWN_ZONE_INNER
-- those further away from the player. This does produce a concentration at INNER (24 blocks)
local distance = math_random()^2 * (MOB_SPAWN_ZONE_OUTER - MOB_SPAWN_ZONE_INNER) + MOB_SPAWN_ZONE_INNER
--print("Using spawn distance of "..tostring(distance).." fx="..tostring(fx)..",x="..tostring(x))
-- TODO Floor xoff and zoff and add 0.5 so it tries to spawn in the middle of the square. Less failed attempts.
-- Use spherical coordinates https://en.wikipedia.org/wiki/Spherical_coordinate_system#Cartesian_coordinates
local theta = math_random() * two_pi
local phi = math_random() * two_pi
local xoff = math_round(distance * math_sin(theta) * math_cos(phi))
local yoff = math_round(distance * math_cos(theta))
local zoff = math_round(distance * math_sin(theta) * math_sin(phi))
-- Choose a random direction. Rejection sampling is simple and fast (1-2 tries usually)
local xoff, yoff, zoff, dd
repeat
xoff, yoff, zoff = math_random() * 2 - 1, math_random() * 2 - 1, math_random() * 2 - 1
dd = xoff*xoff + yoff*yoff + zoff*zoff
until (dd <= 1 and dd >= 1e-6) -- outside of uniform ball, retry
dd = distance / math_sqrt(dd) -- distance scaling factor
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(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 R1 = MOB_SPAWN_ZONE_OUTER
local d = vector_distance( pos, vector.new( goal_pos.x, pos.y, goal_pos.z ) ) -- distance from player to projected point on horizontal plane
local y1 = math_sqrt( R1*R1 - d*d ) -- absolue value of distance to outer sphere
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 y_min
local y_max
if d >= MOB_SPAWN_ZONE_INNER then
local y_min, y_max
if d2 >= MOB_SPAWN_ZONE_INNER_SQ then
-- Outer region, y range has both ends on the outer sphere
y_min = pos.y - y1
y_max = pos.y + y1
else
-- Inner region, y range spans between inner and outer spheres
local R2 = MOB_SPAWN_ZONE_INNER
local y2 = math_sqrt( R2*R2 - d*d )
if goal_pos.y > pos. y then
local y2 = math_sqrt(MOB_SPAWN_ZONE_INNER_SQ - d2)
if goal_pos.y > pos.y then
-- Upper hemisphere
y_min = pos.y + y2
y_max = pos.y + y1
@ -675,16 +476,9 @@ local function get_next_mob_spawn_pos(pos)
y_max = pos.y - y2
end
end
y_min = math_round(y_min)
y_max = math_round(y_max)
-- Limit total range of check to 32 nodes (maximum of 3 map blocks)
if y_max > goal_pos.y + 16 then
y_max = goal_pos.y + 16
end
if y_min < goal_pos.y - 16 then
y_min = goal_pos.y - 16
end
y_min = math_max(math_floor(y_min), goal_pos.y - 16)
y_max = math_min(math_ceil(y_max), goal_pos.y + 16)
-- Ask engine for valid spawn locations
local spawning_position_list = find_nodes_in_area_under_air(
@ -716,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
@ -736,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)
@ -748,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
@ -768,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
@ -997,7 +820,7 @@ if mobs_spawn then
mob_total_wide = 0
end
local cap_space_wide = math.max(type_cap - mob_total_wide, 0)
local cap_space_wide = math_max(type_cap - mob_total_wide, 0)
mcl_log("mob_type", mob_type)
mcl_log("cap_space_wide", cap_space_wide)
@ -1005,10 +828,10 @@ if mobs_spawn then
local cap_space_available = 0
if mob_type == "hostile" then
mcl_log("cap_space_global", cap_space_hostile)
cap_space_available = math.min(cap_space_hostile, cap_space_wide)
cap_space_available = math_min(cap_space_hostile, cap_space_wide)
else
mcl_log("cap_space_global", cap_space_non_hostile)
cap_space_available = math.min(cap_space_non_hostile, cap_space_wide)
cap_space_available = math_min(cap_space_non_hostile, cap_space_wide)
end
local mob_total_close = mob_counts_close[mob_type]
@ -1017,8 +840,8 @@ if mobs_spawn then
mob_total_close = 0
end
local cap_space_close = math.max(close_zone_cap - mob_total_close, 0)
cap_space_available = math.min(cap_space_available, cap_space_close)
local cap_space_close = math_max(close_zone_cap - mob_total_close, 0)
cap_space_available = math_min(cap_space_available, cap_space_close)
mcl_log("cap_space_close", cap_space_close)
mcl_log("cap_space_available", cap_space_available)
@ -1145,7 +968,7 @@ if mobs_spawn then
local amount_to_spawn = math.random(group_min, spawn_in_group)
mcl_log("Spawning quantity: " .. amount_to_spawn)
amount_to_spawn = math.min(amount_to_spawn, cap_space_available)
amount_to_spawn = math_min(amount_to_spawn, cap_space_available)
mcl_log("throttled spawning quantity: " .. amount_to_spawn)
if logging then
@ -1196,8 +1019,8 @@ if mobs_spawn then
local players = get_connected_players()
local total_mobs, total_non_hostile, total_hostile = count_mobs_total_cap()
local cap_space_hostile = math.max(mob_cap.global_hostile - total_hostile, 0)
local cap_space_non_hostile = math.max(mob_cap.global_non_hostile - total_non_hostile, 0)
local cap_space_hostile = math_max(mob_cap.global_hostile - total_hostile, 0)
local cap_space_non_hostile = math_max(mob_cap.global_non_hostile - total_non_hostile, 0)
mcl_log("global cap_space_hostile", cap_space_hostile)
mcl_log("global cap_space_non_hostile", cap_space_non_hostile)
@ -1274,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

@ -95,8 +95,8 @@ mcl_mobs.register_mob("mobs_mc:blaze", {
end
local pos = self.object:get_pos()
minetest.add_particle({
pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2},
velocity = {x=0, y=math.random(1,1), z=0},
pos = {x=pos.x+(math.random()*0.7-0.35)*math.random(),y=pos.y+0.7+math.random()*0.5,z=pos.z+(math.random()*0.7-0.35)*math.random()},
velocity = {x=0, y=1, z=0},
expirationtime = math.random(),
size = math.random(1, 4),
collisiondetection = true,
@ -110,8 +110,8 @@ mcl_mobs.register_mob("mobs_mc:blaze", {
},
})
minetest.add_particle({
pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2},
velocity = {x=0, y=math.random(1,1), z=0},
pos = {x=pos.x+(math.random()*0.7-0.35)*math.random(),y=pos.y+0.7+math.random()*0.5,z=pos.z+(math.random()*0.7-0.35)*math.random()},
velocity = {x=0, y=1, z=0},
expirationtime = math.random(),
size = math.random(1, 4),
collisiondetection = true,
@ -125,8 +125,8 @@ mcl_mobs.register_mob("mobs_mc:blaze", {
},
})
minetest.add_particle({
pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2},
velocity = {x=0, y=math.random(1,1), z=0},
pos = {x=pos.x+(math.random()*0.7-0.35)*math.random(),y=pos.y+0.7+math.random()*0.5,z=pos.z+(math.random()*0.7-0.35)*math.random()},
velocity = {x=0, y=1, z=0},
expirationtime = math.random(),
size = math.random(1, 4),
collisiondetection = true,

View File

@ -84,7 +84,7 @@ local cod = {
self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0))
if minetest.get_item_group(self.standing_in, "water") ~= 0 then
if self.object:get_velocity().y < 5 then
self.object:add_velocity({ x = 0 , y = math.random(-.007, .007), z = 0 })
self.object:add_velocity({ x = 0 , y = math.random()*.014-.007, z = 0 })
end
end
--]]

View File

@ -81,16 +81,16 @@ local dolphin = {
reach = 2,
damage = 2.5,
attack_type = "dogfight",
--[[ this is supposed to make them jump out the water but doesn't appear to work very well
do_custom = function(self,dtime)
--[[ this is supposed to make them jump out the water but doesn't appear to work very well
self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0))
if minetest.get_item_group(self.standing_in, "water") ~= 0 then
if self.object:get_velocity().y < 5 then
self.object:add_velocity({ x = 0 , y = math.random(-.007, .007), z = 0 })
self.object:add_velocity({ x = 0 , y = math.random()*.014-.007, z = 0 })
end
end
--]]
end,
--]]
}
mcl_mobs.register_mob("mobs_mc:dolphin", dolphin)

View File

@ -4,21 +4,17 @@
local S = minetest.get_translator("mobs_mc")
local BEAM_CHECK_FREQUENCY = 2
local BEAM_CHECK_FREQUENCY = 1
local POS_CHECK_FREQUENCY = 15
local HEAL_AMMOUNT = 37
local HEAL_INTERVAL = 1
local HEAL_AMOUNT = 2
local function heal(self)
local o = self.object
self.health = math.min(self.hp_max,self.health + HEAL_AMMOUNT)
end
local function check_beam(self)
for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do
local luaentity = obj:get_luaentity()
if luaentity and luaentity.name == "mcl_end:crystal" then
if luaentity.beam then
if luaentity.beam == self.beam then
heal(self)
break
end
else
@ -106,7 +102,6 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", {
},
ignores_nametag = true,
do_custom = function(self,dtime)
mcl_bossbars.update_boss(self.object, "Ender Dragon", "light_purple")
if self._pos_timer == nil or self._pos_timer > POS_CHECK_FREQUENCY then
self._pos_timer = 0
check_pos(self)
@ -115,8 +110,20 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", {
self._beam_timer = 0
check_beam(self)
end
self._beam_timer = self._beam_timer + dtime
self._pos_timer = self._pos_timer + dtime
if self.beam ~= nil then
-- heal
self._heal_timer = (self._heal_timer or 0) + dtime
if self._heal_timer > HEAL_INTERVAL then
self.health = math.min(self.hp_max,self.health + HEAL_AMOUNT)
self._heal_timer = self._heal_timer - HEAL_INTERVAL
end
end
mcl_bossbars.update_boss(self.object, "Ender Dragon", "light_purple")
end,
on_die = function(self, pos, cmi_cause)
if self._portal_pos then

View File

@ -83,8 +83,8 @@ mcl_mobs.register_mob("mobs_mc:iron_golem", {
stand_speed = 15, walk_speed = 15, run_speed = 25, punch_speed = 15,
stand_start = 0, stand_end = 0,
walk_start = 0, walk_end = 40,
run_start = 0, run_end = 40,
punch_start = 40, punch_end = 50,
run_start = 40, run_end = 80,
punch_start = 80, punch_end = 90,
},
jump = true,
do_custom = function(self, dtime)

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

@ -360,7 +360,7 @@ piglin_brute.xp_min = 20
piglin_brute.xp_max = 20
piglin_brute.hp_min = 50
piglin_brute.hp_max = 50
piglin_brute.fire_resistant = 1
piglin_brute.fire_resistant = false
piglin_brute.do_custom = function()
return
end
@ -371,8 +371,8 @@ piglin_brute.on_rightclick = function()
return
end
piglin_brute.attacks_monsters = true
piglin_brute.lava_damage = 0
piglin_brute.fire_damage = 0
piglin_brute.lava_damage = 4
piglin_brute.fire_damage = 2
piglin_brute.attack_animals = true
piglin_brute.mesh = "extra_mobs_sword_piglin.b3d"
piglin_brute.textures = {"extra_mobs_piglin_brute.png", "default_tool_goldaxe.png", "extra_mobs_trans.png"}

View File

@ -52,7 +52,7 @@ local salmon = {
makes_footstep_sound = false,
swim = true,
fly = true,
fly_in = "mcl_core:water_source",
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
breathes_in_water = true,
jump = false,
view_range = 16,

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(0, math.pi*2)
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

@ -97,7 +97,7 @@ local tropical_fish = {
makes_footstep_sound = false,
swim = true,
fly = true,
fly_in = "mcl_core:water_source",
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
breathes_in_water = true,
jump = false,
view_range = 16,

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(0, math.pi*2)
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

@ -1,5 +1,5 @@
name = mcl_weather
author = xeranas
description = Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience
depends = mcl_init, mcl_worlds
depends = mcl_init, mcl_worlds, mcl_playerinfo, mcl_util
optional_depends = lightning

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"})

View File

@ -1,15 +1,19 @@
local mods_loaded = false
-- Constants
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local NIGHT_VISION_RATIO = 0.45
local MINIMUM_LIGHT_LEVEL = 0.2
-- Settings
local minimum_update_interval = { 250e3 }
local water_color = "#3F76E4"
local mg_name = minetest.get_mapgen_setting("mg_name")
-- Module state
local mods_loaded = false
function mcl_weather.set_sky_box_clear(player, sky, fog)
local pos = player:get_pos()
if minetest.get_item_group(minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name, "water") ~= 0 then return end
-- Make sure the player's head isn't in water before changing the skybox
local node_head = mcl_playerinfo[player:get_player_name()].node_head
if minetest.get_item_group(node_head, "water") ~= 0 then return end
local sc = {
day_sky = "#7BA4FF",
day_horizon = "#C0D8FF",
@ -38,8 +42,10 @@ function mcl_weather.set_sky_box_clear(player, sky, fog)
end
function mcl_weather.set_sky_color(player, def)
local pos = player:get_pos()
if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1.5, 0)).name, "water") ~= 0 then return end
-- Make sure the player's head isn't in water before changing the skybox
local node_head = mcl_playerinfo[player:get_player_name()].node_head
if minetest.get_item_group(node_head, "water") ~= 0 then return end
player:set_sky({
type = def.type,
sky_color = def.sky_color,
@ -47,25 +53,7 @@ function mcl_weather.set_sky_color(player, def)
})
end
-- Function to work out light modifier at different times
-- Noon is brightest, midnight is darkest, 0600 and 18000 is in the middle of this
local function get_light_modifier(time)
-- 0.1 = 0.2
-- 0.4 = 0.8
-- 0.5 = 1
-- 0.6 = 0.8
-- 0.9 = 0.2
local light_multiplier = time * 2
if time > 0.5 then
light_multiplier = 2 * (1 - time)
else
light_multiplier = time / 0.5
end
return light_multiplier
end
mcl_weather.skycolor = {
local skycolor = {
-- Should be activated before do any effect.
active = true,
@ -85,319 +73,205 @@ mcl_weather.skycolor = {
-- number of colors while constructing gradient of user given colors
max_val = 1000,
NIGHT_VISION_RATIO = NIGHT_VISION_RATIO,
-- Table for tracking layer order
layer_names = {},
-- To layer to colors table
add_layer = function(layer_name, layer_color, instant_update)
mcl_weather.skycolor.colors[layer_name] = layer_color
table.insert(mcl_weather.skycolor.layer_names, layer_name)
mcl_weather.skycolor.force_update = true
end,
current_layer_name = function()
return mcl_weather.skycolor.layer_names[#mcl_weather.skycolor.layer_names]
end,
-- Retrieve layer from colors table
retrieve_layer = function()
local last_layer = mcl_weather.skycolor.current_layer_name()
return mcl_weather.skycolor.colors[last_layer]
end,
-- Remove layer from colors table
remove_layer = function(layer_name)
for k, name in pairs(mcl_weather.skycolor.layer_names) do
if name == layer_name then
table.remove(mcl_weather.skycolor.layer_names, k)
mcl_weather.skycolor.force_update = true
return
end
end
end,
-- Wrapper for updating day/night ratio that respects night vision
override_day_night_ratio = function(player, ratio)
local meta = player:get_meta()
local has_night_vision = meta:get_int("night_vision") == 1
local has_darkness = meta:get_int("darkness") == 1
local is_visited_shepherd = meta:get_int("mcl_shepherd:special") == 1
local arg
if has_darkness and not is_visited_shepherd then
if has_night_vision then arg = 0.1
else arg = 0 end
else
-- Apply night vision only for dark sky
local is_dark = minetest.get_timeofday() > 0.8 or minetest.get_timeofday() < 0.2 or mcl_weather.state ~= "none"
local pos = player:get_pos()
local dim = mcl_worlds.pos_to_dimension(pos)
if (has_night_vision or is_visited_shepherd) and is_dark and dim ~= "nether" and dim ~= "end" then
if ratio == nil then
arg = NIGHT_VISION_RATIO
else
arg = math.max(ratio, NIGHT_VISION_RATIO)
end
else
arg = ratio
end
end
player:override_day_night_ratio(arg)
end,
-- Update sky color. If players not specified update sky for all players.
update_sky_color = function(players)
-- Override day/night ratio as well
players = mcl_weather.skycolor.utils.get_players(players)
for _, player in ipairs(players) do
local pos = player:get_pos()
local dim = mcl_worlds.pos_to_dimension(pos)
local has_weather = (mcl_worlds.has_weather(pos) and (mcl_weather.state == "snow" or mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_snow(pos)) or ((mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_rain(pos))
local checkname = minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name
if minetest.get_item_group(checkname, "water") ~= 0 then
local biome_index = minetest.get_biome_data(player:get_pos()).biome
local biome_name = minetest.get_biome_name(biome_index)
local biome = minetest.registered_biomes[biome_name]
if biome then water_color = biome._mcl_waterfogcolor end
if not biome then water_color = "#3F76E4" end
if checkname == "mclx_core:river_water_source" or checkname == "mclx_core:river_water_flowing" then water_color = "#0084FF" end
player:set_sky({ type = "regular",
sky_color = {
day_sky = water_color,
day_horizon = water_color,
dawn_sky = water_color,
dawn_horizon = water_color,
night_sky = water_color,
night_horizon = water_color,
indoors = water_color,
fog_sun_tint = water_color,
fog_moon_tint = water_color,
fog_tint_type = "custom"
},
clouds = false,
})
end
if dim == "overworld" then
local biomesky
local biomefog
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local biome_index = minetest.get_biome_data(player:get_pos()).biome
local biome_name = minetest.get_biome_name(biome_index)
local biome = minetest.registered_biomes[biome_name]
if biome then
--minetest.log("action", string.format("Biome found for number: %s in biome: %s", tostring(biome_index), biome_name))
biomesky = biome._mcl_skycolor
biomefog = biome._mcl_fogcolor
else
--minetest.log("action", string.format("No biome for number: %s in biome: %s", tostring(biome_index), biome_name))
end
end
if (mcl_weather.state == "none") then
-- Clear weather
mcl_weather.set_sky_box_clear(player,biomesky,biomefog)
player:set_sun({visible = true, sunrise_visible = true})
player:set_moon({visible = true})
player:set_stars({visible = true})
mcl_weather.skycolor.override_day_night_ratio(player, nil)
elseif not has_weather then
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.15)
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27)
local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1)
mcl_weather.set_sky_color(player, {
type = "regular",
sky_color = {
day_sky = day_color,
day_horizon = day_color,
dawn_sky = dawn_color,
dawn_horizon = dawn_color,
night_sky = night_color,
night_horizon = night_color,
},
clouds = true,
})
player:set_sun({visible = false, sunrise_visible = false})
player:set_moon({visible = false})
player:set_stars({visible = false})
elseif has_weather then
-- Weather skies
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75)
local night_color = mcl_weather.skycolor.get_sky_layer_color(0)
mcl_weather.set_sky_color(player, {
type = "regular",
sky_color = {
day_sky = day_color,
day_horizon = day_color,
dawn_sky = dawn_color,
dawn_horizon = dawn_color,
night_sky = night_color,
night_horizon = night_color,
},
clouds = true,
})
player:set_sun({visible = false, sunrise_visible = false})
player:set_moon({visible = false})
player:set_stars({visible = false})
local light_factor = mcl_weather.get_current_light_factor()
if mcl_weather.skycolor.current_layer_name() == "lightning" then
mcl_weather.skycolor.override_day_night_ratio(player, 1)
elseif light_factor then
local time = minetest.get_timeofday()
local light_multiplier = get_light_modifier(time)
local new_light = math.max(light_factor * light_multiplier, MINIMUM_LIGHT_LEVEL)
mcl_weather.skycolor.override_day_night_ratio(player, new_light)
else
mcl_weather.skycolor.override_day_night_ratio(player, nil)
end
end
elseif dim == "end" then
local biomesky = "#000000"
local biomefog = "#A080A0"
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local biome_index = minetest.get_biome_data(player:get_pos()).biome
local biome_name = minetest.get_biome_name(biome_index)
local biome = minetest.registered_biomes[biome_name]
if biome then
--minetest.log("action", string.format("Biome found for number: %s in biome: %s", tostring(biome_index), biome_name))
biomesky = biome._mcl_skycolor
biomefog = biome._mcl_fogcolor -- The End biomes seemingly don't use the fog colour, despite having this value according to the wiki. The sky colour is seemingly used for both sky and fog?
else
--minetest.log("action", string.format("No biome for number: %s in biome: %s", tostring(biome_index), biome_name))
end
end
local t = "mcl_playerplus_end_sky.png"
player:set_sky({ type = "skybox",
base_color = biomesky,
textures = {t,t,t,t,t,t},
clouds = false,
})
player:set_sun({visible = false , sunrise_visible = false})
player:set_moon({visible = false})
player:set_stars({visible = false})
mcl_weather.skycolor.override_day_night_ratio(player, 0.5)
elseif dim == "nether" then
local biomesky = "#6EB1FF"
local biomefog = "#330808"
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local biome_index = minetest.get_biome_data(player:get_pos()).biome
local biome_name = minetest.get_biome_name(biome_index)
local biome = minetest.registered_biomes[biome_name]
if biome then
--minetest.log("action", string.format("Biome found for number: %s in biome: %s", tostring(biome_index), biome_name))
biomesky = biome._mcl_skycolor -- The Nether biomes seemingly don't use the sky colour, despite having this value according to the wiki. The fog colour is used for both sky and fog.
biomefog = biome._mcl_fogcolor
else
--minetest.log("action", string.format("No biome for number: %s in biome: %s", tostring(biome_index), biome_name))
end
end
mcl_weather.set_sky_color(player, {
type = "regular",
sky_color = {
day_sky = biomefog,
day_horizon = biomefog,
dawn_sky = biomefog,
dawn_horizon = biomefog,
night_sky = biomefog,
night_horizon = biomefog,
indoors = biomefog,
fog_sun_tint = biomefog,
fog_moon_tint = biomefog,
fog_tint_type = "custom"
},
clouds = false,
})
player:set_sun({visible = false , sunrise_visible = false})
player:set_moon({visible = false})
player:set_stars({visible = false})
mcl_weather.skycolor.override_day_night_ratio(player, nil)
elseif dim == "void" then
player:set_sky({ type = "plain",
base_color = "#000000",
clouds = false,
})
player:set_sun({visible = false, sunrise_visible = false})
player:set_moon({visible = false})
player:set_stars({visible = false})
end
end
end,
-- Returns current layer color in {r, g, b} format
get_sky_layer_color = function(timeofday)
if #mcl_weather.skycolor.layer_names == 0 then
return nil
end
-- min timeofday value 0; max timeofday value 1. So sky color gradient range will be between 0 and 1 * mcl_weather.skycolor.max_val.
local rounded_time = math.floor(timeofday * mcl_weather.skycolor.max_val)
local color = mcl_weather.skycolor.utils.convert_to_rgb(mcl_weather.skycolor.min_val, mcl_weather.skycolor.max_val, rounded_time, mcl_weather.skycolor.retrieve_layer())
return color
end,
utils = {
convert_to_rgb = function(minval, maxval, current_val, colors)
local max_index = #colors - 1
local val = (current_val-minval) / (maxval-minval) * max_index + 1.0
local index1 = math.floor(val)
local index2 = math.min(math.floor(val)+1, max_index + 1)
local f = val - index1
local c1 = colors[index1]
local c2 = colors[index2]
return {r=math.floor(c1.r + f*(c2.r - c1.r)), g=math.floor(c1.g + f*(c2.g-c1.g)), b=math.floor(c1.b + f*(c2.b - c1.b))}
end,
-- Simply getter. Ether returns user given players list or get all connected players if none provided
get_players = function(players)
if players == nil or #players == 0 then
if mods_loaded then
players = minetest.get_connected_players()
elseif players == nil then
players = {}
end
end
return players
end,
-- Returns first player sky color. I assume that all players are in same color layout.
get_current_bg_color = function()
local players = mcl_weather.skycolor.utils.get_players(nil)
if players[1] then
return players[1]:get_sky(true).sky_color
end
return nil
end
},
utils = {},
}
mcl_weather.skycolor = skycolor
local skycolor_utils = skycolor.utils
-- Add layer to colors table
function skycolor.add_layer(layer_name, layer_color, instant_update)
skycolor.colors[layer_name] = layer_color
table.insert(skycolor.layer_names, layer_name)
skycolor.force_update = true
end
function skycolor.current_layer_name()
return skycolor.layer_names[#skycolor.layer_names]
end
-- Retrieve layer from colors table
function skycolor.retrieve_layer()
local last_layer = skycolor.current_layer_name()
return skycolor.colors[last_layer]
end
-- Remove layer from colors table
function skycolor.remove_layer(layer_name)
for k, name in pairs(skycolor.layer_names) do
if name == layer_name then
table.remove(skycolor.layer_names, k)
skycolor.force_update = true
return
end
end
end
-- Wrapper for updating day/night ratio that respects night vision
function skycolor.override_day_night_ratio(player, ratio)
player._skycolor_day_night_ratio = ratio
skycolor.update_player_sky_color(player)
player._skycolor_day_night_ratio = nil
end
local skycolor_filters = {}
skycolor.filters = skycolor_filters
dofile(modpath.."/skycolor/water.lua")
dofile(modpath.."/skycolor/dimensions.lua")
dofile(modpath.."/skycolor/effects.lua")
local function get_skycolor_info(player)
local player_name = player:get_player_name()
local info = mcl_playerinfo[player_name] or {}
local skycolor_data = info.skycolor
if not skycolor_data then
skycolor_data = {}
info.skycolor = skycolor_data
end
return skycolor_data
end
local water_sky = skycolor.water_sky
function skycolor.update_player_sky_color(player)
-- Don't update more than once every 250 milliseconds
local skycolor_data = get_skycolor_info(player)
local last_update = skycolor_data.last_update or 0
local now_us = minetest.get_us_time()
if (now_us - last_update) < minimum_update_interval[1] then return end
skycolor_data.last_update = now_us
local sky_data = {
day_night_ratio = player._skycolor_day_night_ratio
}
for i = 1,#skycolor_filters do
skycolor_filters[i](player, sky_data)
end
assert(sky_data.sky)
player:set_sky(sky_data.sky)
if sky_data.sun then player:set_sun(sky_data.sun) end
if sky_data.moon then player:set_moon(sky_data.moon) end
if sky_data.stars then player:set_stars(sky_data.stars) end
player:override_day_night_ratio(sky_data.day_night_ratio)
end
-- Update sky color. If players not specified update sky for all players.
function skycolor.update_sky_color(players)
-- Override day/night ratio as well
players = skycolor_utils.get_players(players)
local update = skycolor.update_player_sky_color
for _, player in ipairs(players) do
update(player)
end
end
-- Returns current layer color in {r, g, b} format
function skycolor.get_sky_layer_color(timeofday)
if #skycolor.layer_names == 0 then
return nil
end
-- min timeofday value 0; max timeofday value 1. So sky color gradient range will be between 0 and 1 * skycolor.max_val
local rounded_time = math.floor(timeofday * skycolor.max_val)
return skycolor_utils.convert_to_rgb(
skycolor.min_val, skycolor.max_val,
rounded_time, skycolor.retrieve_layer()
)
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)
-- 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
-- Get the first color's values
local index1 = math.floor(scaled_value)
local color1 = colors[index1]
local frac1 = 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)
local frac2 = 1.0 - frac1
local color2 = colors[index2]
-- Interpolate between color1 and color2
return {
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),
}
end
-- Simple getter. Either returns user given players list or get all connected players if none provided
function skycolor_utils.get_players(players)
if players == nil or #players == 0 then
if mods_loaded then
players = minetest.get_connected_players()
elseif players == nil then
players = {}
end
end
return players
end
-- Returns the sky color of the first player, which is done assuming that all players are in same color layout.
function skycolor_utils.get_current_bg_color()
local players = skycolor_utils.get_players(nil)
if players[1] then
return players[1]:get_sky(true).sky_color
end
return nil
end
local timer = 0
minetest.register_globalstep(function(dtime)
if mcl_weather.skycolor.active ~= true or #minetest.get_connected_players() == 0 then
if skycolor.active ~= true or #minetest.get_connected_players() == 0 then
return
end
if mcl_weather.skycolor.force_update then
mcl_weather.skycolor.update_sky_color()
mcl_weather.skycolor.force_update = false
if skycolor.force_update then
skycolor.update_sky_color()
skycolor.force_update = false
return
end
-- regular updates based on iterval
timer = timer + dtime;
if timer >= mcl_weather.skycolor.update_interval then
mcl_weather.skycolor.update_sky_color()
if timer >= skycolor.update_interval then
skycolor.update_sky_color()
timer = 0
end
end)
local function initsky(player)
if player.set_lighting then
player:set_lighting({ shadows = { intensity = tonumber(minetest.settings:get("mcl_default_shadow_intensity") or 0.33) } })
player:set_lighting({
shadows = { intensity = 0.33 },
volumetric_light = { strength = 0.45 },
exposure = {
luminance_min = -3.5,
luminance_max = -2.5,
exposure_correction = 0.35,
speed_dark_bright = 1500,
speed_bright_dark = 700,
},
saturation = 1.1,
})
end
if (mcl_weather.skycolor.active) then
if (skycolor.active) then
mcl_weather.skycolor.force_update = true
end
@ -408,7 +282,7 @@ minetest.register_on_joinplayer(initsky)
minetest.register_on_respawnplayer(initsky)
mcl_worlds.register_on_dimension_change(function(player)
mcl_weather.skycolor.update_sky_color({player})
skycolor.update_sky_color({player})
end)
minetest.register_on_mods_loaded(function()

View File

@ -0,0 +1,184 @@
local MINIMUM_LIGHT_LEVEL = 0.2
local VALID_SNOW_WEATHER_STATES = { snow = true, rain = true, thunder = true }
local VALID_RAIN_WEATHER_STATES = { rain = true, thunder = true }
local mg_name = minetest.get_mapgen_setting("mg_name")
local dimension_handlers = {}
mcl_weather.skycolor.dimension_handlers = dimension_handlers
-- Function to work out light modifier at different times
-- Noon is brightest, midnight is darkest, 0600 and 1800 is in the middle of this
local function get_light_modifier(time)
-- 0.1 = 0.2
-- 0.4 = 0.8
-- 0.5 = 1
-- 0.6 = 0.8
-- 0.9 = 0.2
local light_multiplier = time * 2
if time > 0.5 then
light_multiplier = 2 * (1 - time)
else
light_multiplier = time / 0.5
end
return light_multiplier
end
function dimension_handlers.overworld(player, sky_data)
local pos = player:get_pos()
local biomesky
local biomefog
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local biome_index = minetest.get_biome_data(player:get_pos()).biome
local biome_name = minetest.get_biome_name(biome_index)
local biome = minetest.registered_biomes[biome_name]
if biome then
biomesky = biome._mcl_skycolor
biomefog = biome._mcl_fogcolor
end
end
-- Use overworld defaults
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.15)
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27)
local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1)
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,
}
sky_data.sun = {visible = true, sunrise_visible = true}
sky_data.moon = {visible = true}
sky_data.stars = {visible = true}
if mcl_weather.state == "none" then
-- Clear weather
mcl_weather.set_sky_box_clear(player,biomesky,biomefog)
return
end
-- Check if we currently have weather that affects the sky color
local has_weather = mcl_worlds.has_weather(pos) and (
mcl_weather.has_snow(pos) and VALID_SNOW_WEATHER_STATES[mcl_weather.state] or
mcl_weather.has_rain(pos) and VALID_RAIN_WEATHER_STATES[mcl_weather.state]
)
if has_weather then
-- Weather skies
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75)
local night_color = mcl_weather.skycolor.get_sky_layer_color(0)
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,
}
sky_data.sun = {visible = false, sunrise_visible = false}
sky_data.moon = {visible = false}
sky_data.stars = {visible = false}
local light_factor = mcl_weather.get_current_light_factor()
if mcl_weather.skycolor.current_layer_name() == "lightning" then
sky_data.day_night_ratio = 1
elseif light_factor then
local time = minetest.get_timeofday()
local light_multiplier = get_light_modifier(time)
local new_light = math.max(light_factor * light_multiplier, MINIMUM_LIGHT_LEVEL)
sky_data.day_night_ratio = new_light
end
end
end
-- This can't be function dimension_handlers.end() due to lua syntax
dimension_handlers["end"] = function(player, sky_data)
local biomesky = "#000000"
local biomefog = "#A080A0"
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local biome_index = minetest.get_biome_data(player:get_pos()).biome
local biome_name = minetest.get_biome_name(biome_index)
local biome = minetest.registered_biomes[biome_name]
if biome then
biomesky = biome._mcl_skycolor
biomefog = biome._mcl_fogcolor -- The End biomes seemingly don't use the fog colour, despite having this value according to the wiki. The sky colour is seemingly used for both sky and fog?
end
end
local t = "mcl_playerplus_end_sky.png"
sky_data.sky = { type = "skybox",
base_color = biomesky,
textures = {t,t,t,t,t,t},
clouds = false,
}
sky_data.sun = {visible = false , sunrise_visible = false}
sky_data.moon = {visible = false}
sky_data.stars = {visible = false}
sky_data.day_night_ratio = 0.5
end
function dimension_handlers.nether(player, sky_data)
local biomesky = "#6EB1FF"
local biomefog = "#330808"
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local biome_index = minetest.get_biome_data(player:get_pos()).biome
local biome_name = minetest.get_biome_name(biome_index)
local biome = minetest.registered_biomes[biome_name]
if biome then
-- The Nether biomes seemingly don't use the sky colour, despite having this value according to the wiki.
-- The fog colour is used for both sky and fog.
biomesky = biome._mcl_skycolor
biomefog = biome._mcl_fogcolor
end
end
sky_data.sky = {
type = "regular",
sky_color = {
day_sky = biomefog,
day_horizon = biomefog,
dawn_sky = biomefog,
dawn_horizon = biomefog,
night_sky = biomefog,
night_horizon = biomefog,
indoors = biomefog,
fog_sun_tint = biomefog,
fog_moon_tint = biomefog,
fog_tint_type = "custom"
},
clouds = false,
}
sky_data.sun = {visible = false , sunrise_visible = false}
sky_data.moon = {visible = false}
sky_data.stars = {visible = false}
end
function dimension_handlers.void(player, sky_data)
sky_data.sky = { type = "plain",
base_color = "#000000",
clouds = false,
}
sky_data.sun = {visible = false, sunrise_visible = false}
sky_data.moon = {visible = false}
sky_data.stars = {visible = false}
end
local function dimension(player, sky_data)
local pos = player:get_pos()
local dim = mcl_worlds.pos_to_dimension(pos)
local handler = dimension_handlers[dim]
if handler then return handler(player, sky_data) end
end
table.insert(mcl_weather.skycolor.filters, dimension)

View File

@ -0,0 +1,56 @@
local DIM_ALLOW_NIGHT_VISION = {
overworld = true,
void = true,
}
local NIGHT_VISION_RATIO = mcl_weather.skycolor.NIGHT_VISION_RATIO
local effects_handlers = {}
local has_mcl_potions = mcl_util.to_bool(minetest.get_modpath("mcl_potions"))
function effects_handlers.darkness(player, meta, effect, sky_data)
-- No darkness effect if is a visited shepherd
if meta:get_int("mcl_shepherd:special") == 1 then return end
-- High stars
sky_data.stars = {visible = false}
-- Minor visibility if the player has the night vision effect
if mcl_potions.has_effect(player, "night_vision") then
sky_data.day_night_ratio = 0.1
else
sky_data.day_night_ratio = 0
end
end
function effects_handlers.night_vision(player, meta, effect, sky_data)
-- Apply night vision only for dark sky
if not (minetest.get_timeofday() > 0.8 or minetest.get_timeofday() < 0.2 or mcl_weather.state ~= "none") then return end
-- Only some dimensions allow night vision
local pos = player:get_pos()
local dim = mcl_worlds.pos_to_dimension(pos)
if not DIM_ALLOW_NIGHT_VISION[dim] then return end
-- Apply night vision
sky_data.day_night_ratio = math.max(sky_data.day_night_ratio or 0, NIGHT_VISION_RATIO)
end
local function effects(player, sky_data)
if not has_mcl_potions then return end
local meta = player:get_meta()
for name,effect in pairs(mcl_potions.registered_effects) do
local effect_data = mcl_potions.get_effect(player, name)
if effect_data then
local hook = effect.mcl_weather_skycolor or effects_handlers[name]
if hook then hook(player, meta, effect_data, sky_data) end
end
end
-- Handle night vision for shepherd
if meta:get_int("mcl_shepherd:special") == 1 then
return effects_handlers.night_vision(player, meta, {}, sky_data)
end
end
table.insert(mcl_weather.skycolor.filters, effects)

View File

@ -0,0 +1,40 @@
local DEFAULT_WATER_COLOR = "#3F76E4"
local mg_name = minetest.get_mapgen_setting("mg_name")
local function water_sky(player, sky_data)
local water_color = DEFAULT_WATER_COLOR
local checkname = mcl_playerinfo[player:get_player_name()].node_head
if minetest.get_item_group(checkname, "water") == 0 then return end
local pos = player:get_pos()
local biome = nil
if mg_name ~= "v6" and mg_name ~= "singlenode" then
local biome_index = minetest.get_biome_data(pos).biome
local biome_name = minetest.get_biome_name(biome_index)
biome = minetest.registered_biomes[biome_name]
end
if biome then water_color = biome._mcl_waterfogcolor end
if not biome then water_color = DEFAULT_WATER_COLOR end
if checkname == "mclx_core:river_water_source" or checkname == "mclx_core:river_water_flowing" then water_color = "#0084FF" end
sky_data.sky = { type = "regular",
sky_color = {
day_sky = water_color,
day_horizon = water_color,
dawn_sky = water_color,
dawn_horizon = water_color,
night_sky = water_color,
night_horizon = water_color,
indoors = water_color,
fog_sun_tint = water_color,
fog_moon_tint = water_color,
fog_tint_type = "custom"
},
clouds = true,
}
end
table.insert(mcl_weather.skycolor.filters, water_sky)

View File

@ -10,6 +10,10 @@ mcl_weather.thunder = {
init_done = false,
}
lightning.register_on_strike(function(pos, pos2, objects)
if not mcl_weather.has_rain(pos) then return nil, true end
end)
minetest.register_globalstep(function(dtime)
if mcl_weather.get_weather() ~= "thunder" then
return false

View File

@ -678,6 +678,7 @@ local function make_formspec(name)
image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;]
image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;]
field_close_on_enter[filter;false]
field_enter_after_edit[filter;true]
]]
fs[#fs + 1] = fmt([[ tooltip[search;%s]

View File

@ -126,6 +126,9 @@ S("• I: Show/hide inventory menu").."\n\n"..
S("Inventory interaction:").."\n"..
S("See the entry “Basics > Inventory”.").."\n\n"..
S("Hunger/Eating:").."\n"..
S("• While holding food, hold the right mouse button (PC) or double-tap and hold the second tap (Android) to eat").."\n\n"..
S("Camera:").."\n"..
S("• Z: Zoom").."\n"..
S("• F7: Toggle camera mode").."\n\n"..

View File

@ -78,6 +78,8 @@ World interaction:=
• I: Show/hide inventory menu=
Inventory interaction:=
See the entry “Basics > Inventory”.=
Hunger/Eating:=
• While holding food, hold the right mouse button (PC) or double-tap and hold the second tap (Android) to eat=
Camera:=
• Z: Zoom=
• F7: Toggle camera mode=

View File

@ -37,6 +37,8 @@ end
-- Digging capabilities of tool
tt.register_snippet(function(itemstring, toolcaps, itemstack)
local def = minetest.registered_items[itemstring]
if not def then return end
if not toolcaps then
return
end
@ -165,6 +167,8 @@ end)]]
-- Food
tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring]
if not def then return end
local desc
if def._tt_food then
desc = S("Food item")
@ -179,6 +183,8 @@ end)
-- Node info
tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring]
if not def then return end
local desc = ""
-- Health-related node facts

View File

@ -64,6 +64,8 @@ end)
tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring]
if not def then return end
local s = ""
if def.groups.eatable and def.groups.eatable > 0 then
s = s .. S("Hunger points: +@1", def.groups.eatable)
@ -89,6 +91,8 @@ end)
tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring]
if not def then return end
if def.groups.place_flowerlike == 1 then
return S("Grows on grass blocks or dirt")
elseif def.groups.place_flowerlike == 2 then
@ -98,6 +102,8 @@ end)
tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring]
if not def then return end
if def.groups.flammable then
return S("Flammable")
end
@ -127,6 +133,8 @@ end)
tt.register_snippet(function(itemstring, _, itemstack)
if not itemstack then return end
local def = itemstack:get_definition()
if not def then return end
if def.groups._mcl_potion ~= 1 then return end
local s = ""

View File

@ -20,23 +20,12 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/snippets.lua")
-- Apply item description updates
local function apply_snippets(desc, itemstring, toolcaps, itemstack)
local first = true
-- Apply snippets
for s=1, #tt.registered_snippets do
local str, snippet_color = tt.registered_snippets[s](itemstring, toolcaps, itemstack)
if snippet_color == nil then
snippet_color = tt.COLOR_DEFAULT
end
if str then
if first then
first = false
end
desc = desc .. "\n"
if snippet_color then
desc = desc .. minetest.colorize(snippet_color, str)
else
desc = desc .. str
end
if snippet_color == nil then snippet_color = tt.COLOR_DEFAULT end
desc = desc .. "\n" .. (snippet_color and minetest.colorize(snippet_color, str) or str)
end
end
return desc
@ -67,10 +56,7 @@ function tt.reload_itemstack_description(itemstack)
if def and def._mcl_generate_description then
def._mcl_generate_description(itemstack)
elseif should_change(itemstring, def) then
local toolcaps
if def.tool_capabilities then
toolcaps = itemstack:get_tool_capabilities()
end
local toolcaps = def.tool_capabilities and itemstack:get_tool_capabilities()
local orig_desc = def._tt_original_description or def.description
if meta:get_string("name") ~= "" then
orig_desc = minetest.colorize(tt.NAME_COLOR, meta:get_string("name"))
@ -78,17 +64,13 @@ function tt.reload_itemstack_description(itemstack)
local potency = meta:get_int("mcl_potions:potion_potent")
local plus = meta:get_int("mcl_potions:potion_plus")
if potency > 0 then
local sym_potency = mcl_util.to_roman(potency+1)
orig_desc = orig_desc.. " ".. sym_potency
orig_desc = orig_desc .. " " .. mcl_util.to_roman(potency+1)
end
if plus > 0 then
local sym_plus = " "
local i = plus
while i>0 do
i = i - 1
sym_plus = sym_plus.. "+"
orig_desc = orig_desc .. " "
for i = 1, plus do
orig_desc = orig_desc .. "+"
end
orig_desc = orig_desc.. sym_plus
end
end
local desc = apply_snippets(orig_desc, itemstring, toolcaps or def.tool_capabilities, itemstack)

View File

@ -3,9 +3,7 @@
-- Custom text (_tt_help)
tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring]
if def._tt_help then
return def._tt_help
end
return def and def._tt_help or nil
end)

View File

@ -330,9 +330,16 @@ function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon
local name = player:get_player_name()
local hudtable = hb.get_hudtable(identifier)
-- hb.change_hudbar may be called with a non-existing hudbar like hunger.
if hudtable == nil then
return false
end
if not hudtable.hudstate[name] then
return false
end
local value_changed, max_changed = false, false
if new_value then

View File

@ -22,10 +22,8 @@ return {
"epCode",
"chmodsayshello",
"MrRar",
"FossFanatic ",
"SmokeyDope",
"Faerraven / Michieal",
"Codiac",
"rudzik8",
"teknomunk",
}},
@ -38,6 +36,8 @@ return {
"NO11",
"SumianVoice",
"PrairieWind",
"FossFanatic",
"Codiac",
}},
{S("Contributors"), 0x52FF00, {
"RandomLegoBrick",
@ -142,6 +142,7 @@ return {
"SOS-Games",
"Bram",
"qoheniac",
"WillConker",
}},
{S("Music"), 0xA60014, {
"Jordach for the jukebox music compilation from Big Freaking Dig",

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

@ -5,3 +5,4 @@ Error: Too many parameters!=Fehler: Zu viele Parameter!
Error: Incorrect value of XP=Fehler: Ungültiger EP-Wert
Error: Player not found=Fehler: Spieler nicht gefunden
Added @1 XP to @2, total: @3, experience level: @4=@1 EP an @2 gegeben, gesamt: @3, Erfahrungsstufe: @4
Bottle o' Enchanting=Erfahrungsfläschchen

View File

@ -1,7 +1,12 @@
local size_min, size_max = 20, 59
local delta_size = size_max - size_min
-- Constants
local size_min = 20 / 100 -- minimum size, prescaled
local size_max = 59 / 100 -- maximum size, prescaled
local delta_size = (size_max - size_min) / 10 -- Size change for each XP size level
local max_orb_age = 300 -- seconds
local gravity = vector.new(0, -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), 0)
local size_to_xp = {
-- min and max XP amount for a given size
{-32768, 2}, -- 1
{ 3, 6}, -- 2
{ 7, 16}, -- 3
@ -16,24 +21,20 @@ local size_to_xp = {
}
local function xp_to_size(xp)
local i, l = 1, #size_to_xp
xp = xp or 0
while xp > size_to_xp[i][1] and i < l do
i = i + 1
-- Find the size for the xp amount
for i=1,11 do
local bucket = size_to_xp[i]
if xp >= bucket[1] and xp <= bucket[2] then
return (i - 1) * delta_size + size_min
end
end
return ((i - 1) / (l - 1) * delta_size + size_min) / 100
-- Fallback is the minimum size
return size_min
end
local max_orb_age = 300 -- seconds
local gravity = vector.new(0, -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), 0)
local collector, pos, pos2
local direction, distance, player_velocity, goal
local currentvel, acceleration, multiplier, velocity
local node, vel, def
local is_moving, is_slippery, slippery, slip_factor
local size
local function xp_step(self, dtime)
--if item set to be collected then only execute go to player
if self.collected == true then
@ -41,33 +42,32 @@ local function xp_step(self, dtime)
self.collected = false
return
end
collector = minetest.get_player_by_name(self.collector)
local collector = minetest.get_player_by_name(self.collector)
if collector and collector:get_hp() > 0 and vector.distance(self.object:get_pos(),collector:get_pos()) < 7.25 then
self.object:set_acceleration(vector.new(0,0,0))
self.disable_physics(self)
--get the variables
pos = self.object:get_pos()
pos2 = collector:get_pos()
local pos = self.object:get_pos()
local pos2 = collector:get_pos()
player_velocity = collector:get_velocity() or collector:get_player_velocity()
local player_velocity = collector:get_velocity() or collector:get_player_velocity()
pos2.y = pos2.y + 0.8
direction = vector.direction(pos,pos2)
distance = vector.distance(pos2,pos)
multiplier = distance
local direction = vector.direction(pos,pos2)
local distance = vector.distance(pos2,pos)
local multiplier = distance
if multiplier < 1 then
multiplier = 1
end
goal = vector.multiply(direction,multiplier)
currentvel = self.object:get_velocity()
local currentvel = self.object:get_velocity()
if distance > 1 then
multiplier = 20 - distance
velocity = vector.multiply(direction,multiplier)
goal = velocity
acceleration = vector.new(goal.x-currentvel.x,goal.y-currentvel.y,goal.z-currentvel.z)
self.object:add_velocity(vector.add(acceleration,player_velocity))
local velocity = vector.multiply(direction, multiplier)
local acceleration = vector.new(velocity.x - currentvel.x, velocity.y - currentvel.y, velocity.z - currentvel.z)
self.object:add_velocity(vector.add(acceleration, player_velocity))
elseif distance < 0.8 then
mcl_experience.add_xp(collector, self._xp)
self.object:remove()
@ -75,28 +75,26 @@ local function xp_step(self, dtime)
return
else
self.collector = nil
self.enable_physics(self)
self:enable_physics()
end
end
-- Age orbs
self.age = self.age + dtime
if self.age > max_orb_age then
self.object:remove()
return
end
pos = self.object:get_pos()
local pos = self.object:get_pos()
if not pos then return end
if pos then
node = minetest.get_node_or_nil({
x = pos.x,
y = pos.y -0.25,
z = pos.z
})
else
return
end
-- Get the node directly below the XP orb
local node = minetest.get_node_or_nil({
x = pos.x,
y = pos.y - 0.25, -- Orb collision box is +/-0.2, so go a bit below that
z = pos.z
})
-- Remove nodes in 'ignore'
if node and node.name == "ignore" then
@ -109,18 +107,18 @@ local function xp_step(self, dtime)
end
-- Slide on slippery nodes
vel = self.object:get_velocity()
def = node and minetest.registered_nodes[node.name]
is_moving = (def and not def.walkable) or
local vel = self.object:get_velocity()
local def = node and minetest.registered_nodes[node.name]
local is_moving = (def and not def.walkable) or
vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
is_slippery = false
local is_slippery = false
if def and def.walkable then
slippery = minetest.get_item_group(node.name, "slippery")
local slippery = minetest.get_item_group(node.name, "slippery")
is_slippery = slippery ~= 0
if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then
-- Horizontal deceleration
slip_factor = 4.0 / (slippery + 4)
local slip_factor = 4.0 / (slippery + 4)
self.object:set_acceleration({
x = -vel.x * slip_factor,
y = 0,
@ -160,7 +158,6 @@ minetest.register_entity("mcl_experience:orb", {
initial_sprite_basepos = {x = 0, y = 0},
is_visible = true,
pointable = false,
static_save = false,
},
moving_state = true,
slippery_state = false,
@ -191,7 +188,7 @@ minetest.register_entity("mcl_experience:orb", {
-- This was a minetest bug for a while: https://github.com/minetest/minetest/issues/14420
local xp = tonumber(staticdata) or 0
self._xp = xp
size = xp_to_size(xp)
local size = xp_to_size(xp)
self.object:set_properties({
visual_size = {x = size, y = size},
@ -199,6 +196,9 @@ minetest.register_entity("mcl_experience:orb", {
})
self.object:set_sprite({x=1,y=math.random(1,14)}, 14, 0.05, false)
end,
get_staticdata = function(self)
return tostring(self._xp or 0)
end,
enable_physics = function(self)
if not self.physical_state then

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

@ -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

@ -113,8 +113,8 @@ mesecon.register_node("mcl_observers:observer", {
sounds = mcl_sounds.node_sound_stone_defaults(),
paramtype2 = "facedir",
on_rotate = false,
_mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5,
_mcl_blast_resistance = 3,
_mcl_hardness = 3,
}, {
description = S("Observer"),
_tt_help = S("Emits redstone pulse when block in front changes"),
@ -172,8 +172,8 @@ mesecon.register_node("mcl_observers:observer_down", {
sounds = mcl_sounds.node_sound_stone_defaults(),
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
on_rotate = false,
_mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5,
_mcl_blast_resistance = 3,
_mcl_hardness = 3,
drop = "mcl_observers:observer_off",
}, {
tiles = {
@ -224,8 +224,8 @@ mesecon.register_node("mcl_observers:observer_up", {
sounds = mcl_sounds.node_sound_stone_defaults(),
groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 },
on_rotate = false,
_mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5,
_mcl_blast_resistance = 3,
_mcl_hardness = 3,
drop = "mcl_observers:observer_off",
}, {
tiles = {

View File

@ -0,0 +1,4 @@
# textdomain: mcl_target
Target=Zielscheibe
A target is a block that provides a temporary redstone charge when hit by a projectile.=
Throw a projectile on the target to activate it.=

View File

@ -2,13 +2,19 @@
Use the button to push it.=Benutzen Sie den Knopf, um ihn zu drücken.
Stone Button=Steinknopf
A stone button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Ein Steinknopf ist eine Redstonekomponente aus Stein. Er kann gedrückt werden, um ein Redstonesignal zu senden. Im gedrückten Zustand versorgt er benachbarte Redstonekomponenten für 1 Sekunde mit Redstoneenergie.
Polished Blackstone Button=Polierter Schwarzsteinknopf
A polished blackstone button is a redstone component made out of polished blackstone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=
Oak Button=Eichenknopf
Acacia Button=Akazienknopf
Birch Button=Birkenknopf
Dark Oak Button=Schwarzeichenknopf
Spruce Button=Fichtenknopf
Jungle Button=Dschungelknopf
Mangrove Button=
Crimson Button=Karmesinholzknopf
Warped Button=Wirrholzknopf
A wooden button is a redstone component made out of wood which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1.5 seconds. Wooden buttons may also be pushed by arrows.=Ein Holzknopf ist eine Redstonekomponente aus Holz. Er kann gedrückt werden, um ein Redstonesignal zu senden. Im gedrückten Zustand versorgt er benachbarte Redstonekomponenten für 1,5 Sekunden mit Redstoneenergie. Holzknöpfe können auch von Pfeilen gedrückt werden.
Provides redstone power when pushed=Gibt Redstoneenergie, wenn gedrückt
Push duration: @1s=Druckdauer: @1s
Pushable by arrow=Drückbar von Pfeilen
A button is a redstone component which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.=

View File

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

View File

@ -218,7 +218,7 @@ minetest.register_node("mesecons_pistons:piston_normal_off", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = function(pos, node, user, mode)
if mode == screwdriver.ROTATE_AXIS then
minetest.set_node(pos, {name="mesecons_pistons:piston_up_normal_off"})
@ -255,7 +255,7 @@ minetest.register_node("mesecons_pistons:piston_normal_on", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = false,
})
@ -326,7 +326,7 @@ minetest.register_node("mesecons_pistons:piston_sticky_off", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = function(pos, node, user, mode)
if mode == screwdriver.ROTATE_AXIS then
minetest.set_node(pos, {name="mesecons_pistons:piston_up_sticky_off"})
@ -363,7 +363,7 @@ minetest.register_node("mesecons_pistons:piston_sticky_on", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = false,
})
@ -449,7 +449,7 @@ minetest.register_node("mesecons_pistons:piston_up_normal_off", {
footstep = mcl_sounds.node_sound_wood_defaults().footstep
}),
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = function(pos, node, user, mode)
if mode == screwdriver.ROTATE_AXIS then
minetest.set_node(pos, {name="mesecons_pistons:piston_down_normal_off"})
@ -487,7 +487,7 @@ minetest.register_node("mesecons_pistons:piston_up_normal_on", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = false,
})
@ -556,7 +556,7 @@ minetest.register_node("mesecons_pistons:piston_up_sticky_off", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = function(pos, node, user, mode)
if mode == screwdriver.ROTATE_AXIS then
minetest.set_node(pos, {name="mesecons_pistons:piston_down_sticky_off"})
@ -594,7 +594,7 @@ minetest.register_node("mesecons_pistons:piston_up_sticky_on", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = false,
})
@ -680,7 +680,7 @@ minetest.register_node("mesecons_pistons:piston_down_normal_off", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = function(pos, node, user, mode)
if mode == screwdriver.ROTATE_AXIS then
minetest.set_node(pos, {name="mesecons_pistons:piston_normal_off"})
@ -718,7 +718,7 @@ minetest.register_node("mesecons_pistons:piston_down_normal_on", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = false,
})
@ -782,7 +782,7 @@ minetest.register_node("mesecons_pistons:piston_down_sticky_off", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = function(pos, node, user, mode)
if mode == screwdriver.ROTATE_AXIS then
minetest.set_node(pos, {name="mesecons_pistons:piston_sticky_off"})
@ -820,7 +820,7 @@ minetest.register_node("mesecons_pistons:piston_down_sticky_on", {
},
},
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
_mcl_hardness = 1.5,
on_rotate = false,
})

View File

@ -6,11 +6,18 @@ Birch Pressure Plate=Birkendruckplatte
Dark Oak Pressure Plate=Schwarzeichendruckplatte
Spruce Pressure Plate=Fichtendruckplatte
Jungle Pressure Plate=Dschungeldruckplatte
Mangrove Pressure Plate=
Crimson Pressure Plate=Karmesinholzdruckplatte
Warped Pressure Plate=Wirrholzdruckplatte
A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Eine Holzdruckplatte ist eine Redstonekomponente, die ihre benachbarten Blöcke mit Redstoneenergie versorgt, solange sich ein beliebiges bewegliches Objekt (wie Gegenstände, Spieler und Mobs) auf ihm befindet.
Stone Pressure Plate=Steindruckplatte
Polished Blackstone Pressure Plate=Polierte Schwarzsteindruckplatte
A stone pressure plate is a redstone component which supplies its surrounding blocks with redstone power while a player or mob stands on top of it. It is not triggered by anything else.=Eine Steindruckplatte ist eine Redstonekomponente, die ihre benachbarten Blöcke mit Redstoneenergie versorgt, solange sich ein Spieler oder Mob auf ihm befindet. Sie wird von nichts anderem ausgelöst.
Stone Pressure Plate=Steindruckplatte
Provides redstone power when pushed=Gibt Redstoneenergie aus, wenn gedrückt
Pushable by players, mobs and objects=Drückbar von Spielern, Mobs und Objekten
Pushable by players, mobs and objects=
Pushable by players and mobs=Drückbar von Spielern und Mobs
Pushable by players=Drückbar von Spielern
Pushable by mobs=Drückbar von Mobs
Pushable by players=
Pushable by mobs=

View File

@ -28,6 +28,7 @@ local function get_anvil_formspec(set_name)
"field[4.125,0.75;7.25,1;name;;" .. F(set_name) .. "]",
"field_close_on_enter[name;false]",
"field_enter_after_edit[name;true]",
"set_focus[name;true]",
mcl_formspec.get_itemslot_bg_v4(1.625, 2.6, 1, 1),

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

@ -58,10 +58,25 @@ mcl_armor = {
},
player_view_range_factors = {},
trims = {
core_textures = {},
blacklisted = {["mcl_armor:elytra"]=true, ["mcl_armor:elytra_enchanted"]=true},
core_textures = {},
blacklisted = {["mcl_armor:elytra"]=true, ["mcl_armor:elytra_enchanted"]=true},
overlays = {"sentry","dune","coast","wild","tide","ward","vex","rib","snout","eye","spire","silence","wayfinder"},
colors = {["amethyst"]="#8246a5",["gold"]="#ce9627",["emerald"]="#1b9958",["copper"]="#c36447",["diamond"]="#5faed8",["iron"]="#938e88",["lapis"]="#1c306b",["netherite"]="#302a26",["quartz"]="#c9bcb9",["redstone"]="#af2c23"},
translations = {
sentry = S("sentry"),
dune = S("dune"),
coast = S("coast"),
wild = S("wild"),
tide = S("tide"),
ward = S("ward"),
vex = S("vex"),
rib = S("rib"),
snout = S("snout"),
eye = S("eye"),
spire = S("spire"),
silence = S("silence"),
wayfinder = S("wayfinder"),
},
colors = {["amethyst"]="#8246a5",["gold"]="#ce9627",["emerald"]="#1b9958",["copper"]="#c36447",["diamond"]="#5faed8",["iron"]="#938e88",["lapis"]="#1c306b",["netherite"]="#302a26",["quartz"]="#c9bcb9",["redstone"]="#af2c23"},
},
}

View File

@ -1,6 +1,21 @@
# textdomain: mcl_armor
Blast Protection=Explosionsschutz
Projectile Protection=Projektilschutz
Thorns=Dornen
This is a piece of equippable armor which reduces the amount of damage you receive.=Dies ist ein Teil einer tragbaren Rüstung, die die Menge an Schaden, den Sie erleiden, reduziert.
To equip it, put it on the corresponding armor slot in your inventory menu.=Um es zu tragen, legen Sie es in den passenden Rüstungsplatz in Ihrem Inventarmenü.
sentry=
dune=
coast=Küste
wild=
ward=Bezirk
vex=
rib=
snout=Schnauze
eye=Auge
spire=
silence=
wayfinder=Pfadfinder
Leather Cap=Lederkappe
Iron Helmet=Eisenhelm
Golden Helmet=Goldhelm
@ -21,6 +36,4 @@ Iron Boots=Eisenstiefel
Golden Boots=Goldstiefel
Diamond Boots=Diamantstiefel
Chain Boots=Kettenstiefel
Smithing Template '@1'=Schmiedevorlage '@1'
Smithing Template '@1'=Schmiedevorlage '@1'

View File

@ -1,6 +1,18 @@
# textdomain: mcl_armor
This is a piece of equippable armor which reduces the amount of damage you receive.=
To equip it, put it on the corresponding armor slot in your inventory menu.=
sentry=
dune=
coast=
wild=
ward=
vex=
rib=
snout=
eye=
spire=
silence=
wayfinder=
Leather Cap=
Iron Helmet=
Golden Helmet=

View File

@ -2,63 +2,63 @@ local mod_registername = minetest.get_current_modname() .. ":"
local S = minetest.get_translator(minetest.get_current_modname())
for _, template_name in pairs(mcl_armor.trims.overlays) do
minetest.register_craftitem(mod_registername .. template_name, {
description = S("Smithing Template '@1'", template_name),
inventory_image = template_name .. "_armor_trim_smithing_template.png",
})
minetest.register_craft({
output = mod_registername .. template_name .. " 2",
recipe = {
{"mcl_core:diamond",mod_registername .. template_name,"mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:cobble","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
})
minetest.register_craftitem(mod_registername .. template_name, {
description = S("Smithing Template '@1'", mcl_armor.trims.translations[template_name]),
inventory_image = template_name .. "_armor_trim_smithing_template.png",
})
minetest.register_craft({
output = mod_registername .. template_name .. " 2",
recipe = {
{"mcl_core:diamond",mod_registername .. template_name,"mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:cobble","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
})
end
--temp craft recipies, missing structures
minetest.register_craft({
output = mod_registername .. "eye",
recipe = {
{"mcl_core:diamond","mcl_end:ender_eye","mcl_core:diamond"},
{"mcl_core:diamond","mcl_end:ender_eye","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
output = mod_registername .. "eye",
recipe = {
{"mcl_core:diamond","mcl_end:ender_eye","mcl_core:diamond"},
{"mcl_core:diamond","mcl_end:ender_eye","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
})
minetest.register_craft({
output = mod_registername .. "ward",
recipe = {
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:apple_gold_enchanted","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
output = mod_registername .. "ward",
recipe = {
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:apple_gold_enchanted","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
})
minetest.register_craft({
output = mod_registername .. "snout",
recipe = {
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:goldblock","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
output = mod_registername .. "snout",
recipe = {
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:goldblock","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
})
minetest.register_craft({
output = mod_registername .. "silence",
recipe = {
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
{"mcl_core:diamond", mod_registername.."ward","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
output = mod_registername .. "silence",
recipe = {
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
{"mcl_core:diamond", mod_registername.."ward","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
})
minetest.register_craft({
output = mod_registername .. "wayfinder",
recipe = {
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
{"mcl_core:diamond", "mcl_maps:empty_map","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
})
output = mod_registername .. "wayfinder",
recipe = {
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
{"mcl_core:diamond", "mcl_maps:empty_map","mcl_core:diamond"},
{"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"},
}
})

View File

@ -62,7 +62,7 @@ local bamboo_def = {
inventory_image = "mcl_bamboo_bamboo_shoot.png",
wield_image = "mcl_bamboo_bamboo_shoot.png",
_mcl_blast_resistance = 1,
_mcl_hardness = 1.5,
_mcl_hardness = 1,
node_box = {
type = "fixed",
fixed = {
@ -277,7 +277,7 @@ local bamboo_block_def = {
sounds = node_sound,
paramtype2 = "facedir",
drops = "mcl_bamboo:bamboo_block",
_mcl_blast_resistance = 3,
_mcl_blast_resistance = 2,
_mcl_hardness = 2,
_mcl_stripped_variant = "mcl_bamboo:bamboo_block_stripped", -- this allows us to use the built in Axe's strip block.
on_place = mcl_util.rotate_axis,

View File

@ -208,7 +208,7 @@ if minetest.get_modpath("mcl_fences") then
wood_groups,
minetest.registered_nodes["mcl_core:wood"]._mcl_hardness,
minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance,
node_sound) -- note: about missing params.. will use defaults.
node_sound)
mcl_bamboo.mcl_log(dump(fence_id))
mcl_bamboo.mcl_log(dump(gate_id))

View File

@ -74,7 +74,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

View File

@ -0,0 +1,46 @@
# textdomain: mcl_bamboo
### bamboo_base.lua ###
Bamboo=Bambus
Bamboo Mosaic Plank=Bambusmosaikplanken
Bamboo Plank=Bambusplanken
Stripped Bamboo Block=
Bamboo Block=Bambusblock
### bamboo_items.lua ###
A bamboo button is a redstone component made out of bamboo which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=
A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=
Bamboo=Bambus
Bamboo Button=Bambusknopf
Bamboo Door=Bambustür
Bamboo Fence=Bambuszaun
Bamboo Fence Gate=Bambuszauntor
Bamboo Mosaic Slab=
Bamboo Mosaic Stair=Bambusmosaikstufe
Bamboo Plank Slab=Bambusplatte
Bamboo Plank Stair=Bambusplankenstufe
Bamboo Pressure Plate=Bambusdruckplatte
Bamboo Sign=Bambusschild
Bamboo Slab=Bambusplatte
Bamboo Stair=Bambusstufe
Bamboo Trapdoor=Bambusfalltür
Double Bamboo Mosaic Slab=
Double Bamboo Plank Slab=
Double Bamboo Slab=
Double Stripped Bamboo Slab=
Scaffolding=Bambusdruckplatte
Scaffolding (horizontal)=
Scaffolding block used to climb up or out across areas.=
Stripped Bamboo Slab=
Stripped Bamboo Stair=
To open or close the trapdoor, rightclick it or send a redstone signal to it.=
Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. They occupy the upper or lower part of a block, depending on how they have been placed. When open, they can be climbed like a ladder.=
Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=
To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=

View File

@ -1,5 +1,5 @@
# textdomain: mcl_barrels
Barrel=
Barrel=Fass
Barrels are containers which provide 27 inventory slots.=
To access its inventory, rightclick it. When broken, the items will drop out.=
27 inventory slots=
27 inventory slots=

View File

@ -265,7 +265,7 @@ minetest.register_node("mcl_beacons:beacon", {
remove_beacon_beam(pos)
end,
on_receive_fields = function(pos, formname, fields, sender)
if fields.swiftness or fields.regeneration or fields.leaping or fields.strenght
if fields.swiftness or fields.regeneration or fields.leaping or fields.strength
or fields.haste or fields.resistance or fields.absorption or fields.slow_falling then
local sender_name = sender:get_player_name()
local power_level = beacon_blockcheck(pos)
@ -329,7 +329,7 @@ minetest.register_node("mcl_beacons:beacon", {
end
minetest.get_meta(pos):set_string("effect","resistance")
successful = true
elseif fields.strenght and power_level >= 3 then
elseif fields.strength and power_level >= 3 then
if power_level == 4 then
minetest.get_meta(pos):set_int("effect_level",2)
else

View File

@ -210,7 +210,7 @@ function mcl_beds.register_bed(name, def)
stack_max = 1,
groups = {handy=1, bed = 1, dig_by_piston=1, bouncy=66, fall_damage_add_percent=-50, deco_block = 1, flammable=-1},
_mcl_hardness = 0.2,
_mcl_blast_resistance = 1,
_mcl_blast_resistance = 0.2,
sounds = def.sounds or default_sounds,
selection_box = common_box,
collision_box = common_box,
@ -286,10 +286,9 @@ function mcl_beds.register_bed(name, def)
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
-- FIXME: Should be bouncy=66, but this would be a higher bounciness than slime blocks!
groups = {handy = 1, flammable = -1, bed = 2, dig_by_piston=1, bouncy=33, fall_damage_add_percent=-50, not_in_creative_inventory = 1},
groups = {handy = 1, flammable = -1, bed = 2, dig_by_piston=1, bouncy=66, fall_damage_add_percent=-50, not_in_creative_inventory = 1},
_mcl_hardness = 0.2,
_mcl_blast_resistance = 1,
_mcl_blast_resistance = 0.2,
sounds = def.sounds or default_sounds,
drop = "",
selection_box = common_box,

View File

@ -15,7 +15,7 @@ Black Bed=Schwarzes Bett
Yellow Bed=Gelbes Bett
Green Bed=Grünes Bett
Magenta Bed=Magenta Bett
Orange Bed=Orange Bett
Orange Bed=Oranges Bett
Purple Bed=Violettes Bett
Brown Bed=Braunes Bett
Pink Bed=Rosa Bett
@ -47,4 +47,4 @@ You are missing the 'shout' privilege! It's required in order to talk in chat...
You exceeded the maximum number of messages per 10 seconds!=Sie haben die maximale Anzahl an Chatnachrichten pro 10 Sekunden überschritten!
Hey! Would you guys mind sleeping?=Hey, würdet Ihr bitte zu Bett gehen?
Sorry, but you have to wait @1 seconds until you may use this button again!=Sie müssen leider noch @1 Sekunden warten, bevor sie diesen Knopf erneut benutzen können!
@1/@2 players currently in bed.=@1/@2 Spieler aktuell im Bett.
@1/@2 players currently in bed.=@1/@2 Spieler aktuell im Bett.

View File

@ -0,0 +1,5 @@
# textdomain: mcl_beehives
Beehive=Bienenstock
Artificial bee nest.=
Bee Nest=
A naturally generating block that houses bees and a tasty treat...if you can get it.=

View File

@ -0,0 +1,2 @@
# textdomain: mcl_bells
Bell=Dorfglocke

View File

@ -33,8 +33,8 @@ minetest.register_node("mcl_blackstone:blackstone_gilded", {
{items = {"mcl_blackstone:blackstone_gilded"}, rarity = 1},
}
},
_mcl_blast_resistance = 2,
_mcl_hardness = 2,
_mcl_blast_resistance = 6,
_mcl_hardness = 1.5,
_mcl_silk_touch_drop = true,
_mcl_fortune_drop = {
discrete_uniform_distribution = true,
@ -196,7 +196,7 @@ end
mcl_stairs.register_stair_and_slab("blackstone", "mcl_blackstone:blackstone",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_top.png", "mcl_blackstone_top.png", "mcl_blackstone_side.png"},
S("Blackstone Stairs"),
S("Blackstone Stair"),
S("Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Blackstone Slab"), nil)
@ -204,7 +204,7 @@ mcl_stairs.register_stair_and_slab("blackstone", "mcl_blackstone:blackstone",
mcl_stairs.register_stair_and_slab("blackstone_polished", "mcl_blackstone:blackstone_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_polished.png"},
S("Polished Blackstone Stairs"),
S("Polished Blackstone Stair"),
S("Polished Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Polished Blackstone Slab"), nil)
@ -212,7 +212,7 @@ mcl_stairs.register_stair_and_slab("blackstone_polished", "mcl_blackstone:blacks
mcl_stairs.register_stair_and_slab("blackstone_chiseled_polished", "mcl_blackstone:blackstone_chiseled_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_chiseled_polished.png"},
S("Chiseled Polished Blackstone Stairs"),
S("Chiseled Polished Blackstone Stair"),
S("Chiseled Polished Blackstone Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Chiseled Polished Blackstone Slab"), nil)
@ -220,24 +220,13 @@ mcl_stairs.register_stair_and_slab("blackstone_chiseled_polished", "mcl_blacksto
mcl_stairs.register_stair_and_slab("blackstone_brick_polished", "mcl_blackstone:blackstone_brick_polished",
{cracky=3, pickaxey=1, material_stone=1},
{"mcl_blackstone_polished_bricks.png"},
S("Polished Blackstone Brick Stair Stairs"),
S("Polished Blackstone Brick Stair Slab"),
S("Polished Blackstone Brick Stair"),
S("Polished Blackstone Brick Slab"),
mcl_sounds.node_sound_stone_defaults(), 6, 2,
S("Double Polished Blackstone Brick Stair Slab"), nil)
S("Double Polished Blackstone Brick Slab"), nil)
--Wall
mcl_walls.register_wall(
"mcl_blackstone:wall",
S("Blackstone Wall"),
"mcl_blackstone:blackstone",
{
"mcl_blackstone_top.png",
"mcl_blackstone_top.png",
"mcl_blackstone_side.png"
},
"",
{ cracky=3, pickaxey=1, material_stone=1 }
)
mcl_walls.register_wall("mcl_blackstone:wall", S("Blackstone Wall"), "mcl_blackstone:blackstone")
--lavacooling

View File

@ -5,22 +5,28 @@ Chiseled Polished Blackstone=Gemeißelter polierter Schwarzstein
Polished Blackstone Bricks=Polierter Schwarzsteinziegel
Basalt=Basalt
Polished Basalt=Polierter Basalt
Blackstone Slab=Schwarzstein Stufe
Polished Blackstone Slab=Polierte Schwarzstein Stufe
Chiseled Polished Blackstone Slab=Gemeißelte Polierte Schwarzstein Stufe
Polished Blackstone Brick Slab=Polierte Schwarzsteinziegel Stufe
Blackstone Stairs=Schwarzstein Treppe
Polished Blackstone Stairs=Polierte Schwarzstein Treppe
Chiseled Polished Blackstone Stairs=Gemeißelte Polierte Schwarzstein Treppe
Polished Blackstone Brick Stairs=Polierte Schwarzsteinziegel Treppe
Quartz Bricks=Quartz Ziegel
Blackstone Slab=Schwarzsteinstufe
Polished Blackstone Slab=Polierte Schwarzsteinstufe
Chiseled Polished Blackstone Slab=Gemeißelte polierte Schwarzsteinstufe
Polished Blackstone Brick Slab=Polierte Schwarzsteinziegelstufe
Blackstone Stair=Schwarzsteintreppe
Polished Blackstone Stair=Polierte Schwarzsteintreppe
Chiseled Polished Blackstone Stair=Gemeißelte polierte Schwarzsteintreppe
Polished Blackstone Brick Stair=Polierte Schwarzsteinziegeltreppe
Quartz Bricks=Quarzziegel
Soul Torch=Seelenfakel
Torches are light sources which can be placed at the side or on the top of most blocks.=
Soul Lantern=Seelenlaterne
Soul Soil=Seelenerde
Eternal Soul Fire=Seelenfeuer
Gilded Blackstone=Vergoldeter Schwarzstein
Nether Gold Ore=Nethergolderz
Smooth Basalt=Glatter Basalt
Blackstone Wall=Schwarzsteinmauer
Double Blackstone Slab=
Polished Double Blackstone Slab=
Double Chiseled Polished Blackstone Slab=
Double Polished Blackstone Brick Slab=
@1 has been cooked crisp.=@1 wurde knusprig gebraten.
@1 felt the burn.=@1 ist völlig verbrannt.

View File

@ -0,0 +1,11 @@
# textdomain: mcl_blast_furnace
Inventory=
Blast Furnace=Schmelzofen
Smelts ores faster than furnace=
Use the recipe book to see what ores you can smelt, what you can use as fuel and how long it will burn.=
Use the blast furnace to open the furnace menu.=
Place a furnace fuel in the lower slot and the source material in the upper slot.=
The blast furnace will slowly use its fuel to smelt the item.=
The result will be placed into the output slot at the right side.=
Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace.=
Active Blast Furnace=

View File

@ -13,3 +13,6 @@ Ammunition=Munition
Damage from bow: 1-10=Schaden vom Bogen: 1-10
Damage from dispenser: 3=Schaden vom Werfer: 3
Launches arrows=Verschießt Pfeile
Crossbow=Armbrust
Crossbows are ranged weapons to shoot arrows at your foes.=
To use the crossbow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button to charge, release to load an arrow into the chamber, then to shoot press left mouse.=

View File

@ -340,6 +340,7 @@ local function on_put(pos, listname, index, stack, player)
local inv = meta:get_inventory()
local str = ""
local stack
local oldparam2 = minetest.get_node(pos).param2
for i=1, inv:get_size("stand") do
stack = inv:get_stack("stand", i)
if not stack:is_empty() then
@ -347,7 +348,7 @@ local function on_put(pos, listname, index, stack, player)
else str = str.."0"
end
end
minetest.swap_node(pos, {name = "mcl_brewing:stand_"..str})
minetest.swap_node(pos, {name = "mcl_brewing:stand_"..str, param2 = oldparam2})
minetest.get_node_timer(pos):start(1.0)
--some code here to enforce only potions getting placed on stands
end
@ -455,8 +456,8 @@ minetest.register_node("mcl_brewing:stand_000", {
}
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
on_destruct = on_destruct,
allow_metadata_inventory_take = allow_take,
allow_metadata_inventory_put = allow_put,
@ -536,8 +537,8 @@ minetest.register_node("mcl_brewing:stand_100", {
}
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
on_destruct = on_destruct,
allow_metadata_inventory_take = allow_take,
allow_metadata_inventory_put = allow_put,
@ -616,8 +617,8 @@ minetest.register_node("mcl_brewing:stand_010", {
}
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
on_destruct = on_destruct,
allow_metadata_inventory_take = allow_take,
allow_metadata_inventory_put = allow_put,
@ -691,8 +692,8 @@ minetest.register_node("mcl_brewing:stand_001", {
}
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
on_destruct = on_destruct,
allow_metadata_inventory_take = allow_take,
allow_metadata_inventory_put = allow_put,
@ -776,8 +777,8 @@ minetest.register_node("mcl_brewing:stand_110", {
}
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
on_destruct = on_destruct,
allow_metadata_inventory_take = allow_take,
allow_metadata_inventory_put = allow_put,
@ -857,8 +858,8 @@ minetest.register_node("mcl_brewing:stand_101", {
}
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
on_destruct = on_destruct,
allow_metadata_inventory_take = allow_take,
allow_metadata_inventory_put = allow_put,
@ -938,8 +939,8 @@ minetest.register_node("mcl_brewing:stand_011", {
}
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
on_destruct = on_destruct,
allow_metadata_inventory_take = allow_take,
allow_metadata_inventory_put = allow_put,
@ -1026,8 +1027,8 @@ minetest.register_node("mcl_brewing:stand_111", {
}
},
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_mcl_blast_resistance = 0.5,
_mcl_hardness = 0.5,
on_destruct = on_destruct,
allow_metadata_inventory_take = allow_take,
allow_metadata_inventory_put = allow_put,

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

@ -209,7 +209,7 @@ local function on_place_bucket_empty(itemstack, user, pointed_thing)
-- Call on_rightclick if the pointed node defines it
local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing)
if new_stack then
if new_stack and new_stack ~= itemstack then
return new_stack
end

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 ;)

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