Compare commits

...

240 Commits

Author SHA1 Message Date
Saku Laesvuori c5e1734c1c Make horse taming more similar to minecraft (#1249)
In minecraft horses are tamed by trying to ride them and they can also
be fed to speed up taming. This commit implements both of those
features and disables the old and broken taming system for horses.
2021-04-04 23:24:28 +03:00
kay27 f54f4ebcf9 Merge pull request 'Fix passive mobs despawning' (#1458) from slaesvuo/MineClone2:master into master
Reviewed-on: MineClone2/MineClone2#1458
2021-04-04 10:18:36 +00:00
Lizzy Fleckenstein 598692cf8c Add nil check to prevent crashes with mcl_throwing 2021-04-04 12:10:21 +02:00
Lizzy Fleckenstein ff538d51bd Merge branch 'master' of https://git.minetest.land/MineClone2/MineClone2 2021-04-04 12:01:59 +02:00
Lizzy Fleckenstein 49446bbb7b Make enderdragon spawn upon exit portal generation 2021-04-04 12:01:45 +02:00
Saku Laesvuori 4a085c9526 Fix passive mobs despawning
According to the wiki most passive mobs do not despawn. The ones that do
have already been explicity marked as despawning.

<https://minecraft.fandom.com/wiki/Spawn#Despawning>
<https://minecraft.fandom.com/wiki/Mob#Despawning>
2021-04-04 09:15:25 +03:00
epCode ac87e0604e make ghast firing more MC-like 2021-04-03 18:39:20 -07:00
jordan4ibanez f8229def5e Merge pull request 'Fix locationless playing when picking up items' (#1457) from jordan4ibanez/MineClone2-PopSounds:master into master
Reviewed-on: MineClone2/MineClone2#1457
2021-04-04 01:10:19 +00:00
jordan4ibanez 90fd65ac66 Fix locationless playing 2021-04-03 21:09:43 -04:00
epCode 40b07e466b make ghast fireballs deflectible 2021-04-03 18:07:51 -07:00
jordan4ibanez 0b0a180343 Merge pull request 'Fix local name memory leak' (#1456) from jordan4ibanez/MineClone2-PopSounds:master into master
Reviewed-on: MineClone2/MineClone2#1456
2021-04-04 01:05:56 +00:00
jordan4ibanez 1b511936f5 Fix local name memory leak 2021-04-03 21:05:31 -04:00
jordan4ibanez 441ce5522a Merge pull request 'Adjust the volume even more to perfectly match the gameplay' (#1455) from jordan4ibanez/MineClone2-PopSounds:master into master
Reviewed-on: MineClone2/MineClone2#1455
2021-04-04 00:56:17 +00:00
jordan4ibanez a807ee6372 Adjust the volume even more to perfectly match the gameplay 2021-04-03 20:55:46 -04:00
jordan4ibanez f1863baedc Merge pull request 'Adjust volume and pitch of item collection sound' (#1454) from jordan4ibanez/MineClone2-PopSounds:master into master
Reviewed-on: MineClone2/MineClone2#1454
2021-04-04 00:54:33 +00:00
jordan4ibanez 0641f09915 Adjust volume of item collection sound 2021-04-03 20:53:34 -04:00
jordan4ibanez bb6cce06e5 Merge pull request 'Add sound buffer and different item collection sound' (#1453) from jordan4ibanez/MineClone2-PopSounds:master into master
Reviewed-on: MineClone2/MineClone2#1453
2021-04-04 00:39:52 +00:00
jordan4ibanez c572db92aa Add sound buffer and different item collection sound 2021-04-03 20:39:08 -04:00
jordan4ibanez b14bc21829 Minor update to home directory warning in minetest.conf 2021-04-03 05:26:08 +00:00
jordan4ibanez 269ed6b3eb Merge pull request 'Update tick rate to 0.05 ticks per second (20 tps)' (#1446) from jordan4ibanez/MineClone2-TickRateAdjustment:master into master
Reviewed-on: MineClone2/MineClone2#1446
2021-04-03 05:22:50 +00:00
jordan4ibanez da3d5025a8 Update tick rate to 0.05 ticks per second (20 tps) 2021-04-03 01:22:13 -04:00
jordan4ibanez 43c47bbe0f Merge pull request 'Revert to previous style of interpolated move_to with tweaks' (#1445) from jordan4ibanez/MineClone2-ManualItemPickupInterpolation:master into master
Reviewed-on: MineClone2/MineClone2#1445
2021-04-03 02:02:58 +00:00
jordan4ibanez 844db8aa7b Revert to previous style of interpolated move_to with tweaks 2021-04-02 22:02:19 -04:00
jordan4ibanez 22cbfa32de Merge pull request 'Adjust the item collection magnet even more' (#1444) from jordan4ibanez/MineClone2-ManualItemPickupInterpolation:master into master
Reviewed-on: MineClone2/MineClone2#1444
2021-04-03 01:58:08 +00:00
jordan4ibanez 0840ad98a2 Adjust the item collection magnet even more 2021-04-02 21:57:38 -04:00
jordan4ibanez ea54936d28 Merge pull request 'Smoothen out item collection to accommodate for move_to interpolation issues' (#1443) from jordan4ibanez/MineClone2-ManualItemPickupInterpolation:master into master
Reviewed-on: MineClone2/MineClone2#1443
2021-04-03 01:52:18 +00:00
jordan4ibanez 1cbd3a998d Use manual move_to to account for move_to interpolation issues 2021-04-02 21:50:47 -04:00
jordan4ibanez 61e812e40a Add in manual interpolation into the item magnet 2021-04-02 21:40:04 -04:00
jordan4ibanez b83b4c55fa Merge pull request 'More fixes to item collection on laggy servers' (#1442) from jordan4ibanez/MineClone2-FixA:master into master
Reviewed-on: MineClone2/MineClone2#1442
2021-04-03 00:43:42 +00:00
jordan4ibanez 18d7be4a4f More fixes to item collection on laggy servers 2021-04-03 00:42:20 -04:00
AFCMS b68c4b07c1 tweak hudbars 2021-04-02 17:20:19 +02:00
AFCMS ca01b3641b make endermen not teleport everytime when hitted 2021-04-02 15:04:21 +02:00
AFCMS 0db47dbf02 Merge branch 'remove-alpha-field' 2021-04-02 14:43:08 +02:00
AFCMS 59d687c579 fix API.md 2021-04-02 14:30:46 +02:00
AFCMS c457c4ce3c fix undeacleared vars in mcl_fishing 2021-04-02 14:28:43 +02:00
AFCMS ead33e3520 fix undeacleared vars in mcl_throwing 2021-04-02 14:27:35 +02:00
AFCMS e20e0fab71 remobe backward compatibility for portals 2021-04-02 14:16:14 +02:00
AFCMS 695ad9120b remove backward compatibility for water 2021-04-02 14:12:44 +02:00
AFCMS 0da8339352 Merge pull request 'Fix #1391' (#1438) from NO11/MineClone2:master into master
Reviewed-on: MineClone2/MineClone2#1438
2021-04-02 11:11:45 +00:00
NO11 39aaf0f21f Fix #1391 2021-04-02 11:09:45 +00:00
AFCMS c0fcbffd70 Merge pull request 'doc-refactoring part 1' (#1437) from doc-refactoring into master
Reviewed-on: MineClone2/MineClone2#1437
2021-04-02 08:31:09 +00:00
AFCMS cbc1052f6b Merge branch 'master' into doc-refactoring 2021-04-02 10:27:22 +02:00
jordan4ibanez 5f361cde29 Merge pull request 'Remove debug info from item magnet' (#1436) from jordan4ibanez/MineClone2-whoopsies:master into master
Reviewed-on: MineClone2/MineClone2#1436
2021-04-02 05:54:33 +00:00
jordan4ibanez 1e3676c391 Remove debug info from item magnet 2021-04-02 05:38:53 +00:00
kay27 fd51910b89 Merge pull request 'Fix item drop on laggy servers' (#1435) from jordan4ibanez/MineClone2-FixItemDrop:master into master
Reviewed-on: MineClone2/MineClone2#1435
2021-04-02 05:11:06 +00:00
jordan4ibanez 2f272b3dff Fix item drop on laggy servers 2021-04-01 23:48:00 -04:00
epCode 0dbe66f3b4 make mob drops similar to MC 2021-04-01 14:12:07 -07:00
AFCMS 15803fddc2 Merge branch 'master' into doc-refactoring 2021-03-31 20:33:37 +02:00
epCode 5356e97b77 fix copy/pasted arrow texture to pixel-perfection 2021-03-31 11:23:59 -07:00
AFCMS 626990adeb Merge branch 'master' into doc-refactoring 2021-03-31 16:15:34 +02:00
iliekprogrammar c44054b51c Merge pull request 'Implement MC-like kelps in terms of growing and destroying' (#1354) from iliekprogrammar/MineClone2:kelp into master
Reviewed-on: MineClone2/MineClone2#1354
2021-03-31 11:57:59 +00:00
iliekprogrammar 9885f36c62 Fix missing age metadata and timer initialization in on_place. 2021-03-31 19:27:57 +08:00
iliekprogrammar bfff643ff4 Allow age to override during initialization. 2021-03-31 17:38:38 +08:00
iliekprogrammar ccea673dcc Fix updating age metadata. Remove kelp.lock_drop. 2021-03-31 17:31:28 +08:00
iliekprogrammar 08e280d9b4 Comment out debug stuff 2021-03-31 14:17:50 +08:00
iliekprogrammar 52c788f197 Merge branch 'master' into kelp 2021-03-31 13:59:27 +08:00
iliekprogrammar 089d6aa5c8 Add dug sounds to kelp when unsubmerged 2021-03-31 13:55:07 +08:00
iliekprogrammar 9518086b6b Kelp store age metadata by bulk on a queue, improve API, etc.
Highlights:
- Implement storing age metadata by bulk on a queue, with maximum interval and queue length.
- "Flexible" initial growth probability. Will provide helper APIs.
- Fix various bugs with unsubmerged kelp detection, submerged tip detection, age metadata.
- Various optimizations.
2021-03-31 13:41:52 +08:00
AFCMS 0740854b5d Merge branch 'master' into doc-refactoring 2021-03-30 22:28:48 +02:00
epCode 86b63c8bc4 Make player model easier to use 2021-03-30 13:26:46 -07:00
epCode 38e4e7293a fix female player anim XD 2021-03-30 10:29:46 -07:00
epCode 97424f7d0a Fix #1414 2021-03-30 10:24:39 -07:00
epCode a14959ac70 add player death animation and particles 2021-03-30 09:53:55 -07:00
AFCMS 3b8916ef65 Merge branch 'master' of ssh://git.minetest.land:29418/MineClone2/MineClone2 2021-03-30 15:48:18 +02:00
AFCMS a040355dce Revert "Revert "Revert "improve wieldview API (!)"""
This reverts commit d4e0d4d1c1.
2021-03-30 01:00:51 +02:00
AFCMS d4e0d4d1c1 Revert "Revert "improve wieldview API (!)""
This reverts commit 613779a851.
2021-03-30 01:00:17 +02:00
AFCMS c35dab1d08 try to fix crash 2021-03-30 00:59:52 +02:00
AFCMS 613779a851 Revert "improve wieldview API (!)"
This reverts commit 600e8bede2.
2021-03-30 00:59:00 +02:00
AFCMS 59c13b6df8 Revert "Revert "remove hard depend to mcl_wip in mcl_minecarts""
This reverts commit 857a0c5565.
2021-03-30 00:58:45 +02:00
AFCMS 857a0c5565 Revert "remove hard depend to mcl_wip in mcl_minecarts"
This reverts commit 369c8b9b8a.
2021-03-30 00:58:36 +02:00
AFCMS 41a8cd0e15 Revert "Revert "remove hard depend to mcl_wip in mcl_minecarts""
This reverts commit 7a5c2d617b.
2021-03-30 00:58:02 +02:00
AFCMS 7a5c2d617b Revert "remove hard depend to mcl_wip in mcl_minecarts"
This reverts commit 369c8b9b8a.
2021-03-30 00:57:46 +02:00
AFCMS 369c8b9b8a remove hard depend to mcl_wip in mcl_minecarts 2021-03-30 00:54:58 +02:00
AFCMS 7ec7012572 fix indentation 2021-03-30 00:50:58 +02:00
AFCMS c70ea7c843 fix crash :-/
I am stupid
2021-03-30 00:49:54 +02:00
AFCMS f60941003d fix the stupidiest typo ever :-/ 2021-03-30 00:49:05 +02:00
AFCMS 3a514ecdad remove duplicated code 2021-03-30 00:44:38 +02:00
AFCMS 600e8bede2 improve wieldview API (!)
to support transform registration without groups
this will make detaching screwdriver from mcl more easy
2021-03-30 00:35:29 +02:00
AFCMS 84819bf9f5 MAKE EVERY SINGLE MOD USE PROPER COLORS!!! 2021-03-30 00:01:29 +02:00
AFCMS f8a627915e use proper colors in mcl_books 2021-03-29 22:57:05 +02:00
AFCMS a2fcd28a3d use proper colors in mcl_skins 2021-03-29 22:23:00 +02:00
AFCMS f51deb0737 use propers colors in mcl_jukebox 2021-03-29 22:21:14 +02:00
epCode 5a7d128861 Add wither functions from MC 2021-03-29 11:29:39 -07:00
Elias Fleckenstein 68d49a43b2 Merge pull request 'Prevent beds from appearing and disappearing if they cannot be placed, fix #1419' (#1423) from ArTee3/MineClone2:fix-bed-placement into master
Reviewed-on: MineClone2/MineClone2#1423
2021-03-29 16:23:45 +00:00
ArTee3 1b9737b431 Prevent beds from appearing and disappearing if they cannot be placed, fix #1419 2021-03-29 18:19:46 +02:00
iliekprogrammar ecdbc30b63 Overhaul kelp interactions.
Highlights:
- Added locking system to drops. Will be removed after testing.
- Expose more variables and functions. Will be finalized soon.
- Implement MC-like age and natural growth mechanics.
- Implement correct piston interactions with kelp and its surface.
- Implement correct falling node interactions for its surface.
- ABMs are now nonfunction. Will be fixed.
- Various optimizations and fixes.
2021-03-29 14:09:09 +08:00
kay27 d1a0299b92 [mcl_dungeons] Remove empty code section, add debug info 2021-03-29 03:34:41 +04:00
kay27 80d845adb6 [mcl_mapgen_core] Fix Nether generation chain reaction 2021-03-29 03:18:17 +04:00
kay27 2e3a5efaf9 [mcl_spawn] Ignore 'ignore' nodes when checking the point, fix MineClone2/MineClone2#1230 2021-03-29 03:08:21 +04:00
kay27 b587b1f2a5 [mcl_spawn] Cleanup 2021-03-29 02:48:45 +04:00
kay27 1818fcf592 [mcl_mapgen_core] Remove water from End, fix MineClone2/MineClone2#1394 2021-03-29 02:43:08 +04:00
kay27 bbd52043f1 [mcl_portals] Make '/spawnstruct nether_portal' chat command work in obsidian nodes (immediate destruction triggered) 2021-03-29 02:17:32 +04:00
kay27 05260d03d5 [mcl_portals] Fix crash on access empty index trying to find portal after its destruction 2021-03-29 01:33:01 +04:00
kay27 cb2aae5a55 [mcl_mapgen_core] Redesign, mostly to remove water from End and restore static lvm_buffer to speed it up 2021-03-28 22:57:11 +04:00
AFCMS d07cf64d11 Merge pull request 'mcl_death_drop refactoring' (#1415) from mcl-death-drop-refactoring into master
Reviewed-on: MineClone2/MineClone2#1415
2021-03-28 18:13:57 +00:00
AFCMS 5a4355b859 Merge branch 'master' of https://git.minetest.land/MineClone2/MineClone2 2021-03-28 19:44:43 +02:00
kay27 628ca226a6 [mcl_portals] Additionally index source Nether portals from 0.71 and earlier before teleporting, to make possible returning through them 2021-03-28 20:36:35 +04:00
iliekprogrammar 24da94ec3b Disable ABMs in favor of nodetimers to check if kelp is unsubmerged. 2021-03-28 20:29:29 +08:00
iliekprogrammar e76a0ba6e8 Added kelp API and additional refactorings.
WIP: register nodetimers for kelp
2021-03-28 14:51:21 +08:00
AFCMS c7389dc0a4 add basic API to mcl_item_entity 2021-03-28 08:13:24 +02:00
AFCMS 890a569b13 add API documentation to mcl_worlds 2021-03-28 07:40:36 +02:00
kay27 54e7529754 [mcl_achievements] Add mcl:stoneAge, mcl:hotStuff, mcl:obsidian 2021-03-28 04:32:57 +04:00
AFCMS cdb67d96a6 add API documentation to mcl_explosions 2021-03-28 01:00:18 +01:00
AFCMS 6f9c1856b8 add API documentation to mcl_colors (!) 2021-03-28 00:48:24 +01:00
AFCMS e56d9d2ab8 add API documentation to controls 2021-03-28 00:44:36 +01:00
AFCMS 52939ff6a4 add API documentation to flowlib (part 5) 2021-03-28 00:32:52 +01:00
AFCMS 39ac3f208d add API documentation to flowlib (part 4) 2021-03-28 00:25:54 +01:00
AFCMS 2a5dcd1634 add API documentation to flowlib (part 3) 2021-03-28 00:23:57 +01:00
AFCMS 19db2a479f add API documentation to flowlib (part 2) 2021-03-28 00:18:19 +01:00
AFCMS fb50b256ed add API documentation to flowlib (part 1) 2021-03-28 00:12:41 +01:00
AFCMS ce123d4676 add API documentation to mcl_autogroup 2021-03-28 00:02:35 +01:00
AFCMS 57ce5143b9 Clarify API documentation 2021-03-27 23:39:22 +01:00
AFCMS 3ba7a40251 Add API documentation 2021-03-27 23:07:46 +01:00
AFCMS 6a6b5970b3 fix API 2021-03-27 20:23:51 +01:00
AFCMS 30e50a64ef basic API (WIP) 2021-03-27 20:12:48 +01:00
AFCMS cb294a5cad Add documentation to mcl_wip (pretty useless...) 2021-03-27 15:27:34 +01:00
AFCMS 9bb5e748b9 Add documentation to mcl_crafting_table API 2021-03-27 15:20:01 +01:00
AFCMS 61c9d065fb Fix  #1400 2021-03-27 07:19:35 +01:00
AFCMS e2fd0823b9 Fix #1398 2021-03-27 07:10:50 +01:00
AFCMS 826d60e16e Merge pull request 'Refactor mcl_throwing API' (#1396) from api-throwing into master
Reviewed-on: MineClone2/MineClone2#1396
2021-03-27 06:00:02 +00:00
AFCMS e2adead700 use proper colors 2021-03-26 22:50:37 +01:00
AFCMS e11941c107 Add API documentation for mcl_throwing 2021-03-26 22:43:18 +01:00
AFCMS e3c99c5be2 add basic API to mcl_throwing
remove hard depends to mcl_fishing
2021-03-26 22:31:15 +01:00
AFCMS 202e30a782 Add API to mcl_tmp_message 2021-03-26 21:37:10 +01:00
AFCMS 50bdf03189 Merge pull request 'anvil damage mechanism' (#1387) from anvil-entity-damage into master
Reviewed-on: MineClone2/MineClone2#1387
2021-03-26 17:36:17 +00:00
AFCMS 8c002671c0 make helmet protect from falling anvils 2021-03-26 18:24:08 +01:00
Lizzy Fleckenstein 0372057fe3 Merge branch 'master' of https://git.minetest.land/MineClone2/MineClone2 2021-03-26 17:51:16 +01:00
Lizzy Fleckenstein 6f8d0d4de0 Fix #1375 2021-03-26 17:51:13 +01:00
AFCMS 9c8ec7d4ec Merge branch 'master' into anvil-entity-damage 2021-03-26 17:40:55 +01:00
AFCMS 041300cde4 remove unuseful code 2021-03-26 17:39:25 +01:00
AFCMS 88fc515cff make mobs take damage of falling anvils 2021-03-26 17:38:25 +01:00
AFCMS 01eba30058 Fix #1234 2021-03-26 14:32:08 +01:00
AFCMS 35b2bd72f8 Merge pull request 'Add a server setting to disable command blocks usage' (#1381) from command-block-setting into master
Reviewed-on: MineClone2/MineClone2#1381
2021-03-26 10:54:53 +00:00
AFCMS 41768e95a1 fix 2021-03-26 11:50:14 +01:00
AFCMS c0308c7c08 fix weird death message (#1378) 2021-03-26 11:49:41 +01:00
AFCMS 50c35ff5e8 Merge branch 'master' into command-block-setting 2021-03-26 10:06:18 +00:00
AFCMS 53d7134437 remove unuseful spamming messages 2021-03-26 10:00:48 +01:00
AFCMS 78bad87a72 fix transation 2021-03-26 09:59:58 +01:00
AFCMS 0e5bbd6d3d fix msg to be mc like
https://www.digminecraft.com/game_commands/enable_command_blocks.php
2021-03-26 09:57:28 +01:00
kay27 25f6a9ee23 [mcl_core] Set obsidian.is_ground_content to false, see MineClone2/MineClone2#1372 2021-03-26 09:29:05 +04:00
AFCMS 8258dae1b8 setting working 2021-03-25 22:13:37 +01:00
AFCMS e4a6244fdd add basic setting 2021-03-25 22:07:38 +01:00
AFCMS b9301f12ce Update mod.conf 2021-03-25 21:59:21 +01:00
AFCMS 86a18802dc use proper colors 2021-03-25 21:57:07 +01:00
Lizzy Fleckenstein 97991d138c Revert "Do a secre thing even more secret then the secret thing of secret"
This reverts commit 630e7e8acb.
2021-03-25 17:34:03 +01:00
Code-Sploit 630e7e8acb Do a secre thing even more secret then the secret thing of secret 2021-03-25 16:20:02 +00:00
Lizzy Fleckenstein d555fce8bc Bruh. kay27 has 20 times more commits than you.
This reverts commit 322578df6a.
2021-03-25 17:29:15 +01:00
Code-Sploit 322578df6a Something even more secret! 2021-03-25 16:03:54 +00:00
epCode dbc6dd8cb3 Add villager sounds 2021-03-25 08:52:32 -07:00
Lizzy Fleckenstein 46c6328432 Something secret :P 2021-03-25 09:24:38 +01:00
Lizzy Fleckenstein 43a60e0c57 Fix #1357 2021-03-24 09:00:31 +01:00
Lizzy Fleckenstein a47eda44e9 Slimes can burn 2021-03-24 08:54:23 +01:00
Lizzy Fleckenstein fe937665f9 Fix #1336 2021-03-24 08:27:31 +01:00
kay27 6addb7db18 Merge pull request 'Move item renaming to tt to fix enchanted named items' (#1364) from BlueBlancmanche/MineClone2:anvil-fix into master
Reviewed-on: MineClone2/MineClone2#1364
2021-03-24 05:09:54 +00:00
Elias Åström 0d7c2c4988 Fix #1358 for real 2021-03-23 12:02:00 +01:00
kay27 3e58e989a1 [mcl_portals] Support Nether portals from 0.71 and earlier 2021-03-23 03:19:17 +04:00
kay27 06280e3bba [mcl_portals] Generate target map chunks on portal creation 2021-03-23 03:17:23 +04:00
Blue Blancmange 44c4999b37 Move item renaming to tt. This allows additional information such as enchantments to be displayed on named items 2021-03-22 23:02:11 +00:00
epCode 647a53c354 Merge pull request 'Fix player speed on soul sand, MineClone2/MineClone2#1356' (#1363) from ArTee3/MineClone2:fix-player-speed-on-soulsand into master
Reviewed-on: MineClone2/MineClone2#1363
2021-03-22 21:53:47 +00:00
ArTee3 910c9083e5 Fix player speed on soul sand, MineClone2/MineClone2#1356 2021-03-22 21:55:57 +01:00
kay27 66a64439c6 [mcl_weather] Fix crash on saving uninitialized data, MineClone2/MineClone2#1361 2021-03-22 17:31:24 +04:00
kay27 7fe3217cd0 [mcl_portals] Remove debug messages 2021-03-22 11:32:28 +04:00
epCode 01df02667b Make setting for swim on lava 2021-03-21 17:53:57 -07:00
kay27 03feb36558 Improve Nether Portals (#1315) (as a squash)
Remove Nether portal caches, MineClone2/MineClone2#1210

Store all exits from Nether portals in quick-access table

Implement proper Nether portal search, using the table, MineClone2/MineClone2#1055

Store Nether portal exits table in mod storage

Remove exits from table on Nether portal destruction

Align destination area to [map chunks 5x5x5](https://git.minetest.land/MineClone2/MineClone2/wiki/World-structure%3A-positions%2C-boundaries%2C-blocks%2C-chunks%2C-dimensions%2C-barriers-and-the-void) to avoid lots of ```emerge_area()``` calls

Support Nether roof, MineClone2/MineClone2#1267

Implement better suitable place search, MineClone2/MineClone2#1126

Implement object queue not to trigger the same search again

Avoid lava lakes, MineClone2/MineClone2#1126

Add ```/spawnstruct nether_portal``` chat command
Co-Authored-By: kay27 <kay27@noreply.git.minetest.land>
Co-Committed-By: kay27 <kay27@noreply.git.minetest.land>
2021-03-21 23:14:33 +00:00
kay27 1f925b6c84 Merge pull request 'Give xp if items are moved between furnace slots, unlock smelting achievements if furnace is inactive' (#1360) from ArTee3/MineClone2:furnace-fixes into master
Reviewed-on: MineClone2/MineClone2#1360
2021-03-21 22:53:59 +00:00
Lizzy Fleckenstein 9a4d26c2ae Fix all invalid usages of math.random in mcl_bows 2021-03-21 19:52:27 +01:00
Lizzy Fleckenstein 2d1ac1c7fa Properly fix arrows crashing the server 2021-03-21 19:47:13 +01:00
Lizzy Fleckenstein f0c2a0a1e9 Fix arrows crashing the server 2021-03-21 19:45:33 +01:00
ArTee3 1fa2bd3477 Give xp if items are moved between furnace slots, unlock smelting achievements if furnace is inactive 2021-03-21 17:01:28 +01:00
Elias Åström 7f56e5efa4 Add hoey digging group to hand 2021-03-21 12:43:47 +01:00
Elias Åström c1e295de5f Make hoe dig some blocks faster
- Sponges
- Hay and kelp blocks
- Nether wart
- Leaves
2021-03-21 12:39:14 +01:00
Elias Åström dac3c21628 Do not register "creative_breakable" as a diggroup 2021-03-21 12:26:34 +01:00
Elias Åström b0c7941b3a Fix #1358 2021-03-21 12:18:24 +01:00
iliekprogrammar ca635b69be Various fixes. 2021-03-21 14:06:54 +08:00
iliekprogrammar ebf9f8c918 placing kelp now creates water sources, small refactoring. 2021-03-21 12:16:56 +08:00
Elias Åström 0996a83ba0 Assert that both parts of mcl_autogroup exist 2021-03-20 19:32:04 +01:00
Elias Åström 1621c23308 Rename "tool_multiplier" to "speed" for tools 2021-03-20 19:25:47 +01:00
iliekprogrammar 23f69dfd1e Core implementation of MC-like kelp drops.
Highlights:
* Kelp should no longer be able to survive without water
(by decreasing its height)
* When kelp is destroyed, each segment now drop a single kelp similar to MC.
* Significantly refactor how kelp grows and dig. Possible optimizations might be
included.
2021-03-21 02:22:25 +08:00
Elias Åström 1873080046 Remove unnecessary code in mcl_item_entity 2021-03-20 14:21:50 +01:00
Elias Åström 46541a4adc Merge branch 'master' of https://git.minetest.land/MineClone2/MineClone2 2021-03-20 11:02:42 +01:00
Elias Åström 10154d5778 Fix #1348 2021-03-20 11:02:16 +01:00
epCode c877d6e922 Merge pull request 'Slightly lift your right arm when holding an item.' (#1345) from iliekprogrammar/MineClone2:hand into master
Reviewed-on: MineClone2/MineClone2#1345
2021-03-20 02:29:11 +00:00
iliekprogrammar 12745bd450 Remove debug information... again :/ 2021-03-20 10:13:48 +08:00
iliekprogrammar 03be45b983 Fix indentation from iliekprogrammar's previous PRs 2021-03-20 09:17:43 +08:00
iliekprogrammar 34dbddb40a Move holding code into mcl_playerplus 2021-03-20 08:42:48 +08:00
kay27 b871433c47 Merge pull request 'Fix #1346' (#1347) from kneekoo/MineClone2:master into master
Reviewed-on: MineClone2/MineClone2#1347
2021-03-19 17:58:03 +00:00
Nicu a40e1c4737 Reduce the size of the pumpkin texture
2732 -> 303 bytes

* We need smaller file sizes for better game startup time, especially for multiplayer and mobile gaming.
2021-03-19 17:41:37 +00:00
Nicu df8fdda2c5 Fix #1346
Fixes crash trying to place cocoa
2021-03-19 17:25:40 +00:00
iliekprogrammar 249b5cfd1e Remove debug information 2021-03-20 00:11:12 +08:00
iliekprogrammar f5f85a2148 Slightly lift your right arm when holding an item. 2021-03-19 23:28:33 +08:00
Lizzy Fleckenstein d168bfa791 Fix pumpking breaking armor display 2021-03-19 14:47:52 +01:00
Lizzy Fleckenstein c20bd768ec Revert "Fix #1277". The commit caused each enchanted armor piece to overlay an additional violet layer over all previous armor layers. A better fix needs to be found.
This reverts commit b82da05590.
2021-03-19 14:36:48 +01:00
Lizzy Fleckenstein 67cedf1308 Fix villager visual_size (Closes #1338) 2021-03-19 14:32:02 +01:00
Lizzy Fleckenstein 9391628813 Fix wielded nodes being upside down 2021-03-19 12:41:03 +01:00
Lizzy Fleckenstein 327bb68927 Fix crystal on_place handler 2021-03-19 12:03:32 +01:00
Lizzy Fleckenstein 906aa3b434 Remove performance settings to see whether it helps 2021-03-19 11:46:35 +01:00
Lizzy Fleckenstein ecd27a4cdb Initialize burning HUD with proper texture 2021-03-19 11:41:29 +01:00
Lizzy Fleckenstein 55df2a57f4 Fix #1336 2021-03-19 11:40:46 +01:00
Lizzy Fleckenstein 4ff987ccc5 Remove burning sound for objects 2021-03-19 11:39:04 +01:00
Lizzy Fleckenstein f3c37f49b9 Only extinguish flame arrow on removal 2021-03-19 11:37:12 +01:00
Lizzy Fleckenstein f3580efced Separate Head / Body rotation (Implement #1189) 2021-03-19 11:32:17 +01:00
Lizzy Fleckenstein 4a53ba67ab Wielditem rotation tweak 2021-03-19 09:37:24 +01:00
epCode d02fc0c83d Re-Enable Skeleton horse spawn egg 2021-03-18 23:12:21 +00:00
epCode e474ce6397 Merge pull request 'Add copyright-safe skeleton horse texture' (#1337) from ZedekThePD/MineClone2:master into master
Reviewed-on: MineClone2/MineClone2#1337
2021-03-18 23:09:47 +00:00
ZeDique la Ruleta b71566aad6 Updated horse texture 2021-03-18 19:08:27 -04:00
epCode 4fbb95bed3 Merge pull request 'Fix rotation for all wielded items' (#1335) from kneekoo/MineClone2:master into master
Reviewed-on: MineClone2/MineClone2#1335
2021-03-18 23:05:57 +00:00
ZeDique la Ruleta 2571c6124b Added copyright-safe skeleton horse texture
- Added proper skeleton horse texture edited from the default Pixel Perfection horse, similar to MC but not the same
2021-03-18 18:51:19 -04:00
Nicu e61f1e38f2 Rotation fix for all wielded items
These were probably needed in an older version of the game/engine, but most items don't need changes for correct wielding. The only tweak was needed for the screwdriver.
2021-03-18 19:31:51 +00:00
AFCMS a482a18a67 Merge branch 'master' of https://git.minetest.land/MineClone2/MineClone2 2021-03-18 18:53:06 +01:00
Elias Åström ed30fa0868 Move data from deprecated files to mod.conf
Move data from deprecated files (depends.txt and description.txt) into
fields in mod.conf for all mods.

This was done with a shell script :)
2021-03-18 17:37:12 +01:00
Elias Åström 8d473a42ca Merge branch 'master' of https://git.minetest.land/MineClone2/MineClone2 2021-03-18 14:04:02 +01:00
Elias Åström 0f2c487dca Remove _mcl_autogroup depends on mcl_autogroup
It looks like the dependency might cause problems with the mod loading
order and lead to situations were _mcl_autogroup is not loaded after all
the other mods.  Because _mcl_autogroup begins with an underscore it
should always be loaded after mcl_autogroup anyways.
2021-03-18 13:59:22 +01:00
Elias Åström dc41c594aa Move depends.txt into mod.conf for mcl_comparators
Fixes a crash in mcl_comparators caused by attempting to index global
'mesecon' (a nil value).
2021-03-18 13:45:29 +01:00
Elias Åström bfe51316ee Merge branch 'mcl_autogroups' 2021-03-18 13:43:58 +01:00
Elias Åström 13268965ee Update README.txt in _mcl_autogroup 2021-03-18 13:40:56 +01:00
Elias Åström 521f96b4ab Use mod.conf for mcl_autogroup and _mcl_autogroup 2021-03-18 13:36:25 +01:00
Elias Åström c8b543991f Automatically assign nodes to creative_breakable
If they belong to any digging group.
2021-03-18 11:35:40 +01:00
Elias Åström 8f9650abe4 Update the groupcaps of all enchanted tools
Not just those enchanted with efficiency.
2021-03-18 11:35:40 +01:00
Elias Åström 4c46eb2b4b Make tools without toolcaps do damage as hand
If the tool_capabilities defaults to {} if unspecified the tool, then
users will not be able to attack with the tool at all.  This solves that
by including the damage_group and full_punch_interval from the hand into
the tool_capabilities when it is nil.
2021-03-18 11:35:40 +01:00
Elias Åström fe770c19a5 Fix crash when tool_capabilities is nil 2021-03-18 11:35:40 +01:00
Elias Åström 0112825a9f Localize variables in _mcl_autogroup 2021-03-18 11:35:40 +01:00
Elias Åström cff0130506 Rename _mcl_autogroup_groupcaps to _mcl_diggroups 2021-03-18 11:35:40 +01:00
Elias Åström 7b93f68ed8 Fix typo 2021-03-18 11:35:40 +01:00
Elias Åström ece4c892f4 Force tools to include levels in their diggroups 2021-03-18 11:35:40 +01:00
Elias Åström bec1f786a6 Improve documentation of mcl_autogroup 2021-03-18 11:35:40 +01:00
Elias Åström 6458565bf9 Move mcl_util.hash to a local function
It is probably unlikely it will be useful at other places in Mineclone2.
2021-03-18 11:35:40 +01:00
Elias Åström 2e9b3c2259 Move efficiency code to its own file 2021-03-18 11:35:40 +01:00
Elias Åström 5193730652 Truncate groupcaps_hash to 8 Base64 digits 2021-03-18 11:35:40 +01:00
Elias Åström e77473e800 Make changes to the mcl_autogroup API
Group levels are now specified as a list of names when registering a
digging group.  Digging groups which do not have specified levels will
support tools having two levels, 0 and 1 where 0 means the tool can dig
but not harvest the node and 1 means it can also harvest the node.  If
more levels are required one has to specifiy them when registering the
digging group.
2021-03-18 11:35:40 +01:00
Elias Åström 922bdbc601 Use hashing for more efficient groupcaps updating
This adds the metadata field "groupcaps_hash" to tools enchanted with
efficiency.  This value contains a hash of the groupcaps field in
tool_capabilities.  This value gets compared to the expected hash value
to determine if the tools tool_capabilities should be updated according
to commit af31f8189e8e5c2b.

This commit makes efficiency more efficient.
2021-03-18 11:35:40 +01:00
Elias Åström 3241dbbec5 Update enchanted tools with outdated digging times
Because of the way digging times is implemented in Mineclone2, it is
possible for the digging times of efficiency enchanted tools to become
outdated.

This fixes that by automatically updating the tools tool_capabilities
after each time the tool is used.
2021-03-18 11:35:40 +01:00
Elias Åström b47733507d Fix tools not taking wear when rightclicking
Added the API function mcl_autogroup.get_wear which is used to get the
tool wear for digging a node of a group.  This is used by mcl_tools to
compute the wear of shovels and shears when rightclicking to create
grass paths and carve pumpkins.
2021-03-18 11:35:29 +01:00
Elias Åström f0528b11d7 Make mcl_enchanting use the new mcl_autogroups
The function mcl_autogroups.get_groupcaps is used by mods to get the
groupcaps for tools with efficiency enchantments.  This function is used
by mcl_enchanting when enchanting tools with efficiency.
2021-03-18 11:34:26 +01:00
Elias Åström 503b3a8149 Fix some nodes not being diggable
Previously some nodes like "mcl_flowers:double_grass_top" would be
undiggable.  This was because they did not define _mcl_hardness and it
was not defaulted to 0 in all parts of _mcl_autogroup.
2021-03-18 11:34:26 +01:00
Elias Åström 5b5a254b1a Fix tool uses not being set in _mcl_autogroups 2021-03-18 11:34:26 +01:00
Elias Åström 0c90dda04c Rename register_digtime_group to register_diggroup 2021-03-18 11:34:26 +01:00
Elias Åström fa86d4e5eb Change comments for mcl_autogroup 2021-03-18 11:34:20 +01:00
Elias Åström f8461d5e90 Remove mcl_autogroups.get_groupcaps
Requiring tool definitions to call a function in _mcl_autogroup means
that they need to be loaded after _mcl_autogroup.  This can cause
problems because _mcl_autogroup needs to be loaded after all tool and
node definitions are completed.

Because of this the API is changed so tool definitions instead put the
data used to generate groupcaps in the custom field
_mcl_autogroup_groupcaps.  _mcl_autogroup will then go through all
registered tools and update the groupcaps for every tool where this
field is present.  This means that no mod ever has to depend on
_mcl_autogroup.
2021-03-18 11:33:18 +01:00
Elias Åström fb6f5eae7a Rewrite mcl_autogroup
These changes are primarly made to make mcl_autogroup more efficient.
Previously enchanted tools required storing around 21 kB of metadata due
to the way the previous version of the mod was implemented.  This caused
a lot of lag and a huge amount of network traffic.  With the changes
enchanted tools won't require more than 1 kB of metadata.

The mod is also rewritten to use an API to register digging groups and
compute the groupcaps for tools.  This will make it easier for modders
to register custom digging groups.

The mod is now split up into two parts.  One part called "mcl_autogroup"
to implement the API for registering custom digging groups, and the
other part called "_mcl_autogroup" which contains most of the code which
has to be loaded after most mods.
2021-03-18 11:32:18 +01:00
AFCMS 558fa57cc6 Solve quartz not generating in the nether 2021-03-18 09:48:18 +01:00
283 changed files with 3683 additions and 2437 deletions

4
API.md
View File

@ -17,6 +17,10 @@ Items can have these fields:
anvil. anvil.
See `mcl_banners` for an example. See `mcl_banners` for an example.
Tools can have these fields:
* `_mcl_diggroups`: Specifies the digging groups that a tool can dig and how
efficiently. See `_mcl_autogroup` for more information.
All nodes can have these fields: All nodes can have these fields:
* `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0 * `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0

View File

@ -1,5 +1,8 @@
# This is a game specific minetest.conf file, do not edit # This is a game specific minetest.conf file, do not edit
# If any of these settings are set in your minetest.conf file in ~/.minetest (Linux) or in the root directory of the game (Run in place/Windows)
# They will override these settings
# Basic game rules # Basic game rules
time_speed = 72 time_speed = 72
@ -33,10 +36,10 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de
keepInventory = false keepInventory = false
# Performance settings # Performance settings
dedicated_server_step = 0.001 dedicated_server_step = 0.05 #tick rate
abm_interval = 0.25 # abm_interval = 0.25
max_objects_per_block = 4096 # max_objects_per_block = 4096
max_packets_per_iteration = 10096 # max_packets_per_iteration = 10096
# Clientmodding to support official client # Clientmodding to support official client
enable_client_modding = true enable_client_modding = true

View File

@ -4,6 +4,11 @@ Specifically, this mod has 2 purposes:
1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft. 1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft.
2) Generating digging time group for all nodes based on node metadata (it's complicated) 2) Generating digging time group for all nodes based on node metadata (it's complicated)
This mod also requires another mod called “mcl_autogroup” to function properly.
“mcl_autogroup” exposes the API used to register digging groups, while this mod
uses those digging groups to set the digging time groups for all the nodes and
tools.
See init.lua for more infos. See init.lua for more infos.
The leading underscore in the name “_mcl_autogroup” was added to force Minetest to load this mod as late as possible. The leading underscore in the name “_mcl_autogroup” was added to force Minetest to load this mod as late as possible.

View File

@ -1,169 +1,361 @@
--[[ Mining times. Yeah, mining times … Alright, this is going to be FUN! --[[
This mod implements a HACK to make 100% sure the digging times of all tools
match Minecraft's perfectly. The digging times system of Minetest is very
different, so this weird group trickery has to be used. In Minecraft, each
block has a hardness and the actual Minecraft digging time is determined by
this:
This mod does include a HACK to make 100% sure the digging times of all tools match Minecraft's perfectly.
The digging times system of Minetest is very different, so this weird group trickery has to be used.
In Minecraft, each block has a hardness and the actual Minecraft digging time is determined by this:
1) The block's hardness 1) The block's hardness
2) The tool being used 2) The tool being used (the tool speed and its efficiency level)
3) Whether the tool is considered as eligible for the block 3) Whether the tool is considered as "eligible" for the block
(e.g. only diamond pick eligible for obsidian) (e.g. only diamond pick eligible for obsidian)
See Minecraft Wiki <http://minecraft.gamepedia.com/Minecraft_Wiki> for more information.
In MineClone 2, all diggable node have the hardness set in the custom field _mcl_hardness (0 by default). See Minecraft Wiki <http://minecraft.gamepedia.com/Minecraft_Wiki> for more
The nodes are also required to specify the eligible tools in groups like pickaxey, shovely, etc. information.
This mod then calculates the real digging time based on the node meta data. The real digging times
are then added into mcl_autogroup.digtimes where the table indices are group rating and the values are the
digging times in seconds. These digging times can be then added verbatim into the tool definitions.
Example: How the mod is used
mcl_autogroup.digtimes.pickaxey_dig_diamond[1] = 0.2 ===================
This means that when a node has been assigned the group pickaxey_dig_diamond=1, it can be dug by the In MineClone 2, all diggable nodes have the hardness set in the custom field
diamond pickaxe in 0.2 seconds. "_mcl_hardness" (0 by default). These values are used together with digging
groups by this mod to create the correct digging times for nodes. Digging
groups are registered using the following code:
mcl_autogroup.register_diggroup("shovely")
mcl_autogroup.register_diggroup("pickaxey", {
levels = { "wood", "gold", "stone", "iron", "diamond" }
})
The first line registers a simple digging group. The second line registers a
digging group with 5 different levels (in this case one for each material of a
pickaxes).
This strange setup with mcl_autogroup has been done to minimize the amount of required digging times Nodes indicate that they belong to a particular digging group by being member of
a single tool needs to use. If this is not being done, the loading time will increase considerably the digging group in their node definition. "mcl_core:dirt" for example has
(>10s). shovely=1 in its groups. If the digging group has multiple levels the value of
the group indicates which digging level the node requires.
"mcl_core:stone_with_gold" for example has pickaxey=4 because it requires a
pickaxe of level 4 be mined.
]] For tools to be able to dig nodes of digging groups they need to use the have
the custom field "_mcl_diggroups" function to get the groupcaps. The value of
this field is a table which defines which groups the tool can dig and how
efficiently.
local materials = { "wood", "gold", "stone", "iron", "diamond" } _mcl_diggroups = {
local basegroups = { "pickaxey", "axey", "shovely" } handy = { speed = 1, level = 1, uses = 0 },
local minigroups = { "handy", "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" } pickaxey = { speed = 1, level = 0, uses = 0 },
local divisors = { }
["wood"] = 2,
["gold"] = 12,
["stone"] = 4,
["iron"] = 6,
["diamond"] = 8,
["handy"] = 1,
["shearsy"] = 15,
["swordy"] = 1.5,
["shearsy_wool"] = 5,
["swordy_cobweb"] = 15,
}
local max_efficiency_level = 5
mcl_autogroup = {} The "uses" field indicate how many uses (0 for infinite) a tool has when used on
mcl_autogroup.digtimes = {} the specified digging group. The "speed" field is a multiplier to the dig speed
mcl_autogroup.creativetimes = {} -- Copy of digtimes, except that all values are 0. Used for creative mode on that digging group.
for m=1, #materials do The "level" field indicates which levels of the group the tool can harvest. A
for g=1, #basegroups do level of 0 means that the tool cannot harvest blocks of that node. A level of 1
mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m]] = {} or above means that the tool can harvest nodes with that level or below. See
mcl_autogroup.creativetimes[basegroups[g].."_dig_"..materials[m]] = {} "mcl_tools/init.lua" for examples on how "_mcl_diggroups" is used in practice.
for e=1, max_efficiency_level do
mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m].."_efficiency_"..e] = {} Information about the mod
=========================
The mod is split up into two parts, mcl_autogroup and _mcl_autogroup.
mcl_autogroup contains the API functions used to register custom digging groups.
_mcl_autogroup contains most of the code. The leading underscore in the name
"_mcl_autogroup" is used to force Minetest to load that part of the mod as late
as possible. Minetest loads mods in reverse alphabetical order.
This also means that it is very important that no mod adds _mcl_autogroup as a
dependency.
--]]
assert(minetest.get_modpath("mcl_autogroup"), "This mod requires the mod mcl_autogroup to function")
-- Returns a table containing the unique "_mcl_hardness" for nodes belonging to
-- each diggroup.
local function get_hardness_values_for_groups()
local maps = {}
local values = {}
for g, _ in pairs(mcl_autogroup.registered_diggroups) do
maps[g] = {}
values[g] = {}
end
for _, ndef in pairs(minetest.registered_nodes) do
for g, _ in pairs(mcl_autogroup.registered_diggroups) do
if ndef.groups[g] ~= nil then
maps[g][ndef._mcl_hardness or 0] = true
end
end
end
for g, map in pairs(maps) do
for k, _ in pairs(map) do
table.insert(values[g], k)
end
end
for g, _ in pairs(mcl_autogroup.registered_diggroups) do
table.sort(values[g])
end
return values
end
-- Returns a table containing a table indexed by "_mcl_hardness_value" to get
-- its index in the list of unique hardnesses for each diggroup.
local function get_hardness_lookup_for_groups(hardness_values)
local map = {}
for g, values in pairs(hardness_values) do
map[g] = {}
for k, v in pairs(values) do
map[g][v] = k
end
end
return map
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 = {}
for index, hardness in pairs(hardness_values[group]) do
table.insert(creativetimes, 0)
end
return creativetimes
end
-- Get the list of digging times for using a specific tool on a specific
-- diggroup.
--
-- Parameters:
-- group - the group which it is digging
-- can_harvest - if the tool can harvest the block
-- speed - dig speed multiplier for tool (default 1)
-- efficiency - efficiency level for the tool if applicable
local function get_digtimes(group, can_harvest, speed, efficiency)
local speed = speed or 1
if efficiency then
speed = speed + efficiency * efficiency + 1
end
local digtimes = {}
for index, hardness in pairs(hardness_values[group]) do
local digtime = (hardness or 0) / speed
if can_harvest then
digtime = digtime * 1.5
else
digtime = digtime * 5
end
if digtime <= 0.05 then
digtime = 0
else
digtime = math.ceil(digtime * 20) / 20
end
table.insert(digtimes, digtime)
end
return digtimes
end
-- Get one groupcap field for using a specific tool on a specific group.
local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
return {
times = get_digtimes(group, can_harvest, multiplier, efficiency),
uses = uses,
maxlevel = 0,
}
end
-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a
-- tool.
local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency)
if not groupcaps_def then
return
end
for g, capsdef in pairs(groupcaps_def) do
local mult = capsdef.speed or 1
local uses = capsdef.uses
local def = mcl_autogroup.registered_diggroups[g]
local max_level = def.levels and #def.levels or 1
assert(capsdef.level, toolname .. ' is missing level for ' .. g)
local level = math.min(capsdef.level, max_level)
if def.levels then
groupcaps[g .. "_dig_default"] = get_groupcap(g, false, mult, efficiency, uses)
if level > 0 then
groupcaps[g .. "_dig_" .. def.levels[level]] = get_groupcap(g, true, mult, efficiency, uses)
end
else
groupcaps[g .. "_dig"] = get_groupcap(g, level > 0, mult, efficiency, uses)
end end
end end
end end
for g=1, #minigroups do
mcl_autogroup.digtimes[minigroups[g].."_dig"] = {} -- Checks if the given node would drop its useful drop if dug by a given tool.
mcl_autogroup.creativetimes[minigroups[g].."_dig"] = {} -- Returns true if it will yield its useful drop, false otherwise.
for e=1, max_efficiency_level do function mcl_autogroup.can_harvest(nodename, toolname)
mcl_autogroup.digtimes[minigroups[g].."_dig_efficiency_"..e] = {} local ndef = minetest.registered_nodes[nodename]
mcl_autogroup.creativetimes[minigroups[g].."_dig_efficiency_"..e] = {}
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
return true
end end
-- Check if it can be dug by tool
local tdef = minetest.registered_tools[toolname]
if tdef and tdef._mcl_diggroups then
for g, gdef in pairs(tdef._mcl_diggroups) do
if ndef.groups[g] then
if ndef.groups[g] <= gdef.level then
return true
end
end
end
end
-- Check if it can be dug by hand
local tdef = minetest.registered_tools[""]
if tdef then
for g, gdef in pairs(tdef._mcl_diggroups) do
if ndef.groups[g] then
if ndef.groups[g] <= gdef.level then
return true
end
end
end
end
return false
end
-- Get one groupcap field for using a specific tool on a specific group.
local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
return {
times = get_digtimes(group, can_harvest, multiplier, efficiency),
uses = uses,
maxlevel = 0,
}
end
-- Returns the tool_capabilities from a tool definition or a default set of
-- tool_capabilities
local function get_tool_capabilities(tdef)
if tdef.tool_capabilities then
return tdef.tool_capabilities
end
-- If the damage group and punch interval from hand is not included,
-- then the user will not be able to attack with the tool.
local hand_toolcaps = minetest.registered_tools[""].tool_capabilities
return {
full_punch_interval = hand_toolcaps.full_punch_interval,
damage_groups = hand_toolcaps.damage_groups
}
end
-- Get the groupcaps for a tool. This function returns "groupcaps" table of
-- digging which should be put in the "tool_capabilities" of the tool definition
-- or in the metadata of an enchanted tool.
--
-- Parameters:
-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe")
-- efficiency - The efficiency level the tool is enchanted with (default 0)
--
-- NOTE:
-- This function can only be called after mod initialization. Otherwise a mod
-- would have to add _mcl_autogroup as a dependency which would break the mod
-- loading order.
function mcl_autogroup.get_groupcaps(toolname, efficiency)
local tdef = minetest.registered_tools[toolname]
local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {})
add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency)
return groupcaps
end
-- Get the wear from using a tool on a digging group.
--
-- Parameters
-- toolname - Name of the tool used
-- diggroup - The name of the diggroup the tool is used on
--
-- NOTE:
-- This function can only be called after mod initialization. Otherwise a mod
-- would have to add _mcl_autogroup as a dependency which would break the mod
-- loading order.
function mcl_autogroup.get_wear(toolname, diggroup)
local tdef = minetest.registered_tools[toolname]
local uses = tdef._mcl_diggroups[diggroup].uses
return math.ceil(65535 / uses)
end end
local overwrite = function() local overwrite = function()
for nname, ndef in pairs(minetest.registered_nodes) do for nname, ndef in pairs(minetest.registered_nodes) do
local groups_changed = false
local newgroups = table.copy(ndef.groups) local newgroups = table.copy(ndef.groups)
if (nname ~= "ignore" and ndef.diggable) then if (nname ~= "ignore" and ndef.diggable) then
-- Automatically assign the “solid” group for solid nodes -- Automatically assign the "solid" group for solid nodes
if (ndef.walkable == nil or ndef.walkable == true) if (ndef.walkable == nil or ndef.walkable == true)
and (ndef.collision_box == nil or ndef.collision_box.type == "regular") and (ndef.collision_box == nil or ndef.collision_box.type == "regular")
and (ndef.node_box == nil or ndef.node_box.type == "regular") and (ndef.node_box == nil or ndef.node_box.type == "regular")
and (ndef.groups.not_solid == 0 or ndef.groups.not_solid == nil) then and (ndef.groups.not_solid == 0 or ndef.groups.not_solid == nil) then
newgroups.solid = 1 newgroups.solid = 1
groups_changed = true
end end
-- Automatically assign the “opaque” group for opaque nodes -- Automatically assign the "opaque" group for opaque nodes
if (not (ndef.paramtype == "light" or ndef.sunlight_propagates)) and if (not (ndef.paramtype == "light" or ndef.sunlight_propagates)) and
(ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then (ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then
newgroups.opaque = 1 newgroups.opaque = 1
groups_changed = true
end end
local function calculate_group(hardness, material, diggroup, newgroups, actual_rating, expected_rating, efficiency) local creative_breakable = false
local time, validity_factor
if actual_rating >= expected_rating then
-- Valid tool
validity_factor = 1.5
else
-- Wrong tool (higher digging time)
validity_factor = 5
end
local speed_multiplier = divisors[material]
if efficiency then
speed_multiplier = speed_multiplier + efficiency * efficiency + 1
end
time = (hardness * validity_factor) / speed_multiplier
if time <= 0.05 then
time = 0
else
time = math.ceil(time * 20) / 20
end
table.insert(mcl_autogroup.digtimes[diggroup], time)
if not efficiency then
table.insert(mcl_autogroup.creativetimes[diggroup], 0)
end
newgroups[diggroup] = #mcl_autogroup.digtimes[diggroup]
return newgroups
end
-- Hack in digging times -- Assign groups used for digging this node depending on
local hardness = ndef._mcl_hardness -- the registered digging groups
if not hardness then for g, gdef in pairs(mcl_autogroup.registered_diggroups) do
hardness = 0 creative_breakable = true
end local index = hardness_lookup[g][ndef._mcl_hardness or 0]
if ndef.groups[g] then
if gdef.levels then
newgroups[g .. "_dig_default"] = index
-- Handle pickaxey, axey and shovely for i = ndef.groups[g], #gdef.levels do
for _, basegroup in pairs(basegroups) do newgroups[g .. "_dig_" .. gdef.levels[i]] = index
if (hardness ~= -1 and ndef.groups[basegroup]) then
for g=1,#materials do
local diggroup = basegroup.."_dig_"..materials[g]
newgroups = calculate_group(hardness, materials[g], diggroup, newgroups, g, ndef.groups[basegroup])
for e=1,max_efficiency_level do
newgroups = calculate_group(hardness, materials[g], diggroup .. "_efficiency_" .. e, newgroups, g, ndef.groups[basegroup], e)
end end
groups_changed = true else
end newgroups[g .. "_dig"] = index
end
end
for m=1, #minigroups do
local minigroup = minigroups[m]
if hardness ~= -1 then
local diggroup = minigroup.."_dig"
-- actual rating
local ar = ndef.groups[minigroup]
if ar == nil then
ar = 0
end
if (minigroup == "handy")
or
(ndef.groups.shearsy_wool and minigroup == "shearsy_wool" and ndef.groups.wool)
or
(ndef.groups.swordy_cobweb and minigroup == "swordy_cobweb" and nname == "mcl_core:cobweb")
or
(ndef.groups[minigroup] and minigroup ~= "swordy_cobweb" and minigroup ~= "shearsy_wool") then
newgroups = calculate_group(hardness, minigroup, diggroup, newgroups, ar, 1)
for e=1,max_efficiency_level do
newgroups = calculate_group(hardness, minigroup, diggroup .. "_efficiency_" .. e, newgroups, ar, 1, e)
end
groups_changed = true
end end
end end
end end
if groups_changed then -- Automatically assign the node to the
minetest.override_item(nname, { -- creative_breakable group if it belongs to any digging
groups = newgroups -- group.
}) newgroups["creative_breakable"] = 1
end
minetest.override_item(nname, {
groups = newgroups
})
end
end
for tname, tdef in pairs(minetest.registered_tools) do
-- Assign groupcaps for digging the registered digging groups
-- depending on the _mcl_diggroups in the tool definition
if tdef._mcl_diggroups then
local toolcaps = table.copy(get_tool_capabilities(tdef))
toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname)
minetest.override_item(tname, {
tool_capabilities = toolcaps
})
end end
end end
end end

View File

@ -1,3 +1,3 @@
name = _mcl_autogroup name = _mcl_autogroup
author = Wuzzy author = ryvnf
description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.

23
mods/CORE/controls/API.md Normal file
View File

@ -0,0 +1,23 @@
# controls
## controls.players
Table containing player controls at runtime.
WARNING: Never use this table in writing
## controls.register_on_press(func)
Register a function that will be executed with (player, keyname) every time a player press a key.
## controls.registered_on_press
Table containing functions registered with controls.register_on_press().
## controls.register_on_release(func)
Register a function that will be executed with (player, keyname, clock_from_last_press) every time a player release a key.
## controls.registered_on_release
Table containing functions registered with controls.register_on_release().
## controls.register_on_hold(func)
Register a function that will be executed with (player, keyname, clock_from_start_hold) every time a player hold a key.
## controls.registered_on_hold
Table containing functions registered with controls.register_on_hold().

45
mods/CORE/flowlib/API.md Normal file
View File

@ -0,0 +1,45 @@
# flowlib
Simple flow functions.
## flowlib.is_touching(realpos, nodepos, radius)
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.
* pos: position
## flowlib.node_is_water(node)
Return true if <node> is water, false overwise.
* node: node
## flowlib.is_lava(pos)
Return true if node at <pos> is lava, false overwise.
* pos: position
## flowlib.node_is_lava(node)
Return true if <node> is lava, false overwise.
* node: node
## flowlib.is_liquid(pos)
Return true if node at <pos> is liquid, false overwise.
* pos: position
## flowlib.node_is_liquid(node)
Return true if <node> is liquid, false overwise.
* node: node
## flowlib.quick_flow(pos, node)
Return direction where the water is flowing (to be use to push mobs, items...).
* pos: position
* 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.
* pos: position
* realpos: position, position of the entity
* node: node
* radius: number

View File

@ -0,0 +1,27 @@
# mcl_autogroup
This mod emulate digging times from mc.
## mcl_autogroup.can_harvest(nodename, toolname)
Return true if <nodename> can be dig with <toolname>.
* nodename: string, valid nodename
* toolname: (optional) string, valid toolname
## mcl_autogroup.get_groupcaps(toolname, efficiency)
This function is used to calculate diggroups for tools.
WARNING: This function can only be called after mod initialization.
* toolname: string, name of the tool being enchanted (like "mcl_tools:diamond_pickaxe")
* 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>
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
## mcl_autogroup.register_diggroup(group, def)
* group: string, name of the group to register as a digging group
* def: (optional) table, table with information about the diggroup (defaults to {} if unspecified)
* 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.

View File

@ -0,0 +1,28 @@
--[[
This is one part of a mod to replicate the digging times from Minecraft. This
part only exposes a function to register digging groups. The rest of the mod is
implemented and documented in the _mcl_autogroup.
The mod is split up into two parts, mcl_autogroup and _mcl_autogroup.
mcl_autogroup contains the API functions used to register custom digging groups.
_mcl_autogroup contains most of the code. The leading underscore in the name
"_mcl_autogroup" is used to force Minetest to load that part of the mod as late
as possible. Minetest loads mods in reverse alphabetical order.
--]]
mcl_autogroup = {}
mcl_autogroup.registered_diggroups = {}
assert(minetest.get_modpath("_mcl_autogroup"), "This mod requires the mod _mcl_autogroup to function")
-- Register a group as a digging group.
--
-- Parameters:
-- group - Name of the group to register as a digging group
-- def - Table with information about the diggroup (defaults to {} if unspecified)
--
-- Values in def:
-- level - If specified it is an array containing the names of the different
-- digging levels the digging group supports.
function mcl_autogroup.register_diggroup(group, def)
mcl_autogroup.registered_diggroups[group] = def or {}
end

View File

@ -0,0 +1,3 @@
name = mcl_autogroup
author = ryvnf
description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.

View File

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

View File

@ -0,0 +1,15 @@
# mcl_explosions
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
* 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)
* 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

View File

@ -33,25 +33,26 @@ mcl_vars.MAP_BLOCKSIZE = math.max(1, core.MAP_BLOCKSIZE or 16)
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000) mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000) mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000)
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2) local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
local chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
local central_chunk_max_pos = central_chunk_min_pos + chunk_size_in_nodes - 1 local central_chunk_max_pos = central_chunk_min_pos + mcl_vars.chunk_size_in_nodes - 1
local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes
local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE
local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE) local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE)
local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE
local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1 local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1
local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / mcl_vars.chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk
local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits. local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * chunk_size_in_nodes mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * mcl_vars.chunk_size_in_nodes
mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * chunk_size_in_nodes mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * mcl_vars.chunk_size_in_nodes
local function coordinate_to_block(x) local function coordinate_to_block(x)
return math.floor(x / mcl_vars.MAP_BLOCKSIZE) return math.floor(x / mcl_vars.MAP_BLOCKSIZE)
end end
local function coordinate_to_chunk(x) local function coordinate_to_chunk(x)
return math.floor((coordinate_to_block(x) + central_chunk_offset) / mcl_vars.chunksize) return math.floor((coordinate_to_block(x) - central_chunk_offset) / mcl_vars.chunksize)
end end
function mcl_vars.pos_to_block(pos) function mcl_vars.pos_to_block(pos)
@ -70,7 +71,7 @@ function mcl_vars.pos_to_chunk(pos)
} }
end end
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / chunk_size_in_nodes) local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / mcl_vars.chunk_size_in_nodes)
local k_positive_z = k_positive * 2 local k_positive_z = k_positive * 2
local k_positive_y = k_positive_z * k_positive_z local k_positive_y = k_positive_z * k_positive_z
@ -174,3 +175,86 @@ minetest.craftitemdef_default.stack_max = 64
-- Set random seed for all other mods (Remember to make sure no other mod calls this function) -- Set random seed for all other mods (Remember to make sure no other mod calls this function)
math.randomseed(os.time()) math.randomseed(os.time())
local chunks = {} -- intervals of chunks generated
function mcl_vars.add_chunk(pos)
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
local prev
for i, d in pairs(chunks) do
if n <= d[2] then -- we've found it
if (n == d[2]) or (n >= d[1]) then return end -- already here
if n == d[1]-1 then -- right before:
if prev and (prev[2] == n-1) then
prev[2] = d[2]
table.remove(chunks, i)
return
end
d[1] = n
return
end
if prev and (prev[2] == n-1) then --join to previous
prev[2] = n
return
end
table.insert(chunks, i, {n, n}) -- insert new interval before i
return
end
prev = d
end
chunks[#chunks+1] = {n, n}
end
function mcl_vars.is_generated(pos)
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
for i, d in pairs(chunks) do
if n <= d[2] then
return (n >= d[1])
end
end
return false
end
-- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like mt 5.4 does.
-- p: Position, if it's wrong, {name="error"} node will return.
-- force: optional (default: false) - Do the maximum to still read the node within us_timeout.
-- us_timeout: optional (default: 244 = 0.000244 s = 1/80/80/80), set it at least to 3000000 to let mapgen to finish its job.
--
-- returns node definition, eg. {name="air"}. Unfortunately still can return {name="ignore"}.
function mcl_vars.get_node(p, force, us_timeout)
-- check initial circumstances
if not p or not p.x or not p.y or not p.z then return {name="error"} end
-- try common way
local node = minetest.get_node(p)
if node.name ~= "ignore" then
return node
end
-- copy table to get sure it won't changed by other threads
local pos = {x=p.x,y=p.y,z=p.z}
-- try LVM
minetest.get_voxel_manip():read_from_map(pos, pos)
node = minetest.get_node(pos)
if node.name ~= "ignore" or not force then
return node
end
-- all ways failed - need to emerge (or forceload if generated)
local us_timeout = us_timeout or 244
if mcl_vars.is_generated(pos) then
minetest.chat_send_all("IMPOSSIBLE! Please report this to MCL2 issue tracker!")
minetest.forceload_block(pos)
else
minetest.emerge_area(pos, pos)
end
local t = minetest.get_us_time()
node = minetest.get_node(pos)
while (not node or node.name == "ignore") and (minetest.get_us_time() - t < us_timeout) do
node = minetest.get_node(pos)
end
return node
-- it still can return "ignore", LOL, even if force = true, but only after time out
end

View File

@ -0,0 +1,80 @@
# mcl_worlds
This mod provides utility functions about positions and dimensions.
## mcl_worlds.is_in_void(pos)
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
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.
Mainly used for ore generation.
Takes an 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
If the Y coordinate is not located in any dimension, it will return: nil, "void"
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.
* pos: position
## mcl_worlds.layer_to_y(layer, mc_dimension)
Takes a Minecraft layer and a “dimension” name and returns the corresponding Y coordinate for MineClone 2.
mc_dimension can be "overworld", "nether", "end" (default: "overworld").
* layer: int
* mc_dimension: string
## mcl_worlds.has_weather(pos)
Returns true if <pos> can have weather, false owerwise.
Weather can be only in the overworld.
* pos: position
## mcl_worlds.has_dust(pos)
Returns true if <pos> can have nether dust, false owerwise.
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.
* 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.
* pos: position
## mcl_worlds.register_on_dimension_change(function(player, dimension))
Register a callback function func(player, dimension).
It will be called whenever a player changes between dimensions.
The void counts as dimension.
* player: player, the player who changed the dimension
* dimension: position, The new dimension of the player ("overworld", "nether", "end", "void").
## mcl_worlds.registered_on_dimension_change
Table containing all function registered with mcl_worlds.register_on_dimension_change()
## mcl_worlds.dimension_change(player, dimension)
Notify this mod of a dimmension change of <player> to <dimension>
* player: player, player who changed the dimension
* dimension: string, new dimension ("overworld", "nether", "end", "void")

View File

@ -6,7 +6,7 @@ mcl_worlds = {}
function mcl_worlds.is_in_void(pos) function mcl_worlds.is_in_void(pos)
local void = local void =
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
(pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or (pos.y < mcl_vars.mg_nether_max+128 and pos.y > mcl_vars.mg_nether_min) or
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min)) (pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
local void_deadly = false local void_deadly = false
@ -15,11 +15,11 @@ function mcl_worlds.is_in_void(pos)
-- Overworld → Void → End → Void → Nether → Void -- Overworld → Void → End → Void → Nether → Void
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max+128 then
-- The void between End and Nether. Like usual, but here, the void -- The void between End and Nether. Like usual, but here, the void
-- *above* the Nether also has a small tolerance area, so player -- *above* the Nether also has a small tolerance area, so player
-- can fly above the Nether without getting hurt instantly. -- can fly above the Nether without getting hurt instantly.
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max + deadly_tolerance) void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max+128 + deadly_tolerance)
elseif pos.y < mcl_vars.mg_nether_min then elseif pos.y < mcl_vars.mg_nether_min then
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
end end
@ -35,7 +35,7 @@ end
function mcl_worlds.y_to_layer(y) function mcl_worlds.y_to_layer(y)
if y >= mcl_vars.mg_overworld_min then if y >= mcl_vars.mg_overworld_min then
return y - mcl_vars.mg_overworld_min, "overworld" return y - mcl_vars.mg_overworld_min, "overworld"
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
return y - mcl_vars.mg_nether_min, "nether" return y - mcl_vars.mg_nether_min, "nether"
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
return y - mcl_vars.mg_end_min, "end" return y - mcl_vars.mg_end_min, "end"
@ -73,7 +73,7 @@ end
-- Takes a position and returns true if this position can have Nether dust -- Takes a position and returns true if this position can have Nether dust
function mcl_worlds.has_dust(pos) function mcl_worlds.has_dust(pos)
-- Weather in the Overworld and the high part of the void below -- Weather in the Overworld and the high part of the void below
return pos.y <= mcl_vars.mg_nether_max + 64 and pos.y >= mcl_vars.mg_nether_min - 64 return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10
end end
-- Takes a position (pos) and returns true if compasses are working here -- Takes a position (pos) and returns true if compasses are working here

View File

@ -1,6 +1,6 @@
local S = minetest.get_translator("mcl_boats") local S = minetest.get_translator("mcl_boats")
local boat_visual_size = {x = 3, y = 3, z = 3} local boat_visual_size = {x = 1, y = 1, z = 1}
local paddling_speed = 22 local paddling_speed = 22
local boat_y_offset = 0.35 local boat_y_offset = 0.35
local boat_y_offset_ground = boat_y_offset + 0.6 local boat_y_offset_ground = boat_y_offset + 0.6
@ -12,9 +12,7 @@ local function is_group(pos, group)
return minetest.get_item_group(nn, group) ~= 0 return minetest.get_item_group(nn, group) ~= 0
end end
local function is_water(pos) local is_water = flowlib.is_water
return is_group(pos, "water")
end
local function is_ice(pos) local function is_ice(pos)
return is_group(pos, "ice") return is_group(pos, "ice")
@ -247,7 +245,7 @@ function boat.on_step(self, dtime, moveresult)
else else
local ctrl = self._passenger:get_player_control() local ctrl = self._passenger:get_player_control()
if ctrl and ctrl.sneak then if ctrl and ctrl.sneak then
detach_player(self._passenger, true) detach_object(self._passenger, true)
self._passenger = nil self._passenger = nil
end end
end end

View File

@ -1,7 +1,7 @@
name = mcl_boats name = mcl_boats
author = PilzAdam author = PilzAdam
description = Adds drivable boats. description = Adds drivable boats.
depends = mcl_player depends = mcl_player, flowlib
optional_depends = mcl_core, doc_identifier optional_depends = mcl_core, doc_identifier

View File

@ -117,6 +117,10 @@ function mcl_burning.damage(obj)
end end
function mcl_burning.set_on_fire(obj, burn_time, reason) function mcl_burning.set_on_fire(obj, burn_time, reason)
if obj:get_hp() < 0 then
return
end
local luaentity = obj:get_luaentity() local luaentity = obj:get_luaentity()
if luaentity and luaentity.fire_resistant then if luaentity and luaentity.fire_resistant then
return return
@ -145,7 +149,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
end end
if old_burn_time <= burn_time then if old_burn_time <= burn_time then
local sound_id = mcl_burning.get(obj, "int", "sound_id") --[[local sound_id = mcl_burning.get(obj, "int", "sound_id")
if sound_id == 0 then if sound_id == 0 then
sound_id = minetest.sound_play("fire_fire", { sound_id = minetest.sound_play("fire_fire", {
object = obj, object = obj,
@ -153,7 +157,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
max_hear_distance = 16, max_hear_distance = 16,
loop = true, loop = true,
}) + 1 }) + 1
end end]]--
local hud_id local hud_id
if obj:is_player() then if obj:is_player() then
@ -163,7 +167,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
hud_elem_type = "image", hud_elem_type = "image",
position = {x = 0.5, y = 0.5}, position = {x = 0.5, y = 0.5},
scale = {x = -100, y = -100}, scale = {x = -100, y = -100},
text = "fire_basic_flame.png", text = "mcl_burning_entity_flame_animated.png^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. 1,
z_index = 1000, z_index = 1000,
}) + 1 }) + 1
end end
@ -171,7 +175,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
mcl_burning.set(obj, "float", "burn_time", burn_time) mcl_burning.set(obj, "float", "burn_time", burn_time)
mcl_burning.set(obj, "string", "reason", reason) mcl_burning.set(obj, "string", "reason", reason)
mcl_burning.set(obj, "int", "hud_id", hud_id) mcl_burning.set(obj, "int", "hud_id", hud_id)
mcl_burning.set(obj, "int", "sound_id", sound_id) --mcl_burning.set(obj, "int", "sound_id", sound_id)
local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire")
local minp, maxp = mcl_burning.get_collisionbox(obj) local minp, maxp = mcl_burning.get_collisionbox(obj)
@ -194,8 +198,8 @@ end
function mcl_burning.extinguish(obj) function mcl_burning.extinguish(obj)
if mcl_burning.is_burning(obj) then if mcl_burning.is_burning(obj) then
local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1 --local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1
minetest.sound_stop(sound_id) --minetest.sound_stop(sound_id)
if obj:is_player() then if obj:is_player() then
local hud_id = mcl_burning.get(obj, "int", "hud_id") - 1 local hud_id = mcl_burning.get(obj, "int", "hud_id") - 1
@ -206,7 +210,7 @@ function mcl_burning.extinguish(obj)
mcl_burning.set(obj, "float", "burn_time") mcl_burning.set(obj, "float", "burn_time")
mcl_burning.set(obj, "float", "damage_timer") mcl_burning.set(obj, "float", "damage_timer")
mcl_burning.set(obj, "int", "hud_id") mcl_burning.set(obj, "int", "hud_id")
mcl_burning.set(obj, "int", "sound_id") --mcl_burning.set(obj, "int", "sound_id")
end end
end end

View File

@ -1,5 +1,8 @@
local S = minetest.get_translator("mcl_falling_nodes") local S = minetest.get_translator("mcl_falling_nodes")
local dmes = minetest.get_modpath("mcl_death_messages") ~= nil local dmes = minetest.get_modpath("mcl_death_messages") ~= nil
local has_mcl_armor = minetest.get_modpath("mcl_armor")
local is_creative_enabled = minetest.is_creative_enabled
local get_falling_depth = function(self) local get_falling_depth = function(self)
if not self._startpos then if not self._startpos then
@ -13,9 +16,8 @@ local deal_falling_damage = function(self, dtime)
if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then
return return
end end
-- Cause damage to any player it hits. -- Cause damage to any entity it hits.
-- Algorithm based on MC anvils. -- Algorithm based on MC anvils.
-- TODO: Support smashing other objects, too.
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not self._startpos then if not self._startpos then
-- Fallback -- Fallback
@ -23,30 +25,39 @@ local deal_falling_damage = function(self, dtime)
end end
local objs = minetest.get_objects_inside_radius(pos, 1) local objs = minetest.get_objects_inside_radius(pos, 1)
for _,v in ipairs(objs) do for _,v in ipairs(objs) do
local hp = v:get_hp() if v:is_player() then
if v:is_player() and hp ~= 0 then local hp = v:get_hp()
if not self._hit_players then
self._hit_players = {}
end
local name = v:get_player_name() local name = v:get_player_name()
local hit = false if hp ~= 0 then
for _,v in ipairs(self._hit_players) do if not self._hit_players then
if name == v then self._hit_players = {}
hit = true
end end
end local hit = false
if not hit then for _,v in ipairs(self._hit_players) do
table.insert(self._hit_players, name) if name == v then
local way = self._startpos.y - pos.y hit = true
local damage = (way - 1) * 2
damage = math.min(40, math.max(0, damage))
if damage >= 1 then
hp = hp - damage
if hp < 0 then
hp = 0
end end
if v:is_player() then end
-- TODO: Reduce damage if wearing a helmet if not hit then
table.insert(self._hit_players, name)
local way = self._startpos.y - pos.y
local damage = (way - 1) * 2
damage = math.min(40, math.max(0, damage))
if damage >= 1 then
hp = hp - damage
if hp < 0 then
hp = 0
end
-- Reduce damage if wearing a helmet
local inv = v:get_inventory()
local helmet = inv:get_stack("armor", 2)
if has_mcl_armor and not helmet:is_empty() then
hp = hp/4*3
if not is_creative_enabled(name) then
helmet:add_wear(65535/helmet:get_definition().groups.mcl_armor_uses) --TODO: be sure damage is exactly like mc (informations are missing in the mc wiki)
inv:set_stack("armor", 2, helmet)
end
end
local msg local msg
if minetest.get_item_group(self.node.name, "anvil") ~= 0 then if minetest.get_item_group(self.node.name, "anvil") ~= 0 then
msg = S("@1 was smashed by a falling anvil.", v:get_player_name()) msg = S("@1 was smashed by a falling anvil.", v:get_player_name())
@ -56,8 +67,35 @@ local deal_falling_damage = function(self, dtime)
if dmes then if dmes then
mcl_death_messages.player_damage(v, msg) mcl_death_messages.player_damage(v, msg)
end end
v:set_hp(hp, { type = "punch", from = "mod" })
end
end
end
else
local hp = v:get_luaentity().health
if hp and hp ~= 0 then
if not self._hit_mobs then
self._hit_mobs = {}
end
local hit = false
for _,mob in ipairs(self._hit_mobs) do
if v == mob then
hit = true
end
end
--TODO: reduce damage for mobs then they will be able to wear armor
if not hit then
table.insert(self._hit_mobs, v)
local way = self._startpos.y - pos.y
local damage = (way - 1) * 2
damage = math.min(40, math.max(0, damage))
if damage >= 1 then
hp = hp - damage
if hp < 0 then
hp = 0
end
v:get_luaentity().health = hp
end end
v:set_hp(hp, { type = "punch", from = "mod" })
end end
end end
end end

View File

@ -1,10 +1,36 @@
--these are lua locals, used for higher performance
local minetest,math,vector,ipairs = minetest,math,vector,ipairs
--this is used for the player pool in the sound buffer
local pool = {}
local tick = false
minetest.register_on_joinplayer(function(player)
local name
name = player:get_player_name()
pool[name] = 0
end)
minetest.register_on_leaveplayer(function(player)
local name
name = player:get_player_name()
pool[name] = nil
end)
local has_awards = minetest.get_modpath("awards")
local mcl_item_entity = {}
--basic settings --basic settings
local item_drop_settings = {} --settings table local item_drop_settings = {} --settings table
item_drop_settings.dug_buffer = 0.65 -- the warm up period before a dug item can be collected
item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting
item_drop_settings.radius_magnet = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.radius_magnet = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect!
item_drop_settings.xp_radius_magnet = 7.25 --radius of xp magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.xp_radius_magnet = 7.25 --radius of xp magnet. MUST BE LARGER THAN radius_collect!
item_drop_settings.radius_collect = 0.2 --radius of collection item_drop_settings.radius_collect = 0.2 --radius of collection
item_drop_settings.player_collect_height = 1.0 --added to their pos y value item_drop_settings.player_collect_height = 0.8 --added to their pos y value
item_drop_settings.collection_safety = false --do this to prevent items from flying away on laggy servers item_drop_settings.collection_safety = false --do this to prevent items from flying away on laggy servers
item_drop_settings.random_item_velocity = true --this sets random item velocity if velocity is 0 item_drop_settings.random_item_velocity = true --this sets random item velocity if velocity is 0
item_drop_settings.drop_single_item = false --if true, the drop control drops 1 item instead of the entire stack, and sneak+drop drops the stack item_drop_settings.drop_single_item = false --if true, the drop control drops 1 item instead of the entire stack, and sneak+drop drops the stack
@ -16,16 +42,33 @@ local get_gravity = function()
return tonumber(minetest.settings:get("movement_gravity")) or 9.81 return tonumber(minetest.settings:get("movement_gravity")) or 9.81
end end
local registered_pickup_achievement = {}
--TODO: remove limitation of 1 award per itemname
function mcl_item_entity.register_pickup_achievement(itemname, award)
if not has_awards then
minetest.log("warning", "[mcl_item_entity] Trying to register pickup achievement ["..award.."] for ["..itemname.."] while awards missing")
elseif registered_pickup_achievement[itemname] then
minetest.log("error", "[mcl_item_entity] Trying to register already existing pickup achievement ["..award.."] for ["..itemname.."]")
else
registered_pickup_achievement[itemname] = award
end
end
mcl_item_entity.register_pickup_achievement("tree", "mcl:mineWood")
mcl_item_entity.register_pickup_achievement("mcl_mobitems:blaze_rod", "mcl:blazeRod")
mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow")
mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds")
local check_pickup_achievements = function(object, player) local check_pickup_achievements = function(object, player)
local itemname = ItemStack(object:get_luaentity().itemstring):get_name() if has_awards then
if minetest.get_item_group(itemname, "tree") ~= 0 then local itemname = ItemStack(object:get_luaentity().itemstring):get_name()
awards.unlock(player:get_player_name(), "mcl:mineWood") local playername = player:get_player_name()
elseif itemname == "mcl_mobitems:blaze_rod" then for name,award in pairs(registered_pickup_achievement) do
awards.unlock(player:get_player_name(), "mcl:blazeRod") if itemname == name or minetest.get_item_group(itemname, name) ~= 0 then
elseif itemname == "mcl_mobitems:leather" then awards.unlock(playername, award)
awards.unlock(player:get_player_name(), "mcl:killCow") end
elseif itemname == "mcl_core:diamond" then end
awards.unlock(player:get_player_name(), "mcl:diamonds")
end end
end end
@ -53,103 +96,71 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement
end end
end end
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
tick = not tick
for _,player in pairs(minetest.get_connected_players()) do for _,player in pairs(minetest.get_connected_players()) do
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
local name = player:get_player_name()
local pos = player:get_pos() local pos = player:get_pos()
if tick == true and pool[name] > 0 then
minetest.sound_play("item_drop_pickup", {
pos = pos,
gain = 0.7,
max_hear_distance = 16,
pitch = math.random(70,110)/100
})
if pool[name] > 6 then
pool[name] = 6
else
pool[name] = pool[name] - 1
end
end
local inv = player:get_inventory() local inv = player:get_inventory()
local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
--magnet and collection --magnet and collection
for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do
if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
local collected = false
if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
-- Collection -- Collection
if vector.distance(checkpos, object:get_pos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then if not object:get_luaentity()._removed then
-- Ignore if itemstring is not set yet -- Ignore if itemstring is not set yet
if object:get_luaentity().itemstring ~= "" then if object:get_luaentity().itemstring ~= "" then
inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
minetest.sound_play("item_drop_pickup", {
pos = pos,
max_hear_distance = 16,
gain = 1.0,
}, true)
check_pickup_achievements(object, player)
check_pickup_achievements(object, player)
-- Destroy entity -- Destroy entity
-- This just prevents this section to be run again because object:remove() doesn't remove the item immediately. -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately.
object:get_luaentity().target = checkpos
object:get_luaentity()._removed = true object:get_luaentity()._removed = true
object:remove()
collected = true object:set_velocity({x=0,y=0,z=0})
object:set_acceleration({x=0,y=0,z=0})
object:move_to(checkpos)
pool[name] = pool[name] + 1
minetest.after(0.25, function()
--safety check
if object and object:get_luaentity() then
object:remove()
end
end)
end end
-- Magnet
else
object:get_luaentity()._magnet_active = true
object:get_luaentity()._collector_timer = 0
-- Move object to player
disable_physics(object, object:get_luaentity())
local opos = object:get_pos()
local vec = vector.subtract(checkpos, opos)
vec = vector.add(opos, vector.divide(vec, 2))
object:move_to(vec)
--fix eternally falling items
minetest.after(0, function(object)
local lua = object:get_luaentity()
if lua then
object:set_acceleration({x=0, y=0, z=0})
end
end, object)
--this is a safety to prevent items flying away on laggy servers
if item_drop_settings.collection_safety == true then
if object:get_luaentity().init ~= true then
object:get_luaentity().init = true
minetest.after(1, function(args)
local playername = args[1]
local player = minetest.get_player_by_name(playername)
local object = args[2]
local lua = object:get_luaentity()
if player == nil or not player:is_player() or object == nil or lua == nil or lua.itemstring == nil then
return
end
if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
if not object:get_luaentity()._removed then
minetest.sound_play("item_drop_pickup", {
pos = pos,
max_hear_distance = 16,
gain = 1.0,
}, true)
end
check_pickup_achievements(object, player)
object:get_luaentity()._removed = true
object:remove()
else
enable_physics(object, object:get_luaentity())
end
end, {player:get_player_name(), object})
end
end
end
end
if not collected then
if object:get_luaentity()._magnet_timer > 1 then
object:get_luaentity()._magnet_timer = -item_drop_settings.magnet_time
object:get_luaentity()._magnet_active = false
elseif object:get_luaentity()._magnet_timer < 0 then
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
end end
end end
@ -165,66 +176,6 @@ minetest.register_globalstep(function(dtime)
end end
end) end)
local minigroups = { "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" }
local basegroups = { "pickaxey", "axey", "shovely" }
local materials = { "wood", "gold", "stone", "iron", "diamond" }
-- Checks if the given node would drop its useful drop if dug by a tool
-- with the given tool capabilities. Returns true if it will yield its useful
-- drop, false otherwise.
local check_can_drop = function(node_name, tool_capabilities)
local handy = minetest.get_item_group(node_name, "handy")
local dig_immediate = minetest.get_item_group(node_name, "dig_immediate")
if handy == 1 or dig_immediate == 2 or dig_immediate == 3 then
return true
else
local toolgroupcaps
if tool_capabilities then
toolgroupcaps = tool_capabilities.groupcaps
else
return false
end
-- Compare node groups with tool capabilities
for m=1, #minigroups do
local minigroup = minigroups[m]
local g = minetest.get_item_group(node_name, minigroup)
if g ~= 0 then
local plus = minigroup .. "_dig"
if toolgroupcaps[plus] then
return true
end
for e=1,5 do
local effplus = plus .. "_efficiency_" .. e
if toolgroupcaps[effplus] then
return true
end
end
end
end
for b=1, #basegroups do
local basegroup = basegroups[b]
local g = minetest.get_item_group(node_name, basegroup)
if g ~= 0 then
for m=g, #materials do
local plus = basegroup .. "_dig_"..materials[m]
if toolgroupcaps[plus] then
return true
end
for e=1,5 do
local effplus = plus .. "_efficiency_" .. e
if toolgroupcaps[effplus] then
return true
end
end
end
end
end
return false
end
end
-- Stupid workaround to get drops from a drop table: -- Stupid workaround to get drops from a drop table:
-- Create a temporary table in minetest.registered_nodes that contains the proper drops, -- Create a temporary table in minetest.registered_nodes that contains the proper drops,
-- because unfortunately minetest.get_node_drops needs the drop table to be inside a registered node definition -- because unfortunately minetest.get_node_drops needs the drop table to be inside a registered node definition
@ -269,29 +220,33 @@ local function get_fortune_drops(fortune_drops, fortune_level)
return drop or {} return drop or {}
end end
local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true)
function minetest.handle_node_drops(pos, drops, digger) function minetest.handle_node_drops(pos, drops, digger)
-- NOTE: This function override allows digger to be nil. -- NOTE: This function override allows digger to be nil.
-- This means there is no digger. This is a special case which allows this function to be called -- This means there is no digger. This is a special case which allows this function to be called
-- by hand. Creative Mode is intentionally ignored in this case. -- by hand. Creative Mode is intentionally ignored in this case.
local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true)
if (digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name())) or doTileDrops == false then if (digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name())) or doTileDrops == false then
return return
end end
-- Check if node will yield its useful drop by the digger's tool -- Check if node will yield its useful drop by the digger's tool
local dug_node = minetest.get_node(pos) local dug_node = minetest.get_node(pos)
local toolcaps local tooldef
local tool local tool
if digger ~= nil then if digger ~= nil then
tool = digger:get_wielded_item() tool = digger:get_wielded_item()
toolcaps = tool:get_tool_capabilities() tooldef = minetest.registered_tools[tool:get_name()]
if not check_can_drop(dug_node.name, toolcaps) then if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name()) then
return return
end end
end end
local diggroups = tooldef and tooldef._mcl_diggroups
local shearsy_level = diggroups and diggroups.shearsy and diggroups.shearsy.level
--[[ Special node drops when dug by shears by reading _mcl_shears_drop or with a silk touch tool reading _mcl_silk_touch_drop --[[ Special node drops when dug by shears by reading _mcl_shears_drop or with a silk touch tool reading _mcl_silk_touch_drop
from the node definition. from the node definition.
Definition of _mcl_shears_drop / _mcl_silk_touch_drop: Definition of _mcl_shears_drop / _mcl_silk_touch_drop:
@ -303,7 +258,7 @@ function minetest.handle_node_drops(pos, drops, digger)
local silk_touch_drop = false local silk_touch_drop = false
local nodedef = minetest.registered_nodes[dug_node.name] local nodedef = minetest.registered_nodes[dug_node.name]
if toolcaps ~= nil and toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then if shearsy_level and shearsy_level > 0 and nodedef._mcl_shears_drop then
if nodedef._mcl_shears_drop == true then if nodedef._mcl_shears_drop == true then
drops = { dug_node.name } drops = { dug_node.name }
else else
@ -371,6 +326,10 @@ function minetest.handle_node_drops(pos, drops, digger)
z = -z z = -z
end end
obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z}) obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z})
obj:get_luaentity().age = item_drop_settings.dug_buffer
obj:get_luaentity()._insta_collect = false
end end
end end
end end
@ -437,6 +396,9 @@ minetest.register_entity(":__builtin:item", {
-- Number of seconds this item entity has existed so far -- Number of seconds this item entity has existed so far
age = 0, age = 0,
-- How old it has become in the collection animation
collection_age = 0,
set_item = function(self, itemstring) set_item = function(self, itemstring)
self.itemstring = itemstring self.itemstring = itemstring
if self.itemstring == "" then if self.itemstring == "" then
@ -602,6 +564,11 @@ minetest.register_entity(":__builtin:item", {
on_step = function(self, dtime) on_step = function(self, dtime)
if self._removed then if self._removed then
self.object:set_properties({
physical = false
})
self.object:set_velocity({x=0,y=0,z=0})
self.object:set_acceleration({x=0,y=0,z=0})
return return
end end
self.age = self.age + dtime self.age = self.age + dtime

View File

@ -0,0 +1 @@
Item_Drop_Pickup - https://freesound.org/people/benniknop/sounds/317848/ (License: CC0)

View File

@ -1,5 +1,7 @@
local S = minetest.get_translator("mcl_minecarts") local S = minetest.get_translator("mcl_minecarts")
local has_mcl_wip = minetest.get_modpath("mcl_wip")
mcl_minecarts = {} mcl_minecarts = {}
mcl_minecarts.modpath = minetest.get_modpath("mcl_minecarts") mcl_minecarts.modpath = minetest.get_modpath("mcl_minecarts")
mcl_minecarts.speed_max = 10 mcl_minecarts.speed_max = 10
@ -662,8 +664,6 @@ register_minecart(
"mcl_minecarts_minecart_chest.png", "mcl_minecarts_minecart_chest.png",
{"mcl_minecarts:minecart", "mcl_chests:chest"}, {"mcl_minecarts:minecart", "mcl_chests:chest"},
nil, nil, false) nil, nil, false)
mcl_wip.register_wip_item("mcl_minecarts:chest_minecart")
-- Minecart with Furnace -- Minecart with Furnace
register_minecart( register_minecart(
@ -719,8 +719,6 @@ register_minecart(
end, nil, false end, nil, false
) )
mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart")
-- Minecart with Command Block -- Minecart with Command Block
register_minecart( register_minecart(
"mcl_minecarts:command_block_minecart", "mcl_minecarts:command_block_minecart",
@ -742,8 +740,6 @@ register_minecart(
nil, nil, false nil, nil, false
) )
mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart")
-- Minecart with Hopper -- Minecart with Hopper
register_minecart( register_minecart(
"mcl_minecarts:hopper_minecart", "mcl_minecarts:hopper_minecart",
@ -762,8 +758,6 @@ register_minecart(
nil, nil, false nil, nil, false
) )
mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart")
-- Minecart with TNT -- Minecart with TNT
register_minecart( register_minecart(
"mcl_minecarts:tnt_minecart", "mcl_minecarts:tnt_minecart",
@ -824,29 +818,34 @@ minetest.register_craft({
-- TODO: Re-enable crafting of special minecarts when they have been implemented -- TODO: Re-enable crafting of special minecarts when they have been implemented
if false then if false then
minetest.register_craft({
output = "mcl_minecarts:furnace_minecart",
recipe = {
{"mcl_furnaces:furnace"},
{"mcl_minecarts:minecart"},
},
})
minetest.register_craft({ minetest.register_craft({
output = "mcl_minecarts:furnace_minecart", output = "mcl_minecarts:hopper_minecart",
recipe = { recipe = {
{"mcl_furnaces:furnace"}, {"mcl_hoppers:hopper"},
{"mcl_minecarts:minecart"}, {"mcl_minecarts:minecart"},
}, },
}) })
minetest.register_craft({
output = "mcl_minecarts:hopper_minecart",
recipe = {
{"mcl_hoppers:hopper"},
{"mcl_minecarts:minecart"},
},
})
minetest.register_craft({
output = "mcl_minecarts:chest_minecart",
recipe = {
{"mcl_chests:chest"},
{"mcl_minecarts:minecart"},
},
})
minetest.register_craft({
output = "mcl_minecarts:chest_minecart",
recipe = {
{"mcl_chests:chest"},
{"mcl_minecarts:minecart"},
},
})
end end
if has_mcl_wip then
mcl_wip.register_wip_item("mcl_minecarts:chest_minecart")
mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart")
mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart")
mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart")
end

View File

@ -1,6 +1,6 @@
name = mcl_minecarts name = mcl_minecarts
author = Krock author = Krock
description = Minecarts are vehicles to move players quickly on rails. description = Minecarts are vehicles to move players quickly on rails.
depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons, mcl_wip depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons
optional_depends = doc_identifier optional_depends = doc_identifier, mcl_wip

View File

@ -283,6 +283,33 @@ local get_velocity = function(self)
return 0 return 0
end end
local function update_roll(self)
local is_Fleckenstein = self.nametag == "Fleckenstein"
local was_Fleckenstein = false
local rot = self.object:get_rotation()
rot.z = is_Fleckenstein and pi or 0
self.object:set_rotation(rot)
local cbox = table.copy(self.collisionbox)
local acbox = self.object:get_properties().collisionbox
if math.abs(cbox[2] - acbox[2]) > 0.1 then
was_Fleckenstein = true
end
if is_Fleckenstein ~= was_Fleckenstein then
local pos = self.object:get_pos()
pos.y = pos.y + (acbox[2] + acbox[5])
self.object:set_pos(pos)
end
if is_Fleckenstein then
cbox[2], cbox[5] = -cbox[5], -cbox[2]
end
self.object:set_properties({collisionbox = cbox})
end
-- set and return valid yaw -- set and return valid yaw
local set_yaw = function(self, yaw, delay, dtime) local set_yaw = function(self, yaw, delay, dtime)
@ -298,6 +325,7 @@ local set_yaw = function(self, yaw, delay, dtime)
yaw = yaw + (math.random() * 2 - 1) * 5 * dtime yaw = yaw + (math.random() * 2 - 1) * 5 * dtime
end end
self.object:set_yaw(yaw) self.object:set_yaw(yaw)
update_roll(self)
return yaw return yaw
end end
@ -645,9 +673,9 @@ local update_tag = function(self)
nametag = tag, nametag = tag,
}) })
update_roll(self)
end end
-- drop items -- drop items
local item_drop = function(self, cooked, looting_level) local item_drop = function(self, cooked, looting_level)
@ -707,7 +735,9 @@ local item_drop = function(self, cooked, looting_level)
end end
-- add item if it exists -- add item if it exists
obj = minetest.add_item(pos, ItemStack(item .. " " .. num)) for x = 1, num do
obj = minetest.add_item(pos, ItemStack(item .. " " .. 1))
end
if obj and obj:get_luaentity() then if obj and obj:get_luaentity() then
@ -2789,6 +2819,10 @@ local do_states = function(self, dtime)
local arrow, ent local arrow, ent
local v = 1 local v = 1
if not self.shoot_arrow then if not self.shoot_arrow then
self.firing = true
minetest.after(1, function()
self.firing = false
end)
arrow = minetest.add_entity(p, self.arrow) arrow = minetest.add_entity(p, self.arrow)
ent = arrow:get_luaentity() ent = arrow:get_luaentity()
if ent.velocity then if ent.velocity then
@ -2826,7 +2860,7 @@ local falling = function(self, pos)
end end
if mcl_portals ~= nil then if mcl_portals ~= nil then
if mcl_portals.nether_portal_cooloff[self.object] then if mcl_portals.nether_portal_cooloff(self.object) then
return false -- mob has teleported through Nether portal - it's 99% not falling return false -- mob has teleported through Nether portal - it's 99% not falling
end end
end end
@ -2856,6 +2890,18 @@ local falling = function(self, pos)
self.object:set_acceleration({x = 0, y = 0, z = 0}) self.object:set_acceleration({x = 0, y = 0, z = 0})
end end
if minetest.registered_nodes[node_ok(pos).name].groups.lava then
if self.floats_on_lava == 1 then
self.object:set_acceleration({
x = 0,
y = -self.fall_speed / (max(1, v.y) ^ 2),
z = 0
})
end
end
-- in water then float up -- in water then float up
if minetest.registered_nodes[node_ok(pos).name].groups.water then if minetest.registered_nodes[node_ok(pos).name].groups.water then
@ -3475,6 +3521,7 @@ local mob_step = function(self, dtime)
yaw = yaw + (math.random() * 2 - 1) * 5 * dtime yaw = yaw + (math.random() * 2 - 1) * 5 * dtime
end end
self.object:set_yaw(yaw) self.object:set_yaw(yaw)
update_roll(self)
end end
-- end rotation -- end rotation
@ -3694,6 +3741,8 @@ function mobs:register_mob(name, def)
local can_despawn local can_despawn
if def.can_despawn ~= nil then if def.can_despawn ~= nil then
can_despawn = def.can_despawn can_despawn = def.can_despawn
elseif def.spawn_class == "passive" then
can_despawn = false
else else
can_despawn = true can_despawn = true
end end
@ -3773,6 +3822,7 @@ minetest.register_entity(name, {
knock_back = def.knock_back ~= false, knock_back = def.knock_back ~= false,
shoot_offset = def.shoot_offset or 0, shoot_offset = def.shoot_offset or 0,
floats = def.floats or 1, -- floats in water by default floats = def.floats or 1, -- floats in water by default
floats_on_lava = def.floats_on_lava or 0,
replace_rate = def.replace_rate, replace_rate = def.replace_rate,
replace_what = def.replace_what, replace_what = def.replace_what,
replace_with = def.replace_with, replace_with = def.replace_with,
@ -4179,6 +4229,11 @@ function mobs:register_arrow(name, def)
switch = 0, switch = 0,
owner_id = def.owner_id, owner_id = def.owner_id,
rotate = def.rotate, rotate = def.rotate,
on_punch = function(self)
local vel = self.object:get_velocity()
self.object:set_velocity({x=vel.x * -1, y=vel.y * -1, z=vel.z * -1})
end,
collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0},
automatic_face_movement_dir = def.rotate automatic_face_movement_dir = def.rotate
and (def.rotate - (pi / 180)) or false, and (def.rotate - (pi / 180)) or false,
@ -4241,7 +4296,7 @@ function mobs:register_arrow(name, def)
if self.hit_player or self.hit_mob or self.hit_object then if self.hit_player or self.hit_mob or self.hit_object then
for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do
if self.hit_player if self.hit_player
and player:is_player() then and player:is_player() then

View File

@ -521,7 +521,7 @@ if c("totem") then
-- Totem of Undying -- Totem of Undying
minetest.register_craftitem("mobs_mc:totem", { minetest.register_craftitem("mobs_mc:totem", {
description = S("Totem of Undying"), description = S("Totem of Undying"),
_tt_help = minetest.colorize("#00FF00", S("Protects you from death while wielding it")), _tt_help = minetest.colorize(mcl_colors.GREEN, S("Protects you from death while wielding it")),
_doc_items_longdesc = S("A totem of undying is a rare artifact which may safe you from certain death."), _doc_items_longdesc = S("A totem of undying is a rare artifact which may safe you from certain death."),
_doc_items_usagehelp = S("The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however."), _doc_items_usagehelp = S("The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however."),
inventory_image = "mcl_totems_totem.png", inventory_image = "mcl_totems_totem.png",

View File

@ -534,9 +534,11 @@ mobs:register_mob("mobs_mc:enderman", {
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
-- self:teleport(nil) -- self:teleport(nil)
--else --else
if pr:next(1, 8) == 8 then --FIXME: real mc rate
self:teleport(hitter) self:teleport(hitter)
self.attack=hitter end
self.state="attack" self.attack=hitter
self.state="attack"
--end --end
end end
end, end,

View File

@ -63,6 +63,15 @@ mobs:register_mob("mobs_mc:ghast", {
makes_footstep_sound = false, makes_footstep_sound = false,
instant_death = true, instant_death = true,
fire_resistant = true, fire_resistant = true,
do_custom = function(self)
if self.firing == true then
self.base_texture = {"mobs_mc_ghast_firing.png"}
self.object:set_properties({textures=self.base_texture})
else
self.base_texture = {"mobs_mc_ghast.png"}
self.object:set_properties({textures=self.base_texture})
end
end,
}) })
@ -74,6 +83,7 @@ mobs:register_arrow("mobs_mc:fireball", {
visual_size = {x = 1, y = 1}, visual_size = {x = 1, y = 1},
textures = {"mcl_fire_fire_charge.png"}, textures = {"mcl_fire_fire_charge.png"},
velocity = 15, velocity = 15,
collisionbox = {-.5, -.5, -.5, .5, .5, .5},
hit_player = function(self, player) hit_player = function(self, player)
if rawget(_G, "armor") and armor.last_damage_types then if rawget(_G, "armor") and armor.last_damage_types then

View File

@ -157,8 +157,29 @@ local horse = {
self._regentimer = 0 self._regentimer = 0
end end
-- if driver present allow control of horse -- Some weird human is riding. Buck them off?
if self.driver then if self.driver and not self.tamed and self.buck_off_time <= 0 then
if math.random() < 0.2 then
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
-- TODO bucking animation
else
-- Nah, can't be bothered. Think about it again in one second
self.buck_off_time = 20
end
end
-- Tick the timer for trying to buck the player off
if self.buck_off_time then
if self.driver then
self.buck_off_time = self.buck_off_time - 1
else
-- Player isn't riding anymore so no need to count
self.buck_off_time = nil
end
end
-- if driver present and horse has a saddle allow control of horse
if self.driver and self._saddle then
mobs.drive(self, "walk", "stand", false, dtime) mobs.drive(self, "walk", "stand", false, dtime)
@ -191,6 +212,50 @@ local horse = {
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()
local iname = item:get_name() local iname = item:get_name()
local heal = 0 local heal = 0
-- Taming
self.temper = self.temper or (math.random(1,100))
if not self.tamed then
local temper_increase = 0
-- Feeding, intentionally not using mobs:feed_tame because horse taming is
-- different and more complicated
if (iname == mobs_mc.items.sugar) then
temper_increase = 3
elseif (iname == mobs_mc.items.wheat) then
temper_increase = 3
elseif (iname == mobs_mc.items.apple) then
temper_increase = 3
elseif (iname == mobs_mc.items.golden_carrot) then
temper_increase = 5
elseif (iname == mobs_mc.items.golden_apple) then
temper_increase = 10
-- Trying to ride
elseif not self.driver then
self.object:set_properties({stepheight = 1.1})
mobs.attach(self, clicker)
self.buck_off_time = 40 -- TODO how long does it take in minecraft?
if self.temper > 100 then
self.tamed = true -- NOTE taming can only be finished by riding the horse
if not self.owner or self.owner == "" then
self.owner = clicker:get_player_name()
end
end
temper_increase = 5
-- Clicking on the horse while riding ==> unmount
elseif self.driver and self.driver == clicker then
mobs.detach(clicker, {x = 1, y = 0, z = 1})
end
-- If nothing happened temper_increase = 0 and addition does nothing
self.temper = self.temper + temper_increase
return
end
if can_breed(self.name) then if can_breed(self.name) then
-- Breed horse with golden apple or golden carrot -- Breed horse with golden apple or golden carrot
if (iname == mobs_mc.items.golden_apple) then if (iname == mobs_mc.items.golden_apple) then
@ -202,7 +267,8 @@ local horse = {
return return
end end
end end
-- Feed/tame with anything else -- Feed with anything else
-- TODO heal amounts don't work
if (iname == mobs_mc.items.sugar) then if (iname == mobs_mc.items.sugar) then
heal = 1 heal = 1
elseif (iname == mobs_mc.items.wheat) then elseif (iname == mobs_mc.items.wheat) then
@ -212,7 +278,7 @@ local horse = {
elseif (iname == mobs_mc.items.hay_bale) then elseif (iname == mobs_mc.items.hay_bale) then
heal = 20 heal = 20
end end
if heal > 0 and mobs:feed_tame(self, clicker, heal, false, true) then if heal > 0 and mobs:feed_tame(self, clicker, heal, false, false) then
return return
end end
@ -450,7 +516,7 @@ mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"},
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
--mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0)
--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) --mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0)
mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0) mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0)
mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0) mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)

View File

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

View File

@ -25,6 +25,19 @@ local colors = {
unicolor_black = { mobs_mc.items.wool_black, "#000000D0" }, unicolor_black = { mobs_mc.items.wool_black, "#000000D0" },
} }
local rainbow_colors = {
"unicolor_light_red",
"unicolor_red",
"unicolor_orange",
"unicolor_yellow",
"unicolor_green",
"unicolor_dark_green",
"unicolor_light_blue",
"unicolor_blue",
"unicolor_violet",
"unicolor_red_violet"
}
if minetest.get_modpath("mcl_wool") ~= nil then if minetest.get_modpath("mcl_wool") ~= nil then
colors["unicolor_light_blue"] = { mobs_mc.items.wool_light_blue, "#5050FFD0" } colors["unicolor_light_blue"] = { mobs_mc.items.wool_light_blue, "#5050FFD0" }
end end
@ -112,7 +125,7 @@ mobs:register_mob("mobs_mc:sheep", {
end, end,
-- Set random color on spawn -- Set random color on spawn
do_custom = function(self) do_custom = function(self, dtime)
if not self.initial_color_set then if not self.initial_color_set then
local r = math.random(0,100000) local r = math.random(0,100000)
local textures local textures
@ -149,8 +162,35 @@ mobs:register_mob("mobs_mc:sheep", {
} }
self.initial_color_set = true self.initial_color_set = true
end end
local is_kay27 = self.nametag == "kay27"
if self.color_change_timer then
local old_color = self.color
if is_kay27 then
self.color_change_timer = self.color_change_timer - dtime
if self.color_change_timer < 0 then
self.color_change_timer = 0.5
self.color_index = (self.color_index + 1) % #rainbow_colors
self.color = rainbow_colors[self.color_index + 1]
end
else
self.color_change_timer = nil
self.color_index = nil
self.color = self.initial_color
end
if old_color ~= self.color then
self.base_texture = sheep_texture(self.color)
self.object:set_properties({textures = self.base_texture})
end
elseif is_kay27 then
self.initial_color = self.color
self.color_change_timer = 0
self.color_index = -1
end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
local item = clicker:get_wielded_item() local item = clicker:get_wielded_item()

View File

@ -109,7 +109,6 @@ local slime_big = {
fear_height = 0, fear_height = 0,
spawn_small_alternative = "mobs_mc:slime_small", spawn_small_alternative = "mobs_mc:slime_small",
on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5), on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5),
fire_resistant = true,
use_texture_alpha = true, use_texture_alpha = true,
} }
mobs:register_mob("mobs_mc:slime_big", slime_big) mobs:register_mob("mobs_mc:slime_big", slime_big)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -516,7 +516,7 @@ local function show_trade_formspec(playername, trader, tradenum)
"size[9,8.75]" "size[9,8.75]"
.."background[-0.19,-0.25;9.41,9.49;mobs_mc_trading_formspec_bg.png]" .."background[-0.19,-0.25;9.41,9.49;mobs_mc_trading_formspec_bg.png]"
..disabled_img ..disabled_img
.."label[4,0;"..F(minetest.colorize("#313131", S(profession))).."]" .."label[4,0;"..F(minetest.colorize(mcl_colors.DARK_GRAY, S(profession))).."]"
.."list[current_player;main;0,4.5;9,3;9]" .."list[current_player;main;0,4.5;9,3;9]"
.."list[current_player;main;0,7.74;9,1;]" .."list[current_player;main;0,7.74;9,1;]"
..b_prev..b_next ..b_prev..b_next
@ -960,13 +960,17 @@ mobs:register_mob("mobs_mc:villager", {
"mobs_mc_villager_smith.png", --hat "mobs_mc_villager_smith.png", --hat
}, },
}, },
visual_size = {x=3, y=3}, visual_size = {x=2.75, y=2.75},
makes_footstep_sound = true, makes_footstep_sound = true,
walk_velocity = 1.2, walk_velocity = 1.2,
run_velocity = 2.4, run_velocity = 2.4,
drops = {}, drops = {},
can_despawn = false, can_despawn = false,
-- TODO: sounds -- TODO: sounds
sounds = {
random = "mobs_mc_villager",
distance = 10,
},
animation = { animation = {
stand_speed = 25, stand_speed = 25,
stand_start = 40, stand_start = 40,

View File

@ -28,7 +28,7 @@ mobs:register_mob("mobs_mc:evoker", {
"blank.png", --no hat "blank.png", --no hat
-- TODO: Attack glow -- TODO: Attack glow
} }, } },
visual_size = {x=3, y=3}, visual_size = {x=2.75, y=2.75},
makes_footstep_sound = true, makes_footstep_sound = true,
damage = 6, damage = 6,
walk_velocity = 0.2, walk_velocity = 0.2,

View File

@ -36,7 +36,7 @@ mobs:register_mob("mobs_mc:illusioner", {
-- TODO: more sounds -- TODO: more sounds
distance = 16, distance = 16,
}, },
visual_size = {x=3, y=3}, visual_size = {x=2.75, y=2.75},
walk_velocity = 0.6, walk_velocity = 0.6,
run_velocity = 2, run_velocity = 2,
jump = true, jump = true,

View File

@ -30,7 +30,7 @@ mobs:register_mob("mobs_mc:vindicator", {
-- TODO: Glow when attacking (mobs_mc_vindicator.png) -- TODO: Glow when attacking (mobs_mc_vindicator.png)
}, },
}, },
visual_size = {x=3, y=3}, visual_size = {x=2.75, y=2.75},
makes_footstep_sound = true, makes_footstep_sound = true,
damage = 13, damage = 13,
reach = 2, reach = 2,

View File

@ -45,7 +45,7 @@ mobs:register_mob("mobs_mc:villager_zombie", {
{"mobs_mc_zombie_smith.png"}, {"mobs_mc_zombie_smith.png"},
{"mobs_mc_zombie_villager.png"} {"mobs_mc_zombie_villager.png"}
}, },
visual_size = {x=3, y=3}, visual_size = {x=2.75, y=2.75},
makes_footstep_sound = true, makes_footstep_sound = true,
damage = 3, damage = 3,
reach = 2, reach = 2,

View File

@ -25,7 +25,7 @@ mobs:register_mob("mobs_mc:witch", {
textures = { textures = {
{"mobs_mc_witch.png"}, {"mobs_mc_witch.png"},
}, },
visual_size = {x=3, y=3}, visual_size = {x=2.75, y=2.75},
makes_footstep_sound = true, makes_footstep_sound = true,
damage = 2, damage = 2,
reach = 2, reach = 2,

View File

@ -16,7 +16,7 @@ mobs:register_mob("mobs_mc:wither", {
hp_min = 300, hp_min = 300,
xp_min = 50, xp_min = 50,
xp_max = 50, xp_max = 50,
armor = {undead = 80, fleshy = 80}, armor = {undead = 80, fleshy = 100},
-- This deviates from MC Wiki's size, which makes no sense -- This deviates from MC Wiki's size, which makes no sense
collisionbox = {-0.9, 0.4, -0.9, 0.9, 2.45, 0.9}, collisionbox = {-0.9, 0.4, -0.9, 0.9, 2.45, 0.9},
visual = "mesh", visual = "mesh",
@ -66,6 +66,14 @@ mobs:register_mob("mobs_mc:wither", {
run_start = 0, run_end = 20, run_start = 0, run_end = 20,
}, },
harmed_by_heal = true, harmed_by_heal = true,
do_custom = function(self)
if self.health < (self.hp_max / 2) then
self.base_texture = "mobs_mc_wither_half_health.png"
self.fly = false
self.object:set_properties({textures={self.base_texture}})
self.armor = {undead = 80, fleshy = 80}
end
end,
on_spawn = function(self) on_spawn = function(self)
minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64})
end, end,

View File

@ -38,6 +38,7 @@ mcl_weather.reg_weathers["none"] = {
local storage = minetest.get_mod_storage() local storage = minetest.get_mod_storage()
-- Save weather into mod storage, so it can be loaded after restarting the server -- Save weather into mod storage, so it can be loaded after restarting the server
local save_weather = function() local save_weather = function()
if not mcl_weather.end_time then return end
storage:set_string("mcl_weather_state", mcl_weather.state) storage:set_string("mcl_weather_state", mcl_weather.state)
storage:set_int("mcl_weather_end_time", mcl_weather.end_time) storage:set_int("mcl_weather_end_time", mcl_weather.end_time)
minetest.log("verbose", "[mcl_weather] Weather data saved: state="..mcl_weather.state.." end_time="..mcl_weather.end_time) minetest.log("verbose", "[mcl_weather] Weather data saved: state="..mcl_weather.state.." end_time="..mcl_weather.end_time)

View File

@ -1,13 +1,7 @@
local S = minetest.get_translator("doc") local S = minetest.get_translator("doc")
local F = function(f) return minetest.formspec_escape(S(f)) end local F = function(f) return minetest.formspec_escape(S(f)) end
-- Compability for 0.4.14 or earlier local colorize = minetest.colorize
local colorize
if minetest.colorize then
colorize = minetest.colorize
else
colorize = function(color, text) return text end
end
doc = {} doc = {}
@ -41,10 +35,10 @@ doc.FORMSPEC.ENTRY_HEIGHT = doc.FORMSPEC.ENTRY_END_Y - doc.FORMSPEC.ENTRY_START_
-- Internal helper variables -- Internal helper variables
local DOC_INTRO = S("This is the help.") local DOC_INTRO = S("This is the help.")
local COLOR_NOT_VIEWED = "#00FFFF" -- cyan local COLOR_NOT_VIEWED = mcl_colors.AQUA
local COLOR_VIEWED = "#FFFFFF" -- white local COLOR_VIEWED = mcl_colors.WHITE
local COLOR_HIDDEN = "#999999" -- gray local COLOR_HIDDEN = mcl_colors.GRAY
local COLOR_ERROR = "#FF0000" -- red local COLOR_ERROR = mcl_colors.RED
local CATEGORYFIELDSIZE = { local CATEGORYFIELDSIZE = {
WIDTH = math.ceil(doc.FORMSPEC.WIDTH / 4), WIDTH = math.ceil(doc.FORMSPEC.WIDTH / 4),
@ -776,7 +770,7 @@ function doc.generate_entry_list(cid, playername)
if name == nil or name == "" then if name == nil or name == "" then
name = S("Nameless entry (@1)", eid) name = S("Nameless entry (@1)", eid)
if doc.entry_viewed(playername, cid, eid) then if doc.entry_viewed(playername, cid, eid) then
viewedprefix = "#FF4444" viewedprefix = mcl_colors.RED
else else
viewedprefix = COLOR_ERROR viewedprefix = COLOR_ERROR
end end

View File

@ -2,3 +2,4 @@ name = doc
author = Wuzzy author = Wuzzy
description = A simple in-game documentation system which enables mods to add help entries based on templates. description = A simple in-game documentation system which enables mods to add help entries based on templates.
optional_depends = unified_inventory, sfinv_buttons, central_message, inventory_plus optional_depends = unified_inventory, sfinv_buttons, central_message, inventory_plus
depends = mcl_colors

View File

@ -410,7 +410,7 @@ local function get_tooltip(item, groups, cooktime, burntime)
local tooltip local tooltip
if groups then if groups then
local gcol = "#FFAAFF" local gcol = mcl_colors.LIGHT_PURPLE
if #groups == 1 then if #groups == 1 then
local g = group_names[groups[1]] local g = group_names[groups[1]]
local groupstr local groupstr
@ -446,12 +446,12 @@ local function get_tooltip(item, groups, cooktime, burntime)
if not groups and cooktime then if not groups and cooktime then
tooltip = tooltip .. "\n" .. tooltip = tooltip .. "\n" ..
S("Cooking time: @1", colorize("yellow", cooktime)) S("Cooking time: @1", colorize(mcl_colors.YELLOW, cooktime))
end end
if not groups and burntime then if not groups and burntime then
tooltip = tooltip .. "\n" .. tooltip = tooltip .. "\n" ..
S("Burning time: @1", colorize("yellow", burntime)) S("Burning time: @1", colorize(mcl_colors.YELLOW, burntime))
end end
return fmt(FMT.tooltip, item, ESC(tooltip)) return fmt(FMT.tooltip, item, ESC(tooltip))
@ -668,7 +668,7 @@ local function make_formspec(name)
fs[#fs + 1] = fmt("label[%f,%f;%s]", fs[#fs + 1] = fmt("label[%f,%f;%s]",
sfinv_only and 6.3 or data.iX - 2.2, sfinv_only and 6.3 or data.iX - 2.2,
0.22, 0.22,
ESC(colorize("#383838", fmt("%s / %u", data.pagenum, data.pagemax)))) ESC(colorize(mcl_colors.DARK_GRAY, fmt("%s / %u", data.pagenum, data.pagemax))))
fs[#fs + 1] = fmt([[ fs[#fs + 1] = fmt([[
image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;] image_button[%f,0.12;0.8,0.8;craftguide_prev_icon.png;prev;]

View File

@ -1,5 +1,5 @@
name = mcl_craftguide name = mcl_craftguide
author = kilbith author = kilbith
description = The most comprehensive Crafting Guide on Minetest. description = The most comprehensive Crafting Guide on Minetest.
depends = mcl_core, mcl_compass, mcl_clock, doc depends = mcl_core, mcl_compass, mcl_clock, doc, mcl_colors
optional_depends = sfinv, sfinv_buttons optional_depends = sfinv, sfinv_buttons

View File

@ -1,4 +1,4 @@
name = mcl_tt name = mcl_tt
author = Wuzzy author = Wuzzy
description = Add MCL2 tooltips description = Add MCL2 tooltips
depends = tt, mcl_enchanting depends = tt, mcl_enchanting, mcl_colors

View File

@ -77,7 +77,7 @@ end)
tt.register_snippet(function(itemstring) tt.register_snippet(function(itemstring)
local def = minetest.registered_items[itemstring] local def = minetest.registered_items[itemstring]
if minetest.get_item_group(itemstring, "crush_after_fall") == 1 then if minetest.get_item_group(itemstring, "crush_after_fall") == 1 then
return S("Deals damage when falling"), "#FFFF00" return S("Deals damage when falling"), mcl_colors.YELLOW
end end
end) end)

View File

@ -1,7 +1,8 @@
tt = {} tt = {}
tt.COLOR_DEFAULT = "#d0ffd0" tt.COLOR_DEFAULT = mcl_colors.GREEN
tt.COLOR_DANGER = "#ffff00" tt.COLOR_DANGER = mcl_colors.YELLOW
tt.COLOR_GOOD = "#00ff00" tt.COLOR_GOOD = mcl_colors.GREEN
tt.NAME_COLOR = mcl_colors.YELLOW
-- API -- API
tt.registered_snippets = {} tt.registered_snippets = {}
@ -63,12 +64,15 @@ tt.reload_itemstack_description = function(itemstack)
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
if def and def._mcl_generate_description then if def and def._mcl_generate_description then
def._mcl_generate_description(itemstack) def._mcl_generate_description(itemstack)
elseif should_change(itemstring, def) and meta:get_string("name") == "" then elseif should_change(itemstring, def) then
local toolcaps local toolcaps
if def.tool_capabilities then if def.tool_capabilities then
toolcaps = itemstack:get_tool_capabilities() toolcaps = itemstack:get_tool_capabilities()
end end
local orig_desc = def._tt_original_description or def.description 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"))
end
local desc = apply_snippets(orig_desc, itemstring, toolcaps or def.tool_capabilities, itemstack) local desc = apply_snippets(orig_desc, itemstring, toolcaps or def.tool_capabilities, itemstack)
if desc ~= orig_desc then if desc ~= orig_desc then
meta:set_string("description", desc) meta:set_string("description", desc)

View File

@ -1,3 +1,4 @@
name = tt name = tt
author = Wuzzy author = Wuzzy
description = Support for custom tooltip extensions for items description = Support for custom tooltip extensions for items
depends = mcl_colors

View File

@ -214,7 +214,7 @@ function awards.unlock(name, award)
-- Get award -- Get award
minetest.log("action", name.." has gotten award "..award) minetest.log("action", name.." has gotten award "..award)
minetest.chat_send_all(S("@1 has made the achievement @2", name, minetest.colorize("#51EF4E", "[" .. (awdef.title or award) .. "]"))) minetest.chat_send_all(S("@1 has made the achievement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]")))
data.unlocked[award] = award data.unlocked[award] = award
awards.save() awards.save()
@ -447,7 +447,7 @@ function awards.getFormspec(name, to, sid)
first = false first = false
if def.secret and not award.got then if def.secret and not award.got then
formspec = formspec .. "#707070"..minetest.formspec_escape(S("(Secret Award)")) formspec = formspec .. mcl_colors.DARK_GRAY..minetest.formspec_escape(S("(Secret Award)"))
else else
local title = award.name local title = award.name
if def and def.title then if def and def.title then
@ -456,7 +456,7 @@ function awards.getFormspec(name, to, sid)
if award.got then if award.got then
formspec = formspec .. minetest.formspec_escape(title) formspec = formspec .. minetest.formspec_escape(title)
else else
formspec = formspec .. "#ACACAC".. minetest.formspec_escape(title) formspec = formspec .. mcl_colors.GRAY.. minetest.formspec_escape(title)
end end
end end
end end

View File

@ -6,3 +6,4 @@ license = LGPL 2.1 or later
forum = https://forum.minetest.net/viewtopic.php?t=4870 forum = https://forum.minetest.net/viewtopic.php?t=4870
version = 2.3.0 version = 2.3.0
optional_depends = sfinv, unified_inventory optional_depends = sfinv, unified_inventory
depends = mcl_colors

View File

@ -20,9 +20,9 @@ if hb.settings.bar_type == "progress_bar" then
hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15) hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15)
hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86) hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86)
else else
hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -265) hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -258)
hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_statbar_offset_left_y", "number", -90) hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_statbar_offset_left_y", "number", -90)
hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 25) hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 16)
hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_statbar_offset_right_y", "number", -90) hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_statbar_offset_right_y", "number", -90)
end end
-- Modified in MCL2! -- Modified in MCL2!

View File

@ -238,3 +238,20 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
awards.show_to(name, name, nil, false) awards.show_to(name, name, nil, false)
end end
end) end)
awards.register_achievement("mcl:stoneAge", {
title = S("Stone Age"),
description = S("Mine a stone with new pickaxe."),
icon = "default_cobble.png",
})
awards.register_achievement("mcl:hotStuff", {
title = S("Hot Stuff"),
description = S("Put lava in a bucket."),
icon = "bucket_lava.png",
})
awards.register_achievement("mcl:obsidian", {
title = S("Ice Bucket Challenge"),
description = S("Obtain an obsidian block."),
icon = "default_obsidian.png",
})

View File

@ -1,5 +1,8 @@
local S = minetest.get_translator("mcl_death_messages") local S = minetest.get_translator("mcl_death_messages")
local N = function(s) return s end local N = function(s) return s end
local C = minetest.colorize
local color_skyblue = mcl_colors.AQUA
local function get_tool_name(item) local function get_tool_name(item)
local name = item:get_meta():get_string("name") local name = item:get_meta():get_string("name")
@ -41,6 +44,9 @@ local msgs = {
["murder"] = { ["murder"] = {
N("@1 was slain by @2 using [@3]"), N("@1 was slain by @2 using [@3]"),
}, },
["murder_hand"] = {
N("@1 was slain by @2"),
},
["murder_any"] = { ["murder_any"] = {
N("@1 was killed."), N("@1 was killed."),
}, },
@ -131,7 +137,7 @@ local last_damages = { }
minetest.register_on_dieplayer(function(player, reason) minetest.register_on_dieplayer(function(player, reason)
-- Death message -- Death message
local message = minetest.settings:get_bool("mcl_showDeathMessages") local message = minetest.settings:get_bool("mcl_showDeathMessages") --Maybe cache the setting?
if message == nil then if message == nil then
message = true message = true
end end
@ -201,7 +207,11 @@ minetest.register_on_dieplayer(function(player, reason)
elseif hitter:is_player() then elseif hitter:is_player() then
hittername = hitter:get_player_name() hittername = hitter:get_player_name()
if hittername ~= nil then if hittername ~= nil then
msg = dmsg("murder", name, hittername, minetest.colorize("#00FFFF", hitter_toolname)) if hitter_toolname == "" then
msg = dmsg("murder_hand", name, hittername)
else
msg = dmsg("murder", name, hittername, C(color_skyblue, hitter_toolname))
end
else else
msg = dmsg("murder_any", name) msg = dmsg("murder_any", name)
end end
@ -229,7 +239,7 @@ minetest.register_on_dieplayer(function(player, reason)
if shooter == nil then if shooter == nil then
msg = dmsg("arrow", name) msg = dmsg("arrow", name)
elseif shooter:is_player() then elseif shooter:is_player() then
msg = dmsg("arrow_name", name, shooter:get_player_name(), minetest.colorize("#00FFFF", get_tool_name(shooter:get_wielded_item()))) msg = dmsg("arrow_name", name, shooter:get_player_name(), C(color_skyblue, get_tool_name(shooter:get_wielded_item())))
elseif s_ent and s_ent._cmi_is_mob then elseif s_ent and s_ent._cmi_is_mob then
if s_ent.nametag ~= "" then if s_ent.nametag ~= "" then
msg = dmsg("arrow_name", name, shooter:get_player_name(), get_tool_name(shooter:get_wielded_item())) msg = dmsg("arrow_name", name, shooter:get_player_name(), get_tool_name(shooter:get_wielded_item()))

View File

@ -56,3 +56,4 @@ A ghast scared @1 to death.=Ein Ghast hat @1 zu Tode erschrocken.
@1 was killed by a baby husk.=@1 wurde von einem Wüstenzombiebaby getötet. @1 was killed by a baby husk.=@1 wurde von einem Wüstenzombiebaby getötet.
@1 was killed by a zombie pigman.=@1 wurde von einem Schweinezombie getötet. @1 was killed by a zombie pigman.=@1 wurde von einem Schweinezombie getötet.
@1 was killed by a baby zombie pigman.=@1 wurde von einem Schweinezombiebaby getötet. @1 was killed by a baby zombie pigman.=@1 wurde von einem Schweinezombiebaby getötet.
@1 was slain by @2.=

View File

@ -55,3 +55,4 @@ A ghast scared @1 to death.=Se ha asustado @1 hasta morir.
@1 was killed by a baby husk.=@1 fue asesinado por un bebé husk. @1 was killed by a baby husk.=@1 fue asesinado por un bebé husk.
@1 was killed by a zombie pigman.=@1 fue asesinado por un cerdo zombie. @1 was killed by a zombie pigman.=@1 fue asesinado por un cerdo zombie.
@1 was killed by a baby zombie pigman.=@1 fue asesinado por un bebé cerdo zombie. @1 was killed by a baby zombie pigman.=@1 fue asesinado por un bebé cerdo zombie.
@1 was slain by @2.=

View File

@ -56,3 +56,4 @@ A ghast scared @1 to death.=Un ghast a éffrayé @1 à mort.
@1 was killed by a baby husk.=@1 a été tué par un bébé zombie momie. @1 was killed by a baby husk.=@1 a été tué par un bébé zombie momie.
@1 was killed by a zombie pigman.=@1 a été tué par un zombie-couchon. @1 was killed by a zombie pigman.=@1 a été tué par un zombie-couchon.
@1 was killed by a baby zombie pigman.=@1 a été tué par un bébé zombie-couchon @1 was killed by a baby zombie pigman.=@1 a été tué par un bébé zombie-couchon
@1 was slain by @2.=

View File

@ -56,3 +56,4 @@ A ghast scared @1 to death.=Гаст напугал @1 до смерти.
@1 was killed by a baby husk.=@1 был(а) убит(а) машылом-кадавром. @1 was killed by a baby husk.=@1 был(а) убит(а) машылом-кадавром.
@1 was killed by a zombie pigman.=@1 был(а) убит(а) зомби-свиночеловеком. @1 was killed by a zombie pigman.=@1 был(а) убит(а) зомби-свиночеловеком.
@1 was killed by a baby zombie pigman.=@1 был(а) убит(а) малышом-зомби-свиночеловеком. @1 was killed by a baby zombie pigman.=@1 был(а) убит(а) малышом-зомби-свиночеловеком.
@1 was slain by @2.=

View File

@ -56,3 +56,4 @@ A ghast scared @1 to death.=
@1 was killed by a baby husk.= @1 was killed by a baby husk.=
@1 was killed by a zombie pigman.= @1 was killed by a zombie pigman.=
@1 was killed by a baby zombie pigman.= @1 was killed by a baby zombie pigman.=
@1 was slain by @2.=

View File

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

View File

@ -442,7 +442,7 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
end end
local caption = "" local caption = ""
if name ~= "inv" and filtername[name] then if name ~= "inv" and filtername[name] then
caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]" caption = "label[0,1.2;"..F(minetest.colorize(mcl_colors.DARK_GRAY, filtername[name])).."]"
end end
formspec = "size[10,9.3]".. formspec = "size[10,9.3]"..
@ -489,8 +489,8 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz
if filter == nil then if filter == nil then
filter = "" filter = ""
end end
formspec = formspec .. "field[5.3,1.34;4,0.75;suche;;"..minetest.formspec_escape(filter).."]" formspec = formspec .. "field[5.3,1.34;4,0.75;search;;"..minetest.formspec_escape(filter).."]"
formspec = formspec .. "field_close_on_enter[suche;false]" formspec = formspec .. "field_close_on_enter[search;false]"
end end
if pagenum ~= nil then formspec = formspec .. "p"..tostring(pagenum) end if pagenum ~= nil then formspec = formspec .. "p"..tostring(pagenum) end
@ -561,11 +561,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
elseif fields.inv then elseif fields.inv then
if players[name].page == "inv" then return end if players[name].page == "inv" then return end
page = "inv" page = "inv"
elseif fields.suche == "" and not fields.creative_next and not fields.creative_prev then elseif fields.search == "" and not fields.creative_next and not fields.creative_prev then
set_inv_page("all", player) set_inv_page("all", player)
page = "nix" page = "nix"
elseif fields.suche ~= nil and not fields.creative_next and not fields.creative_prev then elseif fields.search ~= nil and not fields.creative_next and not fields.creative_prev then
set_inv_search(string.lower(fields.suche),player) set_inv_search(string.lower(fields.search),player)
page = "nix" page = "nix"
end end
@ -612,8 +612,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
players[name].start_i = start_i players[name].start_i = start_i
local filter = "" local filter = ""
if not fields.nix and fields.suche ~= nil and fields.suche ~= "" then if not fields.nix and fields.search ~= nil and fields.search ~= "" then
filter = fields.suche filter = fields.search
players[name].filter = filter players[name].filter = filter
end end

View File

@ -109,10 +109,10 @@ local function set_inventory(player, armor_change_only)
mcl_formspec.get_itemslot_bg(0,3,1,1).. mcl_formspec.get_itemslot_bg(0,3,1,1)..
armor_slot_imgs.. armor_slot_imgs..
-- craft and inventory -- craft and inventory
"label[0,4;"..F(minetest.colorize("#313131", S("Inventory"))).."]".. "label[0,4;"..F(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]".. "list[current_player;main;0,4.5;9,3;9]"..
"list[current_player;main;0,7.74;9,1;]".. "list[current_player;main;0,7.74;9,1;]"..
"label[4,0.5;"..F(minetest.colorize("#313131", S("Crafting"))).."]".. "label[4,0.5;"..F(minetest.colorize(mcl_colors.DARK_GRAY, S("Crafting"))).."]"..
"list[current_player;craft;4,1;2,2]".. "list[current_player;craft;4,1;2,2]"..
"list[current_player;craftpreview;7,1.5;1,1;]".. "list[current_player;craftpreview;7,1.5;1,1;]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3).. mcl_formspec.get_itemslot_bg(0,4.5,9,3)..

View File

@ -1,6 +1,6 @@
name = mcl_inventory name = mcl_inventory
author = BlockMen author = BlockMen
description = Adds the player inventory and creative inventory. description = Adds the player inventory and creative inventory.
depends = mcl_init, mcl_formspec depends = mcl_init, mcl_formspec, mcl_colors
optional_depends = mcl_player, _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting optional_depends = mcl_player, _mcl_autogroup, mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting

View File

@ -0,0 +1,7 @@
# mcl_temp_message
Allow mods to show short messages in the hud of players.
## mcl_tmp_message.message(player, message)
Show above the hotbar a hud message <message> to player <player>.

View File

@ -1,4 +0,0 @@
mesecons
mcl_sounds
doc?
screwdriver?

View File

@ -1,2 +1,3 @@
name = mcl_comparators name = mcl_comparators
depends = mcl_wip depends = mcl_wip, mesecons, mcl_sounds
optional_depends = doc, screwdriver

View File

@ -1,12 +0,0 @@
mcl_init
mcl_formspec
mesecons
mcl_sounds
mcl_tnt
mcl_worlds
mcl_core
mcl_nether
mcl_armor_stand
mcl_armor
doc?
screwdriver?

View File

@ -13,12 +13,12 @@ local S = minetest.get_translator("mcl_dispensers")
local setup_dispenser = function(pos) local setup_dispenser = function(pos)
-- Set formspec and inventory -- Set formspec and inventory
local form = "size[9,8.75]".. local form = "size[9,8.75]"..
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]".. "list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3).. mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]".. "list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1).. mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dispenser"))).."]".. "label[3,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Dispenser"))).."]"..
"list[current_name;main;3,0.5;3,3;]".. "list[current_name;main;3,0.5;3,3;]"..
mcl_formspec.get_itemslot_bg(3,0.5,3,3).. mcl_formspec.get_itemslot_bg(3,0.5,3,3)..
"listring[current_name;main]".. "listring[current_name;main]"..

View File

@ -0,0 +1,3 @@
name = mcl_dispensers
depends = mcl_init, mcl_formspec, mesecons, mcl_sounds, mcl_tnt, mcl_worlds, mcl_core, mcl_nether, mcl_armor_stand, mcl_armor, mcl_colors
optional_depends = doc, screwdriver

View File

@ -1,6 +0,0 @@
mcl_init
mcl_formspec
mesecons
mcl_util
doc?
screwdriver?

View File

@ -14,12 +14,12 @@ local S = minetest.get_translator("mcl_droppers")
local setup_dropper = function(pos) local setup_dropper = function(pos)
-- Set formspec and inventory -- Set formspec and inventory
local form = "size[9,8.75]".. local form = "size[9,8.75]"..
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]".. "list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3).. mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]".. "list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1).. mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dropper"))).."]".. "label[3,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Dropper"))).."]"..
"list[current_name;main;3,0.5;3,3;]".. "list[current_name;main;3,0.5;3,3;]"..
mcl_formspec.get_itemslot_bg(3,0.5,3,3).. mcl_formspec.get_itemslot_bg(3,0.5,3,3)..
"listring[current_name;main]".. "listring[current_name;main]"..

View File

@ -15,10 +15,10 @@ local setup_dropper = function(pos)
-- Set formspec and inventory -- Set formspec and inventory
local form = "size[9,8.75]".. local form = "size[9,8.75]"..
"background[-0.19,-0.25;9.41,9.49;crafting_inventory_9_slots.png]".. "background[-0.19,-0.25;9.41,9.49;crafting_inventory_9_slots.png]"..
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. "label[0,4.0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]".. "list[current_player;main;0,4.5;9,3;9]"..
"list[current_player;main;0,7.74;9,1;]".. "list[current_player;main;0,7.74;9,1;]"..
"label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dropper"))).."]".. "label[3,0;"..minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Dropper"))).."]"..
"list[current_name;main;3,0.5;3,3;]".. "list[current_name;main;3,0.5;3,3;]"..
"listring[current_name;main]".. "listring[current_name;main]"..
"listring[current_player;main]" "listring[current_player;main]"

View File

@ -0,0 +1,3 @@
name = mcl_droppers
depends = mcl_init, mcl_formspec, mesecons, mcl_util, mcl_colors
optional_depends = doc, screwdriver

View File

@ -1,2 +0,0 @@
mesecons
mcl_util

View File

@ -0,0 +1,2 @@
name = mcl_observers
depends = mesecons, mcl_util

View File

@ -1,3 +0,0 @@
mcl_sounds
mcl_core
doc?

View File

@ -0,0 +1,3 @@
name = mesecons
depends = mcl_sounds, mcl_core
optional_depends = doc

View File

@ -1 +0,0 @@
mesecons

View File

@ -0,0 +1,2 @@
name = mesecons_alias
depends = mesecons

View File

@ -1,2 +0,0 @@
mesecons
doc?

View File

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

View File

@ -1,3 +0,0 @@
mesecons
doc?
doc_items?

View File

@ -1,6 +1,11 @@
local S = minetest.get_translator("mesecons_commandblock") local S = minetest.get_translator("mesecons_commandblock")
local F = minetest.formspec_escape local F = minetest.formspec_escape
local color_red = mcl_colors.RED
local command_blocks_activated = minetest.settings:get_bool("mcl_enable_commandblocks", true)
local msg_not_activated = S("Command blocks are not enabled on this server")
local function construct(pos) local function construct(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
@ -78,7 +83,7 @@ local function check_commands(commands, player_name)
if string.sub(cmd, 1, 1) == "/" then if string.sub(cmd, 1, 1) == "/" then
msg = S("Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands. Hint: Try to remove the leading slash.", cmd) msg = S("Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands. Hint: Try to remove the leading slash.", cmd)
end end
return false, minetest.colorize("#FF0000", msg) return false, minetest.colorize(color_red, msg)
end end
if player_name then if player_name then
local player_privs = minetest.get_player_privs(player_name) local player_privs = minetest.get_player_privs(player_name)
@ -86,7 +91,7 @@ local function check_commands(commands, player_name)
for cmd_priv, _ in pairs(cmddef.privs) do for cmd_priv, _ in pairs(cmddef.privs) do
if player_privs[cmd_priv] ~= true then if player_privs[cmd_priv] ~= true then
local msg = S("Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.", cmd, cmd_priv) local msg = S("Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.", cmd, cmd_priv)
return false, minetest.colorize("#FF0000", msg) return false, minetest.colorize(color_red, msg)
end end
end end
end end
@ -98,10 +103,15 @@ local function commandblock_action_on(pos, node)
if node.name ~= "mesecons_commandblock:commandblock_off" then if node.name ~= "mesecons_commandblock:commandblock_off" then
return return
end end
minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local commander = meta:get_string("commander")
if not command_blocks_activated then
--minetest.chat_send_player(commander, msg_not_activated)
return
end
minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"})
local commands = resolve_commands(meta:get_string("commands"), pos) local commands = resolve_commands(meta:get_string("commands"), pos)
for _, command in pairs(commands:split("\n")) do for _, command in pairs(commands:split("\n")) do
@ -117,7 +127,6 @@ local function commandblock_action_on(pos, node)
return return
end end
-- Execute command in the name of commander -- Execute command in the name of commander
local commander = meta:get_string("commander")
cmddef.func(commander, param) cmddef.func(commander, param)
end end
end end
@ -129,6 +138,10 @@ local function commandblock_action_off(pos, node)
end end
local on_rightclick = function(pos, node, player, itemstack, pointed_thing) local on_rightclick = function(pos, node, player, itemstack, pointed_thing)
if not command_blocks_activated then
minetest.chat_send_player(player:get_player_name(), msg_not_activated)
return
end
local can_edit = true local can_edit = true
-- Only allow write access in Creative Mode -- Only allow write access in Creative Mode
if not minetest.is_creative_enabled(player:get_player_name()) then if not minetest.is_creative_enabled(player:get_player_name()) then

View File

@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.=Zugr
Editing the command block has failed! You can only change the command block in Creative Mode!=Bearbeitung des Befehlsblocks fehlgeschlagen! Sie können den Befehlsblock nur im Kreativmodus ändern! Editing the command block has failed! You can only change the command block in Creative Mode!=Bearbeitung des Befehlsblocks fehlgeschlagen! Sie können den Befehlsblock nur im Kreativmodus ändern!
Editing the command block has failed! The command block is gone.=Bearbeiten des Befehlsblocks fehlgeschlagen! Der Befehlsblock ist verschwunden. Editing the command block has failed! The command block is gone.=Bearbeiten des Befehlsblocks fehlgeschlagen! Der Befehlsblock ist verschwunden.
Executes server commands when powered by redstone power=Führt Serverbefehle aus, wenn mit Redstoneenergie versorgt Executes server commands when powered by redstone power=Führt Serverbefehle aus, wenn mit Redstoneenergie versorgt
Command blocks are not enabled on this server=

View File

@ -28,3 +28,4 @@ Example 2:@n give @@n mcl_core:apple 5@nGives the nearest player 5 apples=2.
Access denied. You need the “maphack” privilege to edit command blocks.=Acceso denegado. Necesita el privilegio "maphack" para editar bloques de comandos. Access denied. You need the “maphack” privilege to edit command blocks.=Acceso denegado. Necesita el privilegio "maphack" para editar bloques de comandos.
Editing the command block has failed! You can only change the command block in Creative Mode!=¡La edición del bloque de comando ha fallado! ¡Solo puede cambiar el bloque de comandos en modo creativo! Editing the command block has failed! You can only change the command block in Creative Mode!=¡La edición del bloque de comando ha fallado! ¡Solo puede cambiar el bloque de comandos en modo creativo!
Editing the command block has failed! The command block is gone.=¡La edición del bloque de comando ha fallado! El bloque de comando se ha ido. Editing the command block has failed! The command block is gone.=¡La edición del bloque de comando ha fallado! El bloque de comando se ha ido.
Command blocks are not enabled on this server=

View File

@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.=Acc
Editing the command block has failed! You can only change the command block in Creative Mode!=La modification du bloc de commandes a échoué! Vous ne pouvez modifier le bloc de commandes qu'en mode créatif! Editing the command block has failed! You can only change the command block in Creative Mode!=La modification du bloc de commandes a échoué! Vous ne pouvez modifier le bloc de commandes qu'en mode créatif!
Editing the command block has failed! The command block is gone.=La modification du bloc de commandes a échoué! Le bloc de commande a disparu. Editing the command block has failed! The command block is gone.=La modification du bloc de commandes a échoué! Le bloc de commande a disparu.
Executes server commands when powered by redstone power=Exécute les commandes du serveur lorsqu'il est alimenté par l'alimentation Redstone Executes server commands when powered by redstone power=Exécute les commandes du serveur lorsqu'il est alimenté par l'alimentation Redstone
Command blocks are not enabled on this server=Les blocks de commandes ne sont pas activés sur ce serveur

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