Compare commits
534 Commits
0.4.dev-20
...
0.4.dev-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3bea1a944e | ||
|
|
3e419ffb38 | ||
|
|
a149c6ecde | ||
|
|
3f18e9a2da | ||
|
|
4b0494062e | ||
|
|
a09d86dd3c | ||
|
|
3ccb0f691b | ||
|
|
1709fd854a | ||
|
|
7bf446f671 | ||
|
|
e4bc76f55c | ||
|
|
81c5e5200b | ||
|
|
9c3830dd35 | ||
|
|
bf8cfce50e | ||
|
|
b235e4d290 | ||
|
|
b8cf6dee3e | ||
|
|
35df1ee253 | ||
|
|
353f9fd43c | ||
|
|
3899f83da8 | ||
|
|
5f3c70061d | ||
|
|
aba7134301 | ||
|
|
d7447cdf9e | ||
|
|
ff8d2bbc36 | ||
|
|
70c98c9972 | ||
|
|
45f32838b9 | ||
|
|
7d6e80a423 | ||
|
|
f3ec1452cd | ||
|
|
29f03756bd | ||
|
|
fe8c5546f0 | ||
|
|
c4315a7afa | ||
|
|
704782c95b | ||
|
|
67059e1932 | ||
|
|
e2ea711136 | ||
|
|
74aa598769 | ||
|
|
747ff7daf8 | ||
|
|
1f670fc688 | ||
|
|
388906ac70 | ||
|
|
49d9745dc4 | ||
|
|
7c15d793ac | ||
|
|
d90cb3511c | ||
|
|
5100272dc3 | ||
|
|
afda9810f1 | ||
|
|
22df8b81b3 | ||
|
|
7a427c9070 | ||
|
|
a35e4bdbda | ||
|
|
0aeb5adb8f | ||
|
|
9c5cc217bf | ||
|
|
24603d7ad3 | ||
|
|
1eac6ff8ff | ||
|
|
8742b3dab2 | ||
|
|
93cdc9b9dc | ||
|
|
8ed74a3429 | ||
|
|
07a5e59ae7 | ||
|
|
f8c2f1cf54 | ||
|
|
b1f043d010 | ||
|
|
251c0c8508 | ||
|
|
3214daca4c | ||
|
|
e4485f5412 | ||
|
|
4eaaa0ec53 | ||
|
|
42323014ea | ||
|
|
c59d139eeb | ||
|
|
2b4d21160f | ||
|
|
e29a5b11e4 | ||
|
|
b58ee690a3 | ||
|
|
d8edd3d0c8 | ||
|
|
1b078efd5f | ||
|
|
e8e73d37fb | ||
|
|
2eec788544 | ||
|
|
dca28b9e12 | ||
|
|
e879c92596 | ||
|
|
7281c68b27 | ||
|
|
d228f1b658 | ||
|
|
2e60593c5b | ||
|
|
531fe10f51 | ||
|
|
454b07455a | ||
|
|
a4dc6f2c76 | ||
|
|
5608f12f9b | ||
|
|
18d8e3acec | ||
|
|
578fc5bb44 | ||
|
|
e8660cfd8e | ||
|
|
6a57eabb14 | ||
|
|
a67540807a | ||
|
|
20c377ca65 | ||
|
|
5436f1c7d5 | ||
|
|
4107390337 | ||
|
|
e74da72b82 | ||
|
|
24953ba974 | ||
|
|
22a5a1fa43 | ||
|
|
7bac62ee7f | ||
|
|
fcda11c6b0 | ||
|
|
66e1cb324c | ||
|
|
a869d23451 | ||
|
|
41f4941b74 | ||
|
|
b22168d3da | ||
|
|
b9b56bac6b | ||
|
|
fa670fa4b5 | ||
|
|
b131a0cf0c | ||
|
|
d7cef8d762 | ||
|
|
4483fc7df3 | ||
|
|
2cd5addc0c | ||
|
|
5bf06efb2a | ||
|
|
5196e309b8 | ||
|
|
bee1adc651 | ||
|
|
f0e7da8a63 | ||
|
|
5bd32eca0f | ||
|
|
491287c0af | ||
|
|
8ecfd88d92 | ||
|
|
b54178bbbd | ||
|
|
67547f74fc | ||
|
|
56ba193c77 | ||
|
|
d5594e431c | ||
|
|
7bfa2d4da6 | ||
|
|
4cf00f5698 | ||
|
|
a18326e97a | ||
|
|
36c9463467 | ||
|
|
13159c1a48 | ||
|
|
0fbef74f31 | ||
|
|
52122c342d | ||
|
|
96ee73f790 | ||
|
|
dc70f50b59 | ||
|
|
e297c73913 | ||
|
|
280e1a2512 | ||
|
|
1518b8f753 | ||
|
|
5403b1cf6d | ||
|
|
29110d5428 | ||
|
|
462003363f | ||
|
|
b494324ec3 | ||
|
|
4cee9a86ac | ||
|
|
7cad0a2dcd | ||
|
|
ed1ff06867 | ||
|
|
80a64341f0 | ||
|
|
bbf3eebb1a | ||
|
|
6b20ea0752 | ||
|
|
3241ad3ae8 | ||
|
|
9e7ccedba4 | ||
|
|
b9ffb5f30d | ||
|
|
9d456ca87a | ||
|
|
18350ad37f | ||
|
|
0983f65da7 | ||
|
|
42bbd5c9ae | ||
|
|
92ae11bd3b | ||
|
|
443f45eca1 | ||
|
|
a9ddbb4beb | ||
|
|
f8c3743991 | ||
|
|
072c265c30 | ||
|
|
440e9cdbef | ||
|
|
ace005bf7c | ||
|
|
75821c6889 | ||
|
|
d376148ca1 | ||
|
|
582ca33507 | ||
|
|
a6ca7eb29d | ||
|
|
02c035c548 | ||
|
|
418041d906 | ||
|
|
a3a400992e | ||
|
|
68625b047f | ||
|
|
9a1df7bf38 | ||
|
|
81b9cfdfa4 | ||
|
|
ae7aa65069 | ||
|
|
9e0f969b8b | ||
|
|
14a8fa4d68 | ||
|
|
07e5c9bd5f | ||
|
|
49c2ca0216 | ||
|
|
04172e3dd0 | ||
|
|
2c56a9f588 | ||
|
|
20e025b3d8 | ||
|
|
10591d2080 | ||
|
|
af29c0ade5 | ||
|
|
4c876ac62e | ||
|
|
66bf7b0b01 | ||
|
|
17d51a1609 | ||
|
|
0a59605e05 | ||
|
|
202658678d | ||
|
|
4f01db256f | ||
|
|
c04f4a7d73 | ||
|
|
f5e46ba7fc | ||
|
|
8609af54fc | ||
|
|
9a4ef87859 | ||
|
|
a57f4c23d8 | ||
|
|
d629f4d2fb | ||
|
|
6f20a73782 | ||
|
|
8cb7badd63 | ||
|
|
0f3c2f6541 | ||
|
|
56496ad5d8 | ||
|
|
e15dca2a9f | ||
|
|
a32706bc26 | ||
|
|
bdcca4767c | ||
|
|
38f4dbfb51 | ||
|
|
a374b1a6a3 | ||
|
|
0ff94978f5 | ||
|
|
fa24e6b995 | ||
|
|
37b64ff616 | ||
|
|
a2fd8d1db1 | ||
|
|
684b004751 | ||
|
|
cbe11fc7aa | ||
|
|
d01387a82f | ||
|
|
862d76b617 | ||
|
|
bd9912213f | ||
|
|
814ada538a | ||
|
|
53f7eef052 | ||
|
|
405347769a | ||
|
|
5b31d32da8 | ||
|
|
dcef5183f7 | ||
|
|
728d01ef4b | ||
|
|
0557df8d06 | ||
|
|
3a9753b85f | ||
|
|
8e6ac5c263 | ||
|
|
188b303991 | ||
|
|
836595313c | ||
|
|
6779036d25 | ||
|
|
4fb6c07535 | ||
|
|
f01c988094 | ||
|
|
677456d319 | ||
|
|
f022af66da | ||
|
|
98c40f5ee6 | ||
|
|
db0928add3 | ||
|
|
a9a923e4da | ||
|
|
1cac1de3b2 | ||
|
|
524c78a8d6 | ||
|
|
e71262463f | ||
|
|
26666bb36f | ||
|
|
f801e16b78 | ||
|
|
4bf5065a9c | ||
|
|
04085cad3c | ||
|
|
c8997e48c0 | ||
|
|
77621568fd | ||
|
|
601d1936c9 | ||
|
|
06e93f8d95 | ||
|
|
74780134f2 | ||
|
|
93219e3b9d | ||
|
|
77120a021d | ||
|
|
6c14025b2d | ||
|
|
e53794868e | ||
|
|
8c2f3bb378 | ||
|
|
0ac2ce7dea | ||
|
|
c301e3c82a | ||
|
|
9dd78a8a45 | ||
|
|
ede1674d6a | ||
|
|
c3f2b24a9a | ||
|
|
b91bba1ab2 | ||
|
|
fbc22f91d5 | ||
|
|
424b36d469 | ||
|
|
8070f9485b | ||
|
|
c353709f7e | ||
|
|
c13691a8e6 | ||
|
|
2671b9af1b | ||
|
|
7d0ad0f521 | ||
|
|
9bd75d5668 | ||
|
|
fde676a43a | ||
|
|
2469ce6067 | ||
|
|
ef0ec31554 | ||
|
|
da4f51332f | ||
|
|
194258b479 | ||
|
|
fa416e7116 | ||
|
|
71b2e0e002 | ||
|
|
7d1ac4d1f6 | ||
|
|
2f2ef80ec2 | ||
|
|
c0530921ff | ||
|
|
94f1ab4da3 | ||
|
|
3f75b748cf | ||
|
|
8181b68531 | ||
|
|
2de91f11fb | ||
|
|
50621ffe85 | ||
|
|
db4911f956 | ||
|
|
2a325de7aa | ||
|
|
b9cc0a7976 | ||
|
|
97b693052c | ||
|
|
19ed3bb193 | ||
|
|
895b970a10 | ||
|
|
1f56d71f19 | ||
|
|
1ff20da5b6 | ||
|
|
5ef78cd815 | ||
|
|
9101b680c0 | ||
|
|
d24c56fd4b | ||
|
|
77d09552ae | ||
|
|
dbaccff476 | ||
|
|
dc6cf5cdee | ||
|
|
fb3ac49335 | ||
|
|
c54a40df06 | ||
|
|
9c4f68e174 | ||
|
|
4ee4dfdc13 | ||
|
|
2e0c0e9d89 | ||
|
|
db5db587be | ||
|
|
569fca5308 | ||
|
|
b409803527 | ||
|
|
99d257ae8b | ||
|
|
2f2b7915ea | ||
|
|
c1cfcb1577 | ||
|
|
2e90ed07ac | ||
|
|
58bed83d03 | ||
|
|
54917e3062 | ||
|
|
81385682c8 | ||
|
|
807a0d313b | ||
|
|
f9a66c5d46 | ||
|
|
60add387e3 | ||
|
|
ca0fd4173c | ||
|
|
4aa0f040fb | ||
|
|
5957fed9a7 | ||
|
|
6298878bfa | ||
|
|
899004207d | ||
|
|
2b200d481f | ||
|
|
8551ddc839 | ||
|
|
eea3277b81 | ||
|
|
11b86f8d8a | ||
|
|
71a3c2fcd1 | ||
|
|
4ff36696ea | ||
|
|
800d3b4ee7 | ||
|
|
a0b2c7ba25 | ||
|
|
64232f0aec | ||
|
|
591527d878 | ||
|
|
82073025cc | ||
|
|
2c9bb06516 | ||
|
|
18c4a90101 | ||
|
|
5a8ee4889d | ||
|
|
ea1fdf3201 | ||
|
|
2e61008fd9 | ||
|
|
eafde7186f | ||
|
|
a72dc388c3 | ||
|
|
618314985d | ||
|
|
d1d83d7e7f | ||
|
|
bcaab74f1f | ||
|
|
1b670a293b | ||
|
|
45f78bdf40 | ||
|
|
54eca4e736 | ||
|
|
3da05a09b5 | ||
|
|
f79082a46d | ||
|
|
e71d75ed9a | ||
|
|
a4a35f659b | ||
|
|
9eba6a349f | ||
|
|
6a1b6d0344 | ||
|
|
7f7fb9750d | ||
|
|
df190b8f87 | ||
|
|
af33b3b338 | ||
|
|
a87d19cd7e | ||
|
|
611fe41588 | ||
|
|
8b6cce18cb | ||
|
|
d330430336 | ||
|
|
37b2bc3c0c | ||
|
|
f49914dd17 | ||
|
|
f1d9880006 | ||
|
|
6ec447a1aa | ||
|
|
b485fac33e | ||
|
|
98404ad8ea | ||
|
|
e1f5227304 | ||
|
|
2de8f915f8 | ||
|
|
967f25461b | ||
|
|
0053651814 | ||
|
|
7d36833bd4 | ||
|
|
1bbfd0b6d2 | ||
|
|
4547ace59a | ||
|
|
d74659254b | ||
|
|
55d310b05a | ||
|
|
15da308c2a | ||
|
|
e80bc6ef58 | ||
|
|
d81e783665 | ||
|
|
030b63c3d2 | ||
|
|
f3dba05143 | ||
|
|
1020707918 | ||
|
|
c89d1cf072 | ||
|
|
9c5e422d3a | ||
|
|
5e00141005 | ||
|
|
fa70413c82 | ||
|
|
06d2bc7fbd | ||
|
|
1ae9e0afa1 | ||
|
|
f9da2c9507 | ||
|
|
989aba1966 | ||
|
|
6b7d6c27ee | ||
|
|
8db89b8136 | ||
|
|
8c01ad8a9d | ||
|
|
f60a5ec08f | ||
|
|
501b8fe743 | ||
|
|
e9cdb938fe | ||
|
|
f1cb91cd93 | ||
|
|
910186905f | ||
|
|
07ed57476f | ||
|
|
0b21618a05 | ||
|
|
b49a7c140e | ||
|
|
562ac3bce9 | ||
|
|
f21291211c | ||
|
|
d834d6e074 | ||
|
|
11716825fc | ||
|
|
0309021359 | ||
|
|
14a71590c3 | ||
|
|
a5f6d65c37 | ||
|
|
79326e6287 | ||
|
|
c8ec711503 | ||
|
|
0f8b91bfba | ||
|
|
b7fd3c8669 | ||
|
|
b3f4cbe157 | ||
|
|
d0491ce8b6 | ||
|
|
806f10524f | ||
|
|
50110e00e8 | ||
|
|
3a89c40e26 | ||
|
|
ff678d1607 | ||
|
|
abab3db23d | ||
|
|
496451c164 | ||
|
|
993821a924 | ||
|
|
ad5ac22442 | ||
|
|
94b25685c5 | ||
|
|
88cdd3a363 | ||
|
|
e15de8b70d | ||
|
|
61016962ee | ||
|
|
a1eb2836c0 | ||
|
|
64af6d3afe | ||
|
|
365f7a5bfe | ||
|
|
796009ef21 | ||
|
|
b85b4ede82 | ||
|
|
2cb96d9d68 | ||
|
|
78bf92175a | ||
|
|
0c3d39357b | ||
|
|
0e8bd531c2 | ||
|
|
ac69a3561a | ||
|
|
24b1008d56 | ||
|
|
a4340c330a | ||
|
|
2e8e9ee7f5 | ||
|
|
cb05a28745 | ||
|
|
a387c9b95d | ||
|
|
0a426f3592 | ||
|
|
00bc9a8678 | ||
|
|
c241902b40 | ||
|
|
4799a8f761 | ||
|
|
02b334a679 | ||
|
|
b4dd5d3bd7 | ||
|
|
1efdc36b22 | ||
|
|
157a4cf18c | ||
|
|
f22c73f501 | ||
|
|
c920df748b | ||
|
|
a58d725569 | ||
|
|
6a76c226e1 | ||
|
|
569156b013 | ||
|
|
6d4bc012f0 | ||
|
|
2f5c28aaf1 | ||
|
|
4f2c1e36a1 | ||
|
|
bc743ca7ce | ||
|
|
f9d7e399b2 | ||
|
|
3e6f824e6c | ||
|
|
6286c555d4 | ||
|
|
4630281318 | ||
|
|
cd0019acd2 | ||
|
|
e82a76e438 | ||
|
|
ab57fbe4ca | ||
|
|
56f55ab1af | ||
|
|
2445cbbbdc | ||
|
|
48131bf988 | ||
|
|
2b9596fe9b | ||
|
|
0e1f448b61 | ||
|
|
ff82b95800 | ||
|
|
49b7055cb3 | ||
|
|
cb88f7b6d4 | ||
|
|
9425fb8192 | ||
|
|
e48ccd7943 | ||
|
|
6be5441176 | ||
|
|
d5ba7ebaf0 | ||
|
|
270a482740 | ||
|
|
e0b4890794 | ||
|
|
247e8b6e5d | ||
|
|
b760e2ba23 | ||
|
|
103173fc9b | ||
|
|
70ed371d0c | ||
|
|
81d3485109 | ||
|
|
7b7b68cdab | ||
|
|
135a65e200 | ||
|
|
123529e5eb | ||
|
|
e81989a0d8 | ||
|
|
1c15f53318 | ||
|
|
7937813c98 | ||
|
|
ad4040d982 | ||
|
|
69579306dd | ||
|
|
bd21f00f0a | ||
|
|
012bcbcb48 | ||
|
|
e06d4555bf | ||
|
|
abd106bacb | ||
|
|
008de2fb8f | ||
|
|
2e67fa3e48 | ||
|
|
ea36951bc4 | ||
|
|
09c48b60bd | ||
|
|
4cc117ddf6 | ||
|
|
ceaf8edade | ||
|
|
520200d597 | ||
|
|
ab67985d21 | ||
|
|
bc5cc638fc | ||
|
|
bff8be8b76 | ||
|
|
3e95b8a158 | ||
|
|
e8539d4dae | ||
|
|
1907b31da7 | ||
|
|
6145a135bd | ||
|
|
97c3bc408b | ||
|
|
a00e908f52 | ||
|
|
4ad8891e05 | ||
|
|
2b8b2a4f30 | ||
|
|
5c24450e54 | ||
|
|
3a689a5c4f | ||
|
|
44e36d9aad | ||
|
|
62f7f72d20 | ||
|
|
829c632511 | ||
|
|
8730dfb1f9 | ||
|
|
6764365994 | ||
|
|
8addbc9655 | ||
|
|
658d1a7235 | ||
|
|
4b00d4d9d2 | ||
|
|
6a5829788e | ||
|
|
03074cd23e | ||
|
|
2620e8eada | ||
|
|
9b5e676ffa | ||
|
|
fd1ef11617 | ||
|
|
9fa567a6ce | ||
|
|
fc6c00cbe1 | ||
|
|
66f90a6101 | ||
|
|
1fe5c58d56 | ||
|
|
f23616acaf | ||
|
|
7d37913ea4 | ||
|
|
ac56053c74 | ||
|
|
d566ffaa5f | ||
|
|
d06d7cb9a4 | ||
|
|
e494b5d422 | ||
|
|
fdf7b3bcdf | ||
|
|
871e6c0c73 | ||
|
|
392485aa45 | ||
|
|
275a348b75 | ||
|
|
189689716c | ||
|
|
3965d432ca | ||
|
|
746b960c0d | ||
|
|
760416b81f | ||
|
|
1c785c32ef | ||
|
|
cd608b1877 | ||
|
|
c6dd75ccfb | ||
|
|
6b2023dc3e | ||
|
|
2f4a92d701 | ||
|
|
324c544922 | ||
|
|
fbbbcf97d8 | ||
|
|
d96cd236f3 | ||
|
|
581f950e10 | ||
|
|
9344816bd6 | ||
|
|
67c21fc42f | ||
|
|
c2d266efc6 | ||
|
|
ec1859b095 |
42
.gitignore
vendored
@@ -1,5 +1,29 @@
|
|||||||
map/*
|
## Generic ignorable patterns and files
|
||||||
world/*
|
*~
|
||||||
|
.*.swp
|
||||||
|
*bak*
|
||||||
|
tags
|
||||||
|
*.vim
|
||||||
|
|
||||||
|
## Non-static Minetest directories
|
||||||
|
/bin/
|
||||||
|
/games/*
|
||||||
|
!/games/minimal/
|
||||||
|
/cache/
|
||||||
|
/textures/
|
||||||
|
/sounds/
|
||||||
|
/mods/*
|
||||||
|
!/mods/minetest/
|
||||||
|
/mods/minetest/*
|
||||||
|
!/mods/minetest/mods_here.txt
|
||||||
|
/worlds/
|
||||||
|
/world/
|
||||||
|
|
||||||
|
## Configuration/log files
|
||||||
|
minetest.conf
|
||||||
|
debug.txt
|
||||||
|
|
||||||
|
## Build files
|
||||||
CMakeFiles/*
|
CMakeFiles/*
|
||||||
src/CMakeFiles/*
|
src/CMakeFiles/*
|
||||||
src/Makefile
|
src/Makefile
|
||||||
@@ -9,19 +33,13 @@ src/jthread/CMakeFiles/*
|
|||||||
src/jthread/Makefile
|
src/jthread/Makefile
|
||||||
src/jthread/cmake_config.h
|
src/jthread/cmake_config.h
|
||||||
src/jthread/cmake_install.cmake
|
src/jthread/cmake_install.cmake
|
||||||
.*.swp
|
src/jthread/libjthread.a
|
||||||
minetest.conf
|
src/lua/build/
|
||||||
bin/
|
src/lua/CMakeFiles/
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CPackConfig.cmake
|
CPackConfig.cmake
|
||||||
CPackSourceConfig.cmake
|
CPackSourceConfig.cmake
|
||||||
Makefile
|
Makefile
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
src/jthread/libjthread.a
|
|
||||||
debug.txt
|
|
||||||
bin/debug.txt
|
|
||||||
minetestmapper/map.png
|
|
||||||
locale/
|
locale/
|
||||||
src/lua/build/
|
|
||||||
src/lua/CMakeFiles/
|
|
||||||
*bak*
|
|
||||||
|
|||||||
25
.hgignore
@@ -1,25 +0,0 @@
|
|||||||
map/*
|
|
||||||
world/*
|
|
||||||
CMakeFiles/*
|
|
||||||
src/CMakeFiles/*
|
|
||||||
src/Makefile
|
|
||||||
src/cmake_config.h
|
|
||||||
src/cmake_install.cmake
|
|
||||||
src/jthread/CMakeFiles/*
|
|
||||||
src/jthread/Makefile
|
|
||||||
src/jthread/cmake_config.h
|
|
||||||
src/jthread/cmake_install.cmake
|
|
||||||
src/.*.swp
|
|
||||||
src/sqlite/libsqlite3.a
|
|
||||||
src/session.vim
|
|
||||||
util/uloste.png
|
|
||||||
minetest.conf
|
|
||||||
debug.txt
|
|
||||||
bin/
|
|
||||||
CMakeCache.txt
|
|
||||||
CPackConfig.cmake
|
|
||||||
CPackSourceConfig.cmake
|
|
||||||
Makefile
|
|
||||||
cmake_install.cmake
|
|
||||||
src/jthread/libjthread.a
|
|
||||||
data_temp/*
|
|
||||||
@@ -7,10 +7,15 @@ endif(${CMAKE_VERSION} STREQUAL "2.8.2")
|
|||||||
# This can be read from ${PROJECT_NAME} after project() is called
|
# This can be read from ${PROJECT_NAME} after project() is called
|
||||||
project(minetest)
|
project(minetest)
|
||||||
|
|
||||||
|
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||||
|
|
||||||
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
|
# Also remember to set PROTOCOL_VERSION in clientserver.h when releasing
|
||||||
set(VERSION_MAJOR 0)
|
set(VERSION_MAJOR 0)
|
||||||
set(VERSION_MINOR 4)
|
set(VERSION_MINOR 4)
|
||||||
set(VERSION_PATCH dev-20111202-1)
|
set(VERSION_PATCH dev-20120603)
|
||||||
|
if(VERSION_EXTRA)
|
||||||
|
set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA})
|
||||||
|
endif()
|
||||||
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||||
|
|
||||||
MESSAGE(STATUS "*** Will build version ${VERSION_STRING} ***")
|
MESSAGE(STATUS "*** Will build version ${VERSION_STRING} ***")
|
||||||
@@ -49,26 +54,68 @@ find_package(Irrlicht)
|
|||||||
#
|
#
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(DATADIR "data")
|
set(SHAREDIR ".")
|
||||||
set(BINDIR "bin")
|
set(BINDIR "bin")
|
||||||
set(DOCDIR "doc")
|
set(DOCDIR "doc")
|
||||||
set(EXAMPLE_CONF_DIR ".")
|
set(EXAMPLE_CONF_DIR ".")
|
||||||
|
set(LOCALEDIR "locale")
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
# random placeholders
|
# Random placeholders; this isn't usually used and may not work
|
||||||
set(DATADIR "share/${PROJECT_NAME}")
|
# See https://github.com/toabi/minetest-mac/
|
||||||
|
set(SHAREDIR "share/${PROJECT_NAME}")
|
||||||
set(BINDIR "bin")
|
set(BINDIR "bin")
|
||||||
set(DOCDIR "share/doc/${PROJECT_NAME}")
|
set(DOCDIR "share/doc/${PROJECT_NAME}")
|
||||||
set(EXAMPLE_CONF_DIR ".")
|
set(EXAMPLE_CONF_DIR ${DOCDIR})
|
||||||
|
set(LOCALEDIR "locale")
|
||||||
elseif(UNIX) # Linux, BSD etc
|
elseif(UNIX) # Linux, BSD etc
|
||||||
set(DATADIR "share/${PROJECT_NAME}")
|
if(RUN_IN_PLACE)
|
||||||
set(BINDIR "bin")
|
set(SHAREDIR ".")
|
||||||
set(DOCDIR "share/doc/${PROJECT_NAME}")
|
set(BINDIR "bin")
|
||||||
set(EXAMPLE_CONF_DIR "share/doc/${PROJECT_NAME}")
|
set(DOCDIR "doc")
|
||||||
|
set(EXAMPLE_CONF_DIR ".")
|
||||||
|
set(MANDIR "unix/man")
|
||||||
|
set(XDG_APPS_DIR "unix/applications")
|
||||||
|
set(ICONDIR "unix/icons")
|
||||||
|
set(LOCALEDIR "locale")
|
||||||
|
else()
|
||||||
|
set(SHAREDIR "share/${PROJECT_NAME}")
|
||||||
|
set(BINDIR "bin")
|
||||||
|
set(DOCDIR "share/doc/${PROJECT_NAME}")
|
||||||
|
set(MANDIR "share/man")
|
||||||
|
set(EXAMPLE_CONF_DIR ${DOCDIR})
|
||||||
|
set(XDG_APPS_DIR "share/applications")
|
||||||
|
set(ICONDIR "share/icons")
|
||||||
|
set(LOCALEDIR "share/locale")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}")
|
||||||
|
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games/minimal" DESTINATION "${SHAREDIR}/games")
|
||||||
|
set(MINETEST_GAME_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/games/minetest_game")
|
||||||
|
if(EXISTS ${MINETEST_GAME_SOURCE} AND IS_DIRECTORY ${MINETEST_GAME_SOURCE})
|
||||||
|
install(FILES ${MINETEST_GAME_SOURCE}/game.conf DESTINATION "${SHAREDIR}/games/minetest_game/")
|
||||||
|
install(FILES ${MINETEST_GAME_SOURCE}/README.txt DESTINATION "${SHAREDIR}/games/minetest_game/")
|
||||||
|
install(DIRECTORY ${MINETEST_GAME_SOURCE}/mods DESTINATION "${SHAREDIR}/games/minetest_game")
|
||||||
|
endif()
|
||||||
|
if(BUILD_CLIENT)
|
||||||
|
#install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/sounds/base/pack" DESTINATION "${SHAREDIR}/sounds/base")
|
||||||
|
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/textures/base/pack" DESTINATION "${SHAREDIR}/textures/base")
|
||||||
|
endif()
|
||||||
|
if(RUN_IN_PLACE)
|
||||||
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/mods/minetest/mods_here.txt" DESTINATION "${SHAREDIR}/mods/minetest")
|
||||||
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/textures/all/textures_here.txt" DESTINATION "${SHAREDIR}/textures/all")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
install(FILES "README.txt" DESTINATION "${DOCDIR}")
|
install(FILES "README.txt" DESTINATION "${DOCDIR}")
|
||||||
install(FILES "doc/changelog.txt" DESTINATION "${DOCDIR}")
|
install(FILES "doc/lua_api.txt" DESTINATION "${DOCDIR}")
|
||||||
install(FILES "minetest.conf.example" DESTINATION "${DOCDIR}")
|
install(FILES "doc/mapformat.txt" DESTINATION "${DOCDIR}")
|
||||||
|
install(FILES "minetest.conf.example" DESTINATION "${EXAMPLE_CONF_DIR}")
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
install(FILES "doc/minetest.6" "doc/minetestserver.6" DESTINATION "${MANDIR}/man6")
|
||||||
|
install(FILES "misc/minetest.desktop" DESTINATION "${XDG_APPS_DIR}")
|
||||||
|
install(FILES "misc/minetest-icon.svg" DESTINATION "${ICONDIR}/hicolor/scalable/apps")
|
||||||
|
endif()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Subdirectories
|
# Subdirectories
|
||||||
|
|||||||
167
README.txt
@@ -1,50 +1,75 @@
|
|||||||
Minetest-c55
|
Minetest-c55
|
||||||
---------------
|
============
|
||||||
An InfiniMiner/Minecraft inspired game.
|
|
||||||
Copyright (c) 2010-2011 Perttu Ahola <celeron55@gmail.com>
|
|
||||||
(see source files for other contributors)
|
|
||||||
|
|
||||||
Further documentation:
|
An InfiniMiner/Minecraft inspired game.
|
||||||
|
|
||||||
|
Copyright (c) 2010-2012 Perttu Ahola <celeron55@gmail.com>
|
||||||
|
and ther contributors (see source file comments and the version control log)
|
||||||
|
|
||||||
|
In case you downloaded the source code:
|
||||||
|
---------------------------------------
|
||||||
|
If you downloaded the Minetest Engine source code in which this file is
|
||||||
|
contained, you probably want to download the minetest_game project too:
|
||||||
|
https://github.com/celeron55/minetest_game/
|
||||||
|
See the README.txt in it.
|
||||||
|
|
||||||
|
Further documentation
|
||||||
----------------------
|
----------------------
|
||||||
- Website: http://celeron.55.lt/~celeron55/minetest/
|
- Website: http://c55.me/minetest/
|
||||||
- Wiki: http://celeron.55.lt/~celeron55/minetest/wiki/
|
- Wiki: http://c55.me/minetest/wiki/
|
||||||
- Forum: http://celeron.55.lt/~celeron55/minetest/forum/
|
- Forum: http://c55.me/minetest/forum/
|
||||||
|
- Github: https://github.com/celeron55/minetest/
|
||||||
- doc/ directory of source distribution
|
- doc/ directory of source distribution
|
||||||
|
|
||||||
This game is not finished:
|
This game is not finished
|
||||||
--------------------------
|
--------------------------
|
||||||
- Don't expect it to work as well as a finished game will.
|
- Don't expect it to work as well as a finished game will.
|
||||||
- Please report any bugs to me. debug.txt is useful.
|
- Please report any bugs. When doing that, debug.txt is useful.
|
||||||
|
|
||||||
Controls:
|
Default Controls
|
||||||
---------
|
-----------------
|
||||||
- See the in-game pause menu
|
- WASD: Move
|
||||||
|
- Space: Jump
|
||||||
|
- E: Go down
|
||||||
|
- Shift: Sneak
|
||||||
|
- Q: Drop item
|
||||||
|
- I: Open inventory
|
||||||
|
- Mouse: Turn/look
|
||||||
- Settable in the configuration file, see the section below.
|
- Settable in the configuration file, see the section below.
|
||||||
|
|
||||||
Map directory:
|
Paths
|
||||||
--------------
|
------
|
||||||
- Map is stored in a directory, which can be removed to generate a new map.
|
$bin - Compiled binaries
|
||||||
- There is a command-line option for it: --map-dir
|
$share - Cistributed read-only data
|
||||||
- For a RUN_IN_PLACE build, it is located in:
|
$user - User-created modifiable data
|
||||||
../world
|
|
||||||
- Otherwise something like this:
|
Windows .zip / RUN_IN_PLACE source:
|
||||||
Windows: C:\Documents and Settings\user\Application Data\minetest\world
|
$bin = bin
|
||||||
Linux: ~/.minetest/world
|
$share = .
|
||||||
OS X: ~/Library/Application Support/minetest/world
|
$user = .
|
||||||
|
|
||||||
|
Linux installed:
|
||||||
|
$bin = /usr/bin
|
||||||
|
$share = /usr/share/minetest
|
||||||
|
$user = ~/.minetest
|
||||||
|
|
||||||
|
OS X:
|
||||||
|
$bin = ?
|
||||||
|
$share = ?
|
||||||
|
$user = ~/Library/Application Support/minetest
|
||||||
|
|
||||||
|
World directory
|
||||||
|
----------------
|
||||||
|
- Worlds can be found as separate folders in:
|
||||||
|
$user/worlds/
|
||||||
|
|
||||||
Configuration file:
|
Configuration file:
|
||||||
-------------------
|
-------------------
|
||||||
- An optional configuration file can be used. See minetest.conf.example.
|
- Default location:
|
||||||
- Path to file can be passed as a parameter to the executable:
|
$user/minetest.conf
|
||||||
|
- It is created by Minetest when it is ran the first time.
|
||||||
|
- A specific file can be specified on the command line:
|
||||||
--config <path-to-file>
|
--config <path-to-file>
|
||||||
- Defaults:
|
|
||||||
- If built with -DRUN_IN_PLACE=1:
|
|
||||||
../minetest.conf
|
|
||||||
../../minetest.conf
|
|
||||||
- Otherwise something like this:
|
|
||||||
Windows: C:\Documents and Settings\user\Application Data\minetest\minetest.conf
|
|
||||||
Linux: ~/.minetest/minetest.conf
|
|
||||||
OS X: ~/Library/Application Support/minetest.conf
|
|
||||||
|
|
||||||
Command-line options:
|
Command-line options:
|
||||||
---------------------
|
---------------------
|
||||||
@@ -54,13 +79,20 @@ Compiling on GNU/Linux:
|
|||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Install dependencies. Here's an example for Debian/Ubuntu:
|
Install dependencies. Here's an example for Debian/Ubuntu:
|
||||||
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev
|
$ apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg8-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev
|
||||||
|
|
||||||
Download source, extract (this is the URL to the latest of source repository, which might not work at all times):
|
Download source, extract (this is the URL to the latest of source repository, which might not work at all times):
|
||||||
$ wget https://github.com/celeron55/minetest/tarball/master -O master.tar.gz
|
$ wget https://github.com/celeron55/minetest/tarball/master -O master.tar.gz
|
||||||
$ tar xf master.tar.gz
|
$ tar xf master.tar.gz
|
||||||
$ cd celeron55-minetest-286edd4 (or similar)
|
$ cd celeron55-minetest-286edd4 (or similar)
|
||||||
|
|
||||||
|
Download minetest_game (otherwise only the "Minimal development test" game is available)
|
||||||
|
$ cd games/
|
||||||
|
$ wget https://github.com/celeron55/minetest_game/tarball/master -O master.tar.gz
|
||||||
|
$ tar xf master.tar.gz
|
||||||
|
$ mv celeron55-minetest_game-* minetest_game
|
||||||
|
$ cd ..
|
||||||
|
|
||||||
Build a version that runs directly from the source directory:
|
Build a version that runs directly from the source directory:
|
||||||
$ cmake . -DRUN_IN_PLACE=1
|
$ cmake . -DRUN_IN_PLACE=1
|
||||||
$ make -j2
|
$ make -j2
|
||||||
@@ -77,6 +109,9 @@ $ ./minetest
|
|||||||
|
|
||||||
Compiling on Windows:
|
Compiling on Windows:
|
||||||
---------------------
|
---------------------
|
||||||
|
- This section is outdated. In addition to what is described here:
|
||||||
|
- In addition to minetest, you need to download minetest_game.
|
||||||
|
- If you wish to have sound support, you need libogg, libvorbis and libopenal
|
||||||
|
|
||||||
- You need:
|
- You need:
|
||||||
* CMake:
|
* CMake:
|
||||||
@@ -94,12 +129,13 @@ Compiling on Windows:
|
|||||||
http://gnuwin32.sourceforge.net/downlinks/gettext.php
|
http://gnuwin32.sourceforge.net/downlinks/gettext.php
|
||||||
- This is used for other UI languages. Feel free to leave it out.
|
- This is used for other UI languages. Feel free to leave it out.
|
||||||
* And, of course, Minetest-c55:
|
* And, of course, Minetest-c55:
|
||||||
http://celeron.55.lt/~celeron55/minetest/download
|
http://c55.me/minetest/download
|
||||||
- Steps:
|
- Steps:
|
||||||
- Select a directory called DIR hereafter in which you will operate.
|
- Select a directory called DIR hereafter in which you will operate.
|
||||||
- Make sure you have CMake and a compiler installed.
|
- Make sure you have CMake and a compiler installed.
|
||||||
- Download all the other stuff to DIR and extract them into there.
|
- Download all the other stuff to DIR and extract them into there.
|
||||||
("extract here", not "extract to packagename/")
|
("extract here", not "extract to packagename/")
|
||||||
|
NOTE: zlib125dll.zip needs to be extracted into zlib125dll
|
||||||
- All those packages contain a nice base directory in them, which
|
- All those packages contain a nice base directory in them, which
|
||||||
should end up being the direct subdirectories of DIR.
|
should end up being the direct subdirectories of DIR.
|
||||||
- You will end up with a directory structure like this (+=dir, -=file):
|
- You will end up with a directory structure like this (+=dir, -=file):
|
||||||
@@ -176,24 +212,37 @@ Compiling on Windows:
|
|||||||
If using MinGW:
|
If using MinGW:
|
||||||
- Using the command line, browse to the build directory and run 'make'
|
- Using the command line, browse to the build directory and run 'make'
|
||||||
(or mingw32-make or whatever it happens to be)
|
(or mingw32-make or whatever it happens to be)
|
||||||
|
- You may need to copy some of the downloaded DLLs into bin/, see what
|
||||||
|
running the produced executable tells you it doesn't have.
|
||||||
- You should now have a working game with the executable in
|
- You should now have a working game with the executable in
|
||||||
DIR/minetest/bin/minetest.exe
|
DIR/minetest/bin/minetest.exe
|
||||||
|
|
||||||
Windows releases of minetest are built using a bat script like this:
|
Windows releases of minetest are built using a bat script like this:
|
||||||
--------------------------------------------------------------------
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
|
set sourcedir=%CD%
|
||||||
set installpath="C:\tmp\minetest_install"
|
set installpath="C:\tmp\minetest_install"
|
||||||
set irrlichtpath="C:\tmp\irrlicht-1.7.2"
|
set irrlichtpath="C:\tmp\irrlicht-1.7.2"
|
||||||
|
|
||||||
set sourcedir=%CD%
|
|
||||||
set builddir=%sourcedir%\bvc10
|
set builddir=%sourcedir%\bvc10
|
||||||
mkdir %builddir%
|
mkdir %builddir%
|
||||||
pushd %builddir%
|
pushd %builddir%
|
||||||
cmake %sourcedir% -G "Visual Studio 10" -DIRRLICHT_SOURCE_DIR=%irrlichtpath% -DRUN_IN_PLACE=1 -DCMAKE_INSTALL_PREFIX=%installpath%
|
cmake %sourcedir% -G "Visual Studio 10" -DIRRLICHT_SOURCE_DIR=%irrlichtpath% -DRUN_IN_PLACE=1 -DCMAKE_INSTALL_PREFIX=%installpath%
|
||||||
|
if %errorlevel% neq 0 goto fail
|
||||||
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration=Release
|
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration=Release
|
||||||
|
if %errorlevel% neq 0 goto fail
|
||||||
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" INSTALL.vcxproj /p:Configuration=Release
|
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" INSTALL.vcxproj /p:Configuration=Release
|
||||||
|
if %errorlevel% neq 0 goto fail
|
||||||
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" PACKAGE.vcxproj /p:Configuration=Release
|
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" PACKAGE.vcxproj /p:Configuration=Release
|
||||||
|
if %errorlevel% neq 0 goto fail
|
||||||
popd
|
popd
|
||||||
|
echo Finished.
|
||||||
|
exit /b 0
|
||||||
|
|
||||||
|
:fail
|
||||||
|
popd
|
||||||
|
echo Failed.
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
License of Minetest-c55 textures and sounds
|
License of Minetest-c55 textures and sounds
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
@@ -276,4 +325,50 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
IN THE SOFTWARE.
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Lua
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Lua is licensed under the terms of the MIT license reproduced below.
|
||||||
|
This means that Lua is free software and can be used for both academic
|
||||||
|
and commercial purposes at absolutely no cost.
|
||||||
|
|
||||||
|
For details and rationale, see http://www.lua.org/license.html .
|
||||||
|
|
||||||
|
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
Fonts
|
||||||
|
---------------
|
||||||
|
|
||||||
|
DejaVu Sans Mono:
|
||||||
|
|
||||||
|
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
||||||
|
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
||||||
|
|
||||||
|
Bitstream Vera Fonts Copyright:
|
||||||
|
|
||||||
|
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
||||||
|
a trademark of Bitstream, Inc.
|
||||||
|
|
||||||
|
Arev Fonts Copyright:
|
||||||
|
|
||||||
|
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
188
builtin/auth.lua
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
-- Minetest: builtin/auth.lua
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Authentication handler
|
||||||
|
--
|
||||||
|
|
||||||
|
function minetest.string_to_privs(str, delim)
|
||||||
|
assert(type(str) == "string")
|
||||||
|
delim = delim or ','
|
||||||
|
privs = {}
|
||||||
|
for _, priv in pairs(string.split(str, delim)) do
|
||||||
|
privs[priv:trim()] = true
|
||||||
|
end
|
||||||
|
return privs
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.privs_to_string(privs, delim)
|
||||||
|
assert(type(privs) == "table")
|
||||||
|
delim = delim or ','
|
||||||
|
list = {}
|
||||||
|
for priv, bool in pairs(privs) do
|
||||||
|
if bool then
|
||||||
|
table.insert(list, priv)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.concat(list, delim)
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(minetest.string_to_privs("a,b").b == true)
|
||||||
|
assert(minetest.privs_to_string({a=true,b=true}) == "a,b")
|
||||||
|
|
||||||
|
minetest.auth_file_path = minetest.get_worldpath().."/auth.txt"
|
||||||
|
minetest.auth_table = {}
|
||||||
|
|
||||||
|
local function read_auth_file()
|
||||||
|
local newtable = {}
|
||||||
|
local file, errmsg = io.open(minetest.auth_file_path, 'rb')
|
||||||
|
if not file then
|
||||||
|
minetest.log("info", minetest.auth_file_path.." could not be opened for reading ("..errmsg.."); assuming new world")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for line in file:lines() do
|
||||||
|
if line ~= "" then
|
||||||
|
local name, password, privilegestring = string.match(line, "([^:]*):([^:]*):([^:]*)")
|
||||||
|
if not name or not password or not privilegestring then
|
||||||
|
error("Invalid line in auth.txt: "..dump(line))
|
||||||
|
end
|
||||||
|
local privileges = minetest.string_to_privs(privilegestring)
|
||||||
|
newtable[name] = {password=password, privileges=privileges}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
io.close(file)
|
||||||
|
minetest.auth_table = newtable
|
||||||
|
minetest.notify_authentication_modified()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function save_auth_file()
|
||||||
|
local newtable = {}
|
||||||
|
-- Check table for validness before attempting to save
|
||||||
|
for name, stuff in pairs(minetest.auth_table) do
|
||||||
|
assert(type(name) == "string")
|
||||||
|
assert(name ~= "")
|
||||||
|
assert(type(stuff) == "table")
|
||||||
|
assert(type(stuff.password) == "string")
|
||||||
|
assert(type(stuff.privileges) == "table")
|
||||||
|
end
|
||||||
|
local file, errmsg = io.open(minetest.auth_file_path, 'w+b')
|
||||||
|
if not file then
|
||||||
|
error(minetest.auth_file_path.." could not be opened for writing: "..errmsg)
|
||||||
|
end
|
||||||
|
for name, stuff in pairs(minetest.auth_table) do
|
||||||
|
local privstring = minetest.privs_to_string(stuff.privileges)
|
||||||
|
file:write(name..":"..stuff.password..":"..privstring..'\n')
|
||||||
|
end
|
||||||
|
io.close(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
read_auth_file()
|
||||||
|
|
||||||
|
minetest.builtin_auth_handler = {
|
||||||
|
get_auth = function(name)
|
||||||
|
assert(type(name) == "string")
|
||||||
|
-- Figure out what password to use for a new player (singleplayer
|
||||||
|
-- always has an empty password, otherwise use default, which is
|
||||||
|
-- usually empty too)
|
||||||
|
local new_password_hash = ""
|
||||||
|
-- If not in authentication table, return nil
|
||||||
|
if not minetest.auth_table[name] then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
-- Figure out what privileges the player should have.
|
||||||
|
-- Take a copy of the privilege table
|
||||||
|
local privileges = {}
|
||||||
|
for priv, _ in pairs(minetest.auth_table[name].privileges) do
|
||||||
|
privileges[priv] = true
|
||||||
|
end
|
||||||
|
-- If singleplayer, give all privileges except those marked as give_to_singleplayer = false
|
||||||
|
if minetest.is_singleplayer() then
|
||||||
|
for priv, def in pairs(minetest.registered_privileges) do
|
||||||
|
if def.give_to_singleplayer then
|
||||||
|
privileges[priv] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- For the admin, give everything
|
||||||
|
elseif name == minetest.setting_get("name") then
|
||||||
|
for priv, def in pairs(minetest.registered_privileges) do
|
||||||
|
privileges[priv] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- All done
|
||||||
|
return {
|
||||||
|
password = minetest.auth_table[name].password,
|
||||||
|
privileges = privileges,
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
create_auth = function(name, password)
|
||||||
|
assert(type(name) == "string")
|
||||||
|
assert(type(password) == "string")
|
||||||
|
minetest.log('info', "Built-in authentication handler adding player '"..name.."'")
|
||||||
|
minetest.auth_table[name] = {
|
||||||
|
password = password,
|
||||||
|
privileges = minetest.string_to_privs(minetest.setting_get("default_privs")),
|
||||||
|
}
|
||||||
|
save_auth_file()
|
||||||
|
end,
|
||||||
|
set_password = function(name, password)
|
||||||
|
assert(type(name) == "string")
|
||||||
|
assert(type(password) == "string")
|
||||||
|
if not minetest.auth_table[name] then
|
||||||
|
minetest.builtin_auth_handler.create_auth(name, password)
|
||||||
|
else
|
||||||
|
minetest.log('info', "Built-in authentication handler setting password of player '"..name.."'")
|
||||||
|
minetest.auth_table[name].password = password
|
||||||
|
save_auth_file()
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
set_privileges = function(name, privileges)
|
||||||
|
assert(type(name) == "string")
|
||||||
|
assert(type(privileges) == "table")
|
||||||
|
if not minetest.auth_table[name] then
|
||||||
|
minetest.builtin_auth_handler.create_auth(name, minetest.get_password_hash(name, minetest.setting_get("default_password")))
|
||||||
|
end
|
||||||
|
minetest.auth_table[name].privileges = privileges
|
||||||
|
minetest.notify_authentication_modified(name)
|
||||||
|
save_auth_file()
|
||||||
|
end,
|
||||||
|
reload = function()
|
||||||
|
read_auth_file()
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
function minetest.register_authentication_handler(handler)
|
||||||
|
if minetest.registered_auth_handler then
|
||||||
|
error("Add-on authentication handler already registered by "..minetest.registered_auth_handler_modname)
|
||||||
|
end
|
||||||
|
minetest.registered_auth_handler = handler
|
||||||
|
minetest.registered_auth_handler_modname = minetest.get_current_modname()
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.get_auth_handler()
|
||||||
|
if minetest.registered_auth_handler then
|
||||||
|
return minetest.registered_auth_handler
|
||||||
|
end
|
||||||
|
return minetest.builtin_auth_handler
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.set_player_password(name, password)
|
||||||
|
if minetest.get_auth_handler().set_password then
|
||||||
|
minetest.get_auth_handler().set_password(name, password)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.set_player_privs(name, privs)
|
||||||
|
if minetest.get_auth_handler().set_privileges then
|
||||||
|
minetest.get_auth_handler().set_privileges(name, privs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.auth_reload()
|
||||||
|
if minetest.get_auth_handler().reload then
|
||||||
|
return minetest.get_auth_handler().reload()
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
23
builtin/builtin.lua
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
--
|
||||||
|
-- This file contains built-in stuff in Minetest implemented in Lua.
|
||||||
|
--
|
||||||
|
-- It is always loaded and executed after registration of the C API,
|
||||||
|
-- before loading and running any mods.
|
||||||
|
--
|
||||||
|
|
||||||
|
-- Initialize some very basic things
|
||||||
|
print = minetest.debug
|
||||||
|
math.randomseed(os.time())
|
||||||
|
|
||||||
|
-- Load other files
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/misc_helpers.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/item.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/misc_register.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/item_entity.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/deprecated.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/misc.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/privileges.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/auth.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/chatcommands.lua")
|
||||||
|
dofile(minetest.get_modpath("__builtin").."/static_spawn.lua")
|
||||||
|
|
||||||
353
builtin/chatcommands.lua
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
-- Minetest: builtin/chatcommands.lua
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Chat command handler
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.chatcommands = {}
|
||||||
|
function minetest.register_chatcommand(cmd, def)
|
||||||
|
def = def or {}
|
||||||
|
def.params = def.params or ""
|
||||||
|
def.description = def.description or ""
|
||||||
|
def.privs = def.privs or {}
|
||||||
|
minetest.chatcommands[cmd] = def
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_chat_message(function(name, message)
|
||||||
|
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
|
||||||
|
if not param then
|
||||||
|
param = ""
|
||||||
|
end
|
||||||
|
local cmd_def = minetest.chatcommands[cmd]
|
||||||
|
if cmd_def then
|
||||||
|
if not cmd_def.func then
|
||||||
|
-- This is a C++ command
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
local has_privs, missing_privs = minetest.check_player_privs(name, cmd_def.privs)
|
||||||
|
if has_privs then
|
||||||
|
cmd_def.func(name, param)
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
|
||||||
|
end
|
||||||
|
return true -- handled chat message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Chat commands
|
||||||
|
--
|
||||||
|
|
||||||
|
-- Register C++ commands without functions
|
||||||
|
minetest.register_chatcommand("me", {params = nil, description = "chat action (eg. /me orders a pizza)"})
|
||||||
|
minetest.register_chatcommand("status", {description = "print server status line"})
|
||||||
|
minetest.register_chatcommand("shutdown", {params = "", description = "shutdown server", privs = {server=true}})
|
||||||
|
minetest.register_chatcommand("clearobjects", {params = "", description = "clear all objects in world", privs = {server=true}})
|
||||||
|
minetest.register_chatcommand("time", {params = "<0...24000>", description = "set time of day", privs = {settime=true}})
|
||||||
|
minetest.register_chatcommand("ban", {params = "<name>", description = "ban IP of player", privs = {ban=true}})
|
||||||
|
minetest.register_chatcommand("unban", {params = "<name/ip>", description = "remove IP ban", privs = {ban=true}})
|
||||||
|
|
||||||
|
-- Register other commands
|
||||||
|
minetest.register_chatcommand("help", {
|
||||||
|
privs = {},
|
||||||
|
params = "(nothing)/all/privs/<cmd>",
|
||||||
|
description = "Get help for commands or list privileges",
|
||||||
|
func = function(name, param)
|
||||||
|
local format_help_line = function(cmd, def)
|
||||||
|
local msg = "/"..cmd
|
||||||
|
if def.params and def.params ~= "" then msg = msg .. " " .. def.params end
|
||||||
|
if def.description and def.description ~= "" then msg = msg .. ": " .. def.description end
|
||||||
|
return msg
|
||||||
|
end
|
||||||
|
if param == "" then
|
||||||
|
local msg = ""
|
||||||
|
cmds = {}
|
||||||
|
for cmd, def in pairs(minetest.chatcommands) do
|
||||||
|
if minetest.check_player_privs(name, def.privs) then
|
||||||
|
table.insert(cmds, cmd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(name, "Available commands: "..table.concat(cmds, " "))
|
||||||
|
minetest.chat_send_player(name, "Use '/help <cmd>' to get more information, or '/help all' to list everything.")
|
||||||
|
elseif param == "all" then
|
||||||
|
minetest.chat_send_player(name, "Available commands:")
|
||||||
|
for cmd, def in pairs(minetest.chatcommands) do
|
||||||
|
if minetest.check_player_privs(name, def.privs) then
|
||||||
|
minetest.chat_send_player(name, format_help_line(cmd, def))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif param == "privs" then
|
||||||
|
minetest.chat_send_player(name, "Available privileges:")
|
||||||
|
for priv, def in pairs(minetest.registered_privileges) do
|
||||||
|
minetest.chat_send_player(name, priv..": "..def.description)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local cmd = param
|
||||||
|
def = minetest.chatcommands[cmd]
|
||||||
|
if not def then
|
||||||
|
minetest.chat_send_player(name, "Command not available: "..cmd)
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name, format_help_line(cmd, def))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("privs", {
|
||||||
|
params = "<name>",
|
||||||
|
description = "print out privileges of player",
|
||||||
|
func = function(name, param)
|
||||||
|
if param == "" then
|
||||||
|
param = name
|
||||||
|
else
|
||||||
|
--[[if not minetest.check_player_privs(name, {privs=true}) then
|
||||||
|
minetest.chat_send_player(name, "Privileges of "..param.." are hidden from you.")
|
||||||
|
return
|
||||||
|
end]]
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(name, "Privileges of "..param..": "..minetest.privs_to_string(minetest.get_player_privs(param), ' '))
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("grant", {
|
||||||
|
params = "<name> <privilege>|all",
|
||||||
|
description = "Give privilege to player",
|
||||||
|
privs = {},
|
||||||
|
func = function(name, param)
|
||||||
|
if not minetest.check_player_privs(name, {privs=true}) and
|
||||||
|
not minetest.check_player_privs(name, {basic_privs=true}) then
|
||||||
|
minetest.chat_send_player(name, "Your privileges are insufficient.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)")
|
||||||
|
if not grantname or not grantprivstr then
|
||||||
|
minetest.chat_send_player(name, "Invalid parameters (see /help grant)")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local grantprivs = minetest.string_to_privs(grantprivstr)
|
||||||
|
if grantprivstr == "all" then
|
||||||
|
grantprivs = minetest.registered_privileges
|
||||||
|
end
|
||||||
|
local privs = minetest.get_player_privs(grantname)
|
||||||
|
local privs_known = true
|
||||||
|
for priv, _ in pairs(grantprivs) do
|
||||||
|
if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
|
||||||
|
minetest.chat_send_player(name, "Your privileges are insufficient.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not minetest.registered_privileges[priv] then
|
||||||
|
minetest.chat_send_player(name, "Unknown privilege: "..priv)
|
||||||
|
privs_known = false
|
||||||
|
end
|
||||||
|
privs[priv] = true
|
||||||
|
end
|
||||||
|
if not privs_known then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.set_player_privs(grantname, privs)
|
||||||
|
minetest.chat_send_player(name, "Privileges of "..grantname..": "..minetest.privs_to_string(minetest.get_player_privs(grantname), ' '))
|
||||||
|
if grantname ~= name then
|
||||||
|
minetest.chat_send_player(grantname, name.." granted you privileges: "..minetest.privs_to_string(grantprivs, ' '))
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("revoke", {
|
||||||
|
params = "<name> <privilege>|all",
|
||||||
|
description = "Remove privilege from player",
|
||||||
|
privs = {},
|
||||||
|
func = function(name, param)
|
||||||
|
if not minetest.check_player_privs(name, {privs=true}) and
|
||||||
|
not minetest.check_player_privs(name, {basic_privs=true}) then
|
||||||
|
minetest.chat_send_player(name, "Your privileges are insufficient.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local revokename, revokeprivstr = string.match(param, "([^ ]+) (.+)")
|
||||||
|
if not revokename or not revokeprivstr then
|
||||||
|
minetest.chat_send_player(name, "Invalid parameters (see /help revoke)")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local revokeprivs = minetest.string_to_privs(revokeprivstr)
|
||||||
|
local privs = minetest.get_player_privs(revokename)
|
||||||
|
for priv, _ in pairs(revokeprivs) do
|
||||||
|
if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
|
||||||
|
minetest.chat_send_player(name, "Your privileges are insufficient.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if revokeprivstr == "all" then
|
||||||
|
privs = {}
|
||||||
|
else
|
||||||
|
for priv, _ in pairs(revokeprivs) do
|
||||||
|
privs[priv] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.set_player_privs(revokename, privs)
|
||||||
|
minetest.chat_send_player(name, "Privileges of "..revokename..": "..minetest.privs_to_string(minetest.get_player_privs(revokename), ' '))
|
||||||
|
if revokename ~= name then
|
||||||
|
minetest.chat_send_player(revokename, name.." revoked privileges from you: "..minetest.privs_to_string(revokeprivs, ' '))
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("setpassword", {
|
||||||
|
params = "<name> <password>",
|
||||||
|
description = "set given password",
|
||||||
|
privs = {password=true},
|
||||||
|
func = function(name, param)
|
||||||
|
if param == "" then
|
||||||
|
minetest.chat_send_player(name, "Password field required")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.set_player_password(name, param)
|
||||||
|
minetest.chat_send_player(name, "Password set")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
minetest.register_chatcommand("clearpassword", {
|
||||||
|
params = "<name>",
|
||||||
|
description = "set empty password",
|
||||||
|
privs = {password=true},
|
||||||
|
func = function(name, param)
|
||||||
|
minetest.set_player_password(name, '')
|
||||||
|
minetest.chat_send_player(name, "Password cleared")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("auth_reload", {
|
||||||
|
params = "",
|
||||||
|
description = "reload authentication data",
|
||||||
|
privs = {server=true},
|
||||||
|
func = function(name, param)
|
||||||
|
local done = minetest.auth_reload()
|
||||||
|
if done then
|
||||||
|
minetest.chat_send_player(name, "Done.")
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name, "Failed.")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("teleport", {
|
||||||
|
params = "<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>",
|
||||||
|
description = "teleport to given position",
|
||||||
|
privs = {teleport=true},
|
||||||
|
func = function(name, param)
|
||||||
|
-- Returns (pos, true) if found, otherwise (pos, false)
|
||||||
|
local function find_free_position_near(pos)
|
||||||
|
local tries = {
|
||||||
|
{x=1,y=0,z=0},
|
||||||
|
{x=-1,y=0,z=0},
|
||||||
|
{x=0,y=0,z=1},
|
||||||
|
{x=0,y=0,z=-1},
|
||||||
|
}
|
||||||
|
for _, d in ipairs(tries) do
|
||||||
|
local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z}
|
||||||
|
local n = minetest.env:get_node(p)
|
||||||
|
if not minetest.registered_nodes[n.name].walkable then
|
||||||
|
return p, true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return pos, false
|
||||||
|
end
|
||||||
|
|
||||||
|
local teleportee = nil
|
||||||
|
local p = {}
|
||||||
|
p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||||
|
teleportee = minetest.env:get_player_by_name(name)
|
||||||
|
if teleportee and p.x and p.y and p.z then
|
||||||
|
minetest.chat_send_player(name, "Teleporting to ("..p.x..", "..p.y..", "..p.z..")")
|
||||||
|
teleportee:setpos(p)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local teleportee = nil
|
||||||
|
local p = nil
|
||||||
|
local target_name = nil
|
||||||
|
target_name = string.match(param, "^([^ ]+)$")
|
||||||
|
teleportee = minetest.env:get_player_by_name(name)
|
||||||
|
if target_name then
|
||||||
|
local target = minetest.env:get_player_by_name(target_name)
|
||||||
|
if target then
|
||||||
|
p = target:getpos()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if teleportee and p then
|
||||||
|
p = find_free_position_near(p)
|
||||||
|
minetest.chat_send_player(name, "Teleporting to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
|
||||||
|
teleportee:setpos(p)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if minetest.check_player_privs(name, {bring=true}) then
|
||||||
|
local teleportee = nil
|
||||||
|
local p = {}
|
||||||
|
local teleportee_name = nil
|
||||||
|
teleportee_name, p.x, p.y, p.z = string.match(param, "^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||||
|
if teleportee_name then
|
||||||
|
teleportee = minetest.env:get_player_by_name(teleportee_name)
|
||||||
|
end
|
||||||
|
if teleportee and p.x and p.y and p.z then
|
||||||
|
minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to ("..p.x..", "..p.y..", "..p.z..")")
|
||||||
|
teleportee:setpos(p)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local teleportee = nil
|
||||||
|
local p = nil
|
||||||
|
local teleportee_name = nil
|
||||||
|
local target_name = nil
|
||||||
|
teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$")
|
||||||
|
if teleportee_name then
|
||||||
|
teleportee = minetest.env:get_player_by_name(teleportee_name)
|
||||||
|
end
|
||||||
|
if target_name then
|
||||||
|
local target = minetest.env:get_player_by_name(target_name)
|
||||||
|
if target then
|
||||||
|
p = target:getpos()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if teleportee and p then
|
||||||
|
p = find_free_position_near(p)
|
||||||
|
minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
|
||||||
|
teleportee:setpos(p)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.chat_send_player(name, "Invalid parameters (\""..param.."\") or player not found (see /help teleport)")
|
||||||
|
return
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("set", {
|
||||||
|
params = "[-n] <name> <value> | <name>",
|
||||||
|
description = "set or read server configuration setting",
|
||||||
|
privs = {server=true},
|
||||||
|
func = function(name, param)
|
||||||
|
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
|
||||||
|
if arg and arg == "-n" and setname and setvalue then
|
||||||
|
minetest.setting_set(setname, setvalue)
|
||||||
|
minetest.chat_send_player(name, setname.." = "..setvalue)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local setname, setvalue = string.match(param, "([^ ]+) (.+)")
|
||||||
|
if setname and setvalue then
|
||||||
|
if not minetest.setting_get(setname) then
|
||||||
|
minetest.chat_send_player(name, "Failed. Use '/set -n <name> <value>' to create a new setting.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.setting_set(setname, setvalue)
|
||||||
|
minetest.chat_send_player(name, setname.." = "..setvalue)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local setname = string.match(param, "([^ ]+)")
|
||||||
|
if setname then
|
||||||
|
local setvalue = minetest.setting_get(setname)
|
||||||
|
if not setvalue then
|
||||||
|
setvalue = "<not set>"
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(name, setname.." = "..setvalue)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(name, "Invalid parameters (see /help set)")
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
19
builtin/deprecated.lua
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
-- Minetest: builtin/deprecated.lua
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Default material types
|
||||||
|
--
|
||||||
|
function digprop_err()
|
||||||
|
minetest.log("info", debug.traceback())
|
||||||
|
minetest.log("info", "WARNING: The minetest.digprop_* functions are obsolete and need to be replaced by item groups.")
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.digprop_constanttime = digprop_err
|
||||||
|
minetest.digprop_stonelike = digprop_err
|
||||||
|
minetest.digprop_dirtlike = digprop_err
|
||||||
|
minetest.digprop_gravellike = digprop_err
|
||||||
|
minetest.digprop_woodlike = digprop_err
|
||||||
|
minetest.digprop_leaveslike = digprop_err
|
||||||
|
minetest.digprop_glasslike = digprop_err
|
||||||
|
|
||||||
|
|
||||||
442
builtin/item.lua
Normal file
@@ -0,0 +1,442 @@
|
|||||||
|
-- Minetest: builtin/item.lua
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Item definition helpers
|
||||||
|
--
|
||||||
|
|
||||||
|
function minetest.inventorycube(img1, img2, img3)
|
||||||
|
img2 = img2 or img1
|
||||||
|
img3 = img3 or img1
|
||||||
|
return "[inventorycube"
|
||||||
|
.. "{" .. img1:gsub("%^", "&")
|
||||||
|
.. "{" .. img2:gsub("%^", "&")
|
||||||
|
.. "{" .. img3:gsub("%^", "&")
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.get_pointed_thing_position(pointed_thing, above)
|
||||||
|
if pointed_thing.type == "node" then
|
||||||
|
if above then
|
||||||
|
-- The position where a node would be placed
|
||||||
|
return pointed_thing.above
|
||||||
|
else
|
||||||
|
-- The position where a node would be dug
|
||||||
|
return pointed_thing.under
|
||||||
|
end
|
||||||
|
elseif pointed_thing.type == "object" then
|
||||||
|
obj = pointed_thing.ref
|
||||||
|
if obj ~= nil then
|
||||||
|
return obj:getpos()
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.dir_to_facedir(dir)
|
||||||
|
if math.abs(dir.x) > math.abs(dir.z) then
|
||||||
|
if dir.x < 0 then
|
||||||
|
return 3
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if dir.z < 0 then
|
||||||
|
return 2
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.dir_to_wallmounted(dir)
|
||||||
|
if math.abs(dir.y) > math.max(math.abs(dir.x), math.abs(dir.z)) then
|
||||||
|
if dir.y < 0 then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
elseif math.abs(dir.x) > math.abs(dir.z) then
|
||||||
|
if dir.x < 0 then
|
||||||
|
return 3
|
||||||
|
else
|
||||||
|
return 2
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if dir.z < 0 then
|
||||||
|
return 5
|
||||||
|
else
|
||||||
|
return 4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.get_node_drops(nodename, toolname)
|
||||||
|
local drop = ItemStack({name=nodename}):get_definition().drop
|
||||||
|
if drop == nil then
|
||||||
|
-- default drop
|
||||||
|
return {ItemStack({name=nodename})}
|
||||||
|
elseif type(drop) == "string" then
|
||||||
|
-- itemstring drop
|
||||||
|
return {ItemStack(drop)}
|
||||||
|
elseif drop.items == nil then
|
||||||
|
-- drop = {} to disable default drop
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Extended drop table
|
||||||
|
local got_items = {}
|
||||||
|
local got_count = 0
|
||||||
|
local _, item, tool
|
||||||
|
for _, item in ipairs(drop.items) do
|
||||||
|
local good_rarity = true
|
||||||
|
local good_tool = true
|
||||||
|
if item.rarity ~= nil then
|
||||||
|
good_rarity = item.rarity < 1 or math.random(item.rarity) == 1
|
||||||
|
end
|
||||||
|
if item.tools ~= nil then
|
||||||
|
good_tool = false
|
||||||
|
for _, tool in ipairs(item.tools) do
|
||||||
|
if tool:sub(1, 1) == '~' then
|
||||||
|
good_tool = toolname:find(tool:sub(2)) ~= nil
|
||||||
|
else
|
||||||
|
good_tool = toolname == tool
|
||||||
|
end
|
||||||
|
if good_tool then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if good_rarity and good_tool then
|
||||||
|
got_count = got_count + 1
|
||||||
|
for _, add_item in ipairs(item.items) do
|
||||||
|
got_items[#got_items+1] = add_item
|
||||||
|
end
|
||||||
|
if drop.max_items ~= nil and got_count == drop.max_items then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return got_items
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||||
|
local item = itemstack:peek_item()
|
||||||
|
local def = itemstack:get_definition()
|
||||||
|
if def.type == "node" and pointed_thing.type == "node" then
|
||||||
|
local pos = pointed_thing.above
|
||||||
|
local oldnode = minetest.env:get_node(pos)
|
||||||
|
local olddef = ItemStack({name=oldnode.name}):get_definition()
|
||||||
|
|
||||||
|
if not olddef.buildable_to then
|
||||||
|
minetest.log("info", placer:get_player_name() .. " tried to place"
|
||||||
|
.. " node in invalid position " .. minetest.pos_to_string(pos)
|
||||||
|
.. ", replacing " .. oldnode.name)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("action", placer:get_player_name() .. " places node "
|
||||||
|
.. def.name .. " at " .. minetest.pos_to_string(pos))
|
||||||
|
|
||||||
|
local newnode = {name = def.name, param1 = 0, param2 = 0}
|
||||||
|
|
||||||
|
-- Calculate direction for wall mounted stuff like torches and signs
|
||||||
|
if def.paramtype2 == 'wallmounted' then
|
||||||
|
local under = pointed_thing.under
|
||||||
|
local above = pointed_thing.above
|
||||||
|
local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
|
||||||
|
newnode.param2 = minetest.dir_to_wallmounted(dir)
|
||||||
|
-- Calculate the direction for furnaces and chests and stuff
|
||||||
|
elseif def.paramtype2 == 'facedir' then
|
||||||
|
local playerpos = placer:getpos()
|
||||||
|
local dir = {x = pos.x - playerpos.x, y = pos.y - playerpos.y, z = pos.z - playerpos.z}
|
||||||
|
newnode.param2 = minetest.dir_to_facedir(dir)
|
||||||
|
minetest.log("action", "facedir: " .. newnode.param2)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add node and update
|
||||||
|
minetest.env:add_node(pos, newnode)
|
||||||
|
|
||||||
|
-- Run callback
|
||||||
|
if def.after_place_node then
|
||||||
|
def.after_place_node(pos, placer)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Run script hook (deprecated)
|
||||||
|
local _, callback
|
||||||
|
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
||||||
|
callback(pos, newnode, placer)
|
||||||
|
end
|
||||||
|
|
||||||
|
itemstack:take_item()
|
||||||
|
end
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.item_place_object(itemstack, placer, pointed_thing)
|
||||||
|
local pos = minetest.get_pointed_thing_position(pointed_thing, true)
|
||||||
|
if pos ~= nil then
|
||||||
|
local item = itemstack:take_item()
|
||||||
|
minetest.env:add_item(pos, item)
|
||||||
|
end
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.item_place(itemstack, placer, pointed_thing)
|
||||||
|
if itemstack:get_definition().type == "node" then
|
||||||
|
return minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||||
|
else
|
||||||
|
return minetest.item_place_object(itemstack, placer, pointed_thing)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.item_drop(itemstack, dropper, pos)
|
||||||
|
if dropper.get_player_name then
|
||||||
|
local v = dropper:get_look_dir()
|
||||||
|
local p = {x=pos.x+v.x, y=pos.y+1.5+v.y, z=pos.z+v.z}
|
||||||
|
local obj = minetest.env:add_item(p, itemstack)
|
||||||
|
v.x = v.x*2
|
||||||
|
v.y = v.y*2 + 1
|
||||||
|
v.z = v.z*2
|
||||||
|
obj:setvelocity(v)
|
||||||
|
else
|
||||||
|
minetest.env:add_item(pos, itemstack)
|
||||||
|
end
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.item_eat(hp_change, replace_with_item)
|
||||||
|
return function(itemstack, user, pointed_thing) -- closure
|
||||||
|
if itemstack:take_item() ~= nil then
|
||||||
|
user:set_hp(user:get_hp() + hp_change)
|
||||||
|
itemstack:add_item(replace_with_item) -- note: replace_with_item is optional
|
||||||
|
end
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.node_punch(pos, node, puncher)
|
||||||
|
-- Run script hook
|
||||||
|
local _, callback
|
||||||
|
for _, callback in ipairs(minetest.registered_on_punchnodes) do
|
||||||
|
callback(pos, node, puncher)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.node_dig(pos, node, digger)
|
||||||
|
minetest.debug("node_dig")
|
||||||
|
|
||||||
|
local def = ItemStack({name=node.name}):get_definition()
|
||||||
|
if not def.diggable or (def.can_dig and not def.can_dig(pos,digger)) then
|
||||||
|
minetest.debug("not diggable")
|
||||||
|
minetest.log("info", digger:get_player_name() .. " tried to dig "
|
||||||
|
.. node.name .. " which is not diggable "
|
||||||
|
.. minetest.pos_to_string(pos))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log('action', digger:get_player_name() .. " digs "
|
||||||
|
.. node.name .. " at " .. minetest.pos_to_string(pos))
|
||||||
|
|
||||||
|
if not minetest.setting_getbool("creative_mode") then
|
||||||
|
local wielded = digger:get_wielded_item()
|
||||||
|
local drops = minetest.get_node_drops(node.name, wielded:get_name())
|
||||||
|
|
||||||
|
-- Wear out tool
|
||||||
|
tp = wielded:get_tool_capabilities()
|
||||||
|
dp = minetest.get_dig_params(def.groups, tp)
|
||||||
|
wielded:add_wear(dp.wear)
|
||||||
|
digger:set_wielded_item(wielded)
|
||||||
|
|
||||||
|
-- Add dropped items
|
||||||
|
local _, dropped_item
|
||||||
|
for _, dropped_item in ipairs(drops) do
|
||||||
|
digger:get_inventory():add_item("main", dropped_item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local oldnode = nil
|
||||||
|
local oldmetadata = nil
|
||||||
|
if def.after_dig_node then
|
||||||
|
oldnode = node;
|
||||||
|
oldmetadata = minetest.env:get_meta(pos):to_table()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Remove node and update
|
||||||
|
minetest.env:remove_node(pos)
|
||||||
|
|
||||||
|
-- Run callback
|
||||||
|
if def.after_dig_node then
|
||||||
|
def.after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Run script hook (deprecated)
|
||||||
|
local _, callback
|
||||||
|
for _, callback in ipairs(minetest.registered_on_dignodes) do
|
||||||
|
callback(pos, node, digger)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.node_metadata_inventory_move_allow_all(pos, from_list,
|
||||||
|
from_index, to_list, to_index, count, player)
|
||||||
|
minetest.log("verbose", "node_metadata_inventory_move_allow_all")
|
||||||
|
local meta = minetest.env:get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
|
||||||
|
local from_stack = inv:get_stack(from_list, from_index)
|
||||||
|
local taken_items = from_stack:take_item(count)
|
||||||
|
inv:set_stack(from_list, from_index, from_stack)
|
||||||
|
|
||||||
|
local to_stack = inv:get_stack(to_list, to_index)
|
||||||
|
to_stack:add_item(taken_items)
|
||||||
|
inv:set_stack(to_list, to_index, to_stack)
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.node_metadata_inventory_offer_allow_all(pos, listname, index, stack, player)
|
||||||
|
minetest.log("verbose", "node_metadata_inventory_offer_allow_all")
|
||||||
|
local meta = minetest.env:get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local the_stack = inv:get_stack(listname, index)
|
||||||
|
the_stack:add_item(stack)
|
||||||
|
inv:set_stack(listname, index, the_stack)
|
||||||
|
return ItemStack("")
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.node_metadata_inventory_take_allow_all(pos, listname, index, count, player)
|
||||||
|
minetest.log("verbose", "node_metadata_inventory_take_allow_all")
|
||||||
|
local meta = minetest.env:get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
local the_stack = inv:get_stack(listname, index)
|
||||||
|
local taken_items = the_stack:take_item(count)
|
||||||
|
inv:set_stack(listname, index, the_stack)
|
||||||
|
return taken_items
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This is used to allow mods to redefine minetest.item_place and so on
|
||||||
|
-- NOTE: This is not the preferred way. Preferred way is to provide enough
|
||||||
|
-- callbacks to not require redefining global functions. -celeron55
|
||||||
|
local function redef_wrapper(table, name)
|
||||||
|
return function(...)
|
||||||
|
return table[name](...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Item definition defaults
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.nodedef_default = {
|
||||||
|
-- Item properties
|
||||||
|
type="node",
|
||||||
|
-- name intentionally not defined here
|
||||||
|
description = "",
|
||||||
|
groups = {},
|
||||||
|
inventory_image = "",
|
||||||
|
wield_image = "",
|
||||||
|
wield_scale = {x=1,y=1,z=1},
|
||||||
|
stack_max = 99,
|
||||||
|
usable = false,
|
||||||
|
liquids_pointable = false,
|
||||||
|
tool_capabilities = nil,
|
||||||
|
|
||||||
|
-- Interaction callbacks
|
||||||
|
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
|
||||||
|
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
|
||||||
|
on_use = nil,
|
||||||
|
can_dig = nil,
|
||||||
|
|
||||||
|
on_punch = redef_wrapper(minetest, 'node_punch'), -- minetest.node_punch
|
||||||
|
on_dig = redef_wrapper(minetest, 'node_dig'), -- minetest.node_dig
|
||||||
|
|
||||||
|
on_receive_fields = nil,
|
||||||
|
|
||||||
|
on_metadata_inventory_move = minetest.node_metadata_inventory_move_allow_all,
|
||||||
|
on_metadata_inventory_offer = minetest.node_metadata_inventory_offer_allow_all,
|
||||||
|
on_metadata_inventory_take = minetest.node_metadata_inventory_take_allow_all,
|
||||||
|
|
||||||
|
-- Node properties
|
||||||
|
drawtype = "normal",
|
||||||
|
visual_scale = 1.0,
|
||||||
|
tile_images = {""},
|
||||||
|
special_materials = {
|
||||||
|
{image="", backface_culling=true},
|
||||||
|
{image="", backface_culling=true},
|
||||||
|
},
|
||||||
|
alpha = 255,
|
||||||
|
post_effect_color = {a=0, r=0, g=0, b=0},
|
||||||
|
paramtype = "none",
|
||||||
|
paramtype2 = "none",
|
||||||
|
is_ground_content = false,
|
||||||
|
sunlight_propagates = false,
|
||||||
|
walkable = true,
|
||||||
|
pointable = true,
|
||||||
|
diggable = true,
|
||||||
|
climbable = false,
|
||||||
|
buildable_to = false,
|
||||||
|
liquidtype = "none",
|
||||||
|
liquid_alternative_flowing = "",
|
||||||
|
liquid_alternative_source = "",
|
||||||
|
liquid_viscosity = 0,
|
||||||
|
light_source = 0,
|
||||||
|
damage_per_second = 0,
|
||||||
|
selection_box = {type="regular"},
|
||||||
|
legacy_facedir_simple = false,
|
||||||
|
legacy_wallmounted = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
minetest.craftitemdef_default = {
|
||||||
|
type="craft",
|
||||||
|
-- name intentionally not defined here
|
||||||
|
description = "",
|
||||||
|
groups = {},
|
||||||
|
inventory_image = "",
|
||||||
|
wield_image = "",
|
||||||
|
wield_scale = {x=1,y=1,z=1},
|
||||||
|
stack_max = 99,
|
||||||
|
liquids_pointable = false,
|
||||||
|
tool_capabilities = nil,
|
||||||
|
|
||||||
|
-- Interaction callbacks
|
||||||
|
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
|
||||||
|
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
|
||||||
|
on_use = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
minetest.tooldef_default = {
|
||||||
|
type="tool",
|
||||||
|
-- name intentionally not defined here
|
||||||
|
description = "",
|
||||||
|
groups = {},
|
||||||
|
inventory_image = "",
|
||||||
|
wield_image = "",
|
||||||
|
wield_scale = {x=1,y=1,z=1},
|
||||||
|
stack_max = 1,
|
||||||
|
liquids_pointable = false,
|
||||||
|
tool_capabilities = nil,
|
||||||
|
|
||||||
|
-- Interaction callbacks
|
||||||
|
on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
|
||||||
|
on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
|
||||||
|
on_use = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
minetest.noneitemdef_default = { -- This is used for the hand and unknown items
|
||||||
|
type="none",
|
||||||
|
-- name intentionally not defined here
|
||||||
|
description = "",
|
||||||
|
groups = {},
|
||||||
|
inventory_image = "",
|
||||||
|
wield_image = "",
|
||||||
|
wield_scale = {x=1,y=1,z=1},
|
||||||
|
stack_max = 99,
|
||||||
|
liquids_pointable = false,
|
||||||
|
tool_capabilities = nil,
|
||||||
|
|
||||||
|
-- Interaction callbacks
|
||||||
|
on_place = nil,
|
||||||
|
on_drop = nil,
|
||||||
|
on_use = nil,
|
||||||
|
}
|
||||||
|
|
||||||
103
builtin/item_entity.lua
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
-- Minetest: builtin/item_entity.lua
|
||||||
|
|
||||||
|
function minetest.spawn_item(pos, item)
|
||||||
|
-- Take item in any format
|
||||||
|
local stack = ItemStack(item)
|
||||||
|
local obj = minetest.env:add_entity(pos, "__builtin:item")
|
||||||
|
obj:get_luaentity():set_item(stack:to_string())
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_entity("__builtin:item", {
|
||||||
|
initial_properties = {
|
||||||
|
hp_max = 1,
|
||||||
|
physical = true,
|
||||||
|
collisionbox = {-0.17,-0.17,-0.17, 0.17,0.17,0.17},
|
||||||
|
visual = "sprite",
|
||||||
|
visual_size = {x=0.5, y=0.5},
|
||||||
|
textures = {""},
|
||||||
|
spritediv = {x=1, y=1},
|
||||||
|
initial_sprite_basepos = {x=0, y=0},
|
||||||
|
is_visible = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
itemstring = '',
|
||||||
|
physical_state = true,
|
||||||
|
|
||||||
|
set_item = function(self, itemstring)
|
||||||
|
self.itemstring = itemstring
|
||||||
|
local stack = ItemStack(itemstring)
|
||||||
|
local itemtable = stack:to_table()
|
||||||
|
local itemname = nil
|
||||||
|
if itemtable then
|
||||||
|
itemname = stack:to_table().name
|
||||||
|
end
|
||||||
|
local item_texture = nil
|
||||||
|
local item_type = ""
|
||||||
|
if minetest.registered_items[itemname] then
|
||||||
|
item_texture = minetest.registered_items[itemname].inventory_image
|
||||||
|
item_type = minetest.registered_items[itemname].type
|
||||||
|
end
|
||||||
|
prop = {
|
||||||
|
is_visible = true,
|
||||||
|
visual = "sprite",
|
||||||
|
textures = {"unknown_item.png"}
|
||||||
|
}
|
||||||
|
if item_texture and item_texture ~= "" then
|
||||||
|
prop.visual = "sprite"
|
||||||
|
prop.textures = {item_texture}
|
||||||
|
prop.visual_size = {x=0.50, y=0.50}
|
||||||
|
else
|
||||||
|
prop.visual = "wielditem"
|
||||||
|
prop.textures = {itemname}
|
||||||
|
prop.visual_size = {x=0.20, y=0.20}
|
||||||
|
prop.automatic_rotate = math.pi * 0.25
|
||||||
|
end
|
||||||
|
self.object:set_properties(prop)
|
||||||
|
end,
|
||||||
|
|
||||||
|
get_staticdata = function(self)
|
||||||
|
return self.itemstring
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_activate = function(self, staticdata)
|
||||||
|
self.itemstring = staticdata
|
||||||
|
self.object:set_armor_groups({immortal=1})
|
||||||
|
self.object:setvelocity({x=0, y=2, z=0})
|
||||||
|
self.object:setacceleration({x=0, y=-10, z=0})
|
||||||
|
self:set_item(self.itemstring)
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_step = function(self, dtime)
|
||||||
|
local p = self.object:getpos()
|
||||||
|
p.y = p.y - 0.3
|
||||||
|
local nn = minetest.env:get_node(p).name
|
||||||
|
if minetest.registered_nodes[nn].walkable then
|
||||||
|
if self.physical_state then
|
||||||
|
self.object:setvelocity({x=0,y=0,z=0})
|
||||||
|
self.object:setacceleration({x=0, y=0, z=0})
|
||||||
|
self.physical_state = false
|
||||||
|
self.object:set_properties({
|
||||||
|
physical = false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not self.physical_state then
|
||||||
|
self.object:setvelocity({x=0,y=0,z=0})
|
||||||
|
self.object:setacceleration({x=0, y=-10, z=0})
|
||||||
|
self.physical_state = true
|
||||||
|
self.object:set_properties({
|
||||||
|
physical = true
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_punch = function(self, hitter)
|
||||||
|
if self.itemstring ~= '' then
|
||||||
|
hitter:get_inventory():add_item("main", self.itemstring)
|
||||||
|
end
|
||||||
|
self.object:remove()
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
101
builtin/misc.lua
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
-- Minetest: builtin/misc.lua
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Misc. API functions
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.timers_to_add = {}
|
||||||
|
minetest.timers = {}
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
for _, timer in ipairs(minetest.timers_to_add) do
|
||||||
|
table.insert(minetest.timers, timer)
|
||||||
|
end
|
||||||
|
minetest.timers_to_add = {}
|
||||||
|
for index, timer in ipairs(minetest.timers) do
|
||||||
|
timer.time = timer.time - dtime
|
||||||
|
if timer.time <= 0 then
|
||||||
|
timer.func(timer.param)
|
||||||
|
table.remove(minetest.timers,index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
function minetest.after(time, func, param)
|
||||||
|
table.insert(minetest.timers_to_add, {time=time, func=func, param=param})
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.check_player_privs(name, privs)
|
||||||
|
local player_privs = minetest.get_player_privs(name)
|
||||||
|
local missing_privileges = {}
|
||||||
|
for priv, val in pairs(privs) do
|
||||||
|
if val then
|
||||||
|
if not player_privs[priv] then
|
||||||
|
table.insert(missing_privileges, priv)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #missing_privileges > 0 then
|
||||||
|
return false, missing_privileges
|
||||||
|
end
|
||||||
|
return true, ""
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.get_connected_players()
|
||||||
|
-- This could be optimized a bit, but leave that for later
|
||||||
|
local list = {}
|
||||||
|
for _, obj in pairs(minetest.env:get_objects_inside_radius({x=0,y=0,z=0}, 1000000)) do
|
||||||
|
if obj:is_player() then
|
||||||
|
table.insert(list, obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return list
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.hash_node_position(pos)
|
||||||
|
return (pos.z+32768)*65536*65536 + (pos.y+32768)*65536 + pos.x+32768
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.get_item_group(name, group)
|
||||||
|
if not minetest.registered_items[name] or not
|
||||||
|
minetest.registered_items[name].groups[group] then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
return minetest.registered_items[name].groups[group]
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.get_node_group(name, group)
|
||||||
|
return minetest.get_item_group(name, group)
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.string_to_pos(value)
|
||||||
|
local p = {}
|
||||||
|
p.x, p.y, p.z = string.match(value, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
|
||||||
|
if p.x and p.y and p.z then
|
||||||
|
p.x = tonumber(p.x)
|
||||||
|
p.y = tonumber(p.y)
|
||||||
|
p.z = tonumber(p.z)
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
local p = {}
|
||||||
|
p.x, p.y, p.z = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) *%)$")
|
||||||
|
if p.x and p.y and p.z then
|
||||||
|
p.x = tonumber(p.x)
|
||||||
|
p.y = tonumber(p.y)
|
||||||
|
p.z = tonumber(p.z)
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(minetest.string_to_pos("10.0, 5, -2").x == 10)
|
||||||
|
assert(minetest.string_to_pos("( 10.0, 5, -2)").z == -2)
|
||||||
|
assert(minetest.string_to_pos("asd, 5, -2)") == nil)
|
||||||
|
|
||||||
|
function minetest.setting_get_pos(name)
|
||||||
|
local value = minetest.setting_get(name)
|
||||||
|
if not value then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return minetest.string_to_pos(value)
|
||||||
|
end
|
||||||
|
|
||||||
94
builtin/misc_helpers.lua
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
-- Minetest: builtin/misc_helpers.lua
|
||||||
|
|
||||||
|
function basic_dump2(o)
|
||||||
|
if type(o) == "number" then
|
||||||
|
return tostring(o)
|
||||||
|
elseif type(o) == "string" then
|
||||||
|
return string.format("%q", o)
|
||||||
|
elseif type(o) == "boolean" then
|
||||||
|
return tostring(o)
|
||||||
|
elseif type(o) == "function" then
|
||||||
|
return "<function>"
|
||||||
|
elseif type(o) == "userdata" then
|
||||||
|
return "<userdata>"
|
||||||
|
elseif type(o) == "nil" then
|
||||||
|
return "nil"
|
||||||
|
else
|
||||||
|
error("cannot dump a " .. type(o))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function dump2(o, name, dumped)
|
||||||
|
name = name or "_"
|
||||||
|
dumped = dumped or {}
|
||||||
|
io.write(name, " = ")
|
||||||
|
if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
|
||||||
|
or type(o) == "function" or type(o) == "nil"
|
||||||
|
or type(o) == "userdata" then
|
||||||
|
io.write(basic_dump2(o), "\n")
|
||||||
|
elseif type(o) == "table" then
|
||||||
|
if dumped[o] then
|
||||||
|
io.write(dumped[o], "\n")
|
||||||
|
else
|
||||||
|
dumped[o] = name
|
||||||
|
io.write("{}\n") -- new table
|
||||||
|
for k,v in pairs(o) do
|
||||||
|
local fieldname = string.format("%s[%s]", name, basic_dump2(k))
|
||||||
|
dump2(v, fieldname, dumped)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("cannot dump a " .. type(o))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function dump(o, dumped)
|
||||||
|
dumped = dumped or {}
|
||||||
|
if type(o) == "number" then
|
||||||
|
return tostring(o)
|
||||||
|
elseif type(o) == "string" then
|
||||||
|
return string.format("%q", o)
|
||||||
|
elseif type(o) == "table" then
|
||||||
|
if dumped[o] then
|
||||||
|
return "<circular reference>"
|
||||||
|
end
|
||||||
|
dumped[o] = true
|
||||||
|
local t = {}
|
||||||
|
for k,v in pairs(o) do
|
||||||
|
t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
|
||||||
|
end
|
||||||
|
return "{" .. table.concat(t, ", ") .. "}"
|
||||||
|
elseif type(o) == "boolean" then
|
||||||
|
return tostring(o)
|
||||||
|
elseif type(o) == "function" then
|
||||||
|
return "<function>"
|
||||||
|
elseif type(o) == "userdata" then
|
||||||
|
return "<userdata>"
|
||||||
|
elseif type(o) == "nil" then
|
||||||
|
return "nil"
|
||||||
|
else
|
||||||
|
error("cannot dump a " .. type(o))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function string:split(sep)
|
||||||
|
local sep, fields = sep or ",", {}
|
||||||
|
local pattern = string.format("([^%s]+)", sep)
|
||||||
|
self:gsub(pattern, function(c) fields[#fields+1] = c end)
|
||||||
|
return fields
|
||||||
|
end
|
||||||
|
|
||||||
|
function string:trim()
|
||||||
|
return (self:gsub("^%s*(.-)%s*$", "%1"))
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(string.trim("\n \t\tfoo bar\t ") == "foo bar")
|
||||||
|
|
||||||
|
function minetest.pos_to_string(pos)
|
||||||
|
return "(" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ")"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
324
builtin/misc_register.lua
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
-- Minetest: builtin/misc_register.lua
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Make raw registration functions inaccessible to anyone except this file
|
||||||
|
--
|
||||||
|
|
||||||
|
local register_item_raw = minetest.register_item_raw
|
||||||
|
minetest.register_item_raw = nil
|
||||||
|
|
||||||
|
local register_alias_raw = minetest.register_alias_raw
|
||||||
|
minetest.register_item_raw = nil
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Item / entity / ABM registration functions
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.registered_abms = {}
|
||||||
|
minetest.registered_entities = {}
|
||||||
|
minetest.registered_items = {}
|
||||||
|
minetest.registered_nodes = {}
|
||||||
|
minetest.registered_craftitems = {}
|
||||||
|
minetest.registered_tools = {}
|
||||||
|
minetest.registered_aliases = {}
|
||||||
|
|
||||||
|
-- For tables that are indexed by item name:
|
||||||
|
-- If table[X] does not exist, default to table[minetest.registered_aliases[X]]
|
||||||
|
local function set_alias_metatable(table)
|
||||||
|
setmetatable(table, {
|
||||||
|
__index = function(name)
|
||||||
|
return rawget(table, minetest.registered_aliases[name])
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
set_alias_metatable(minetest.registered_items)
|
||||||
|
set_alias_metatable(minetest.registered_nodes)
|
||||||
|
set_alias_metatable(minetest.registered_craftitems)
|
||||||
|
set_alias_metatable(minetest.registered_tools)
|
||||||
|
|
||||||
|
-- These item names may not be used because they would interfere
|
||||||
|
-- with legacy itemstrings
|
||||||
|
local forbidden_item_names = {
|
||||||
|
MaterialItem = true,
|
||||||
|
MaterialItem2 = true,
|
||||||
|
MaterialItem3 = true,
|
||||||
|
NodeItem = true,
|
||||||
|
node = true,
|
||||||
|
CraftItem = true,
|
||||||
|
craft = true,
|
||||||
|
MBOItem = true,
|
||||||
|
ToolItem = true,
|
||||||
|
tool = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function check_modname_prefix(name)
|
||||||
|
if name:sub(1,1) == ":" then
|
||||||
|
-- Escape the modname prefix enforcement mechanism
|
||||||
|
return name:sub(2)
|
||||||
|
else
|
||||||
|
-- Modname prefix enforcement
|
||||||
|
local expected_prefix = minetest.get_current_modname() .. ":"
|
||||||
|
if name:sub(1, #expected_prefix) ~= expected_prefix then
|
||||||
|
error("Name " .. name .. " does not follow naming conventions: " ..
|
||||||
|
"\"modname:\" or \":\" prefix required")
|
||||||
|
end
|
||||||
|
local subname = name:sub(#expected_prefix+1)
|
||||||
|
if subname:find("[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]") then
|
||||||
|
error("Name " .. name .. " does not follow naming conventions: " ..
|
||||||
|
"contains unallowed characters")
|
||||||
|
end
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.register_abm(spec)
|
||||||
|
-- Add to minetest.registered_abms
|
||||||
|
minetest.registered_abms[#minetest.registered_abms+1] = spec
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.register_entity(name, prototype)
|
||||||
|
-- Check name
|
||||||
|
if name == nil then
|
||||||
|
error("Unable to register entity: Name is nil")
|
||||||
|
end
|
||||||
|
name = check_modname_prefix(tostring(name))
|
||||||
|
|
||||||
|
prototype.name = name
|
||||||
|
prototype.__index = prototype -- so that it can be used as a metatable
|
||||||
|
|
||||||
|
-- Add to minetest.registered_entities
|
||||||
|
minetest.registered_entities[name] = prototype
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.register_item(name, itemdef)
|
||||||
|
-- Check name
|
||||||
|
if name == nil then
|
||||||
|
error("Unable to register item: Name is nil")
|
||||||
|
end
|
||||||
|
name = check_modname_prefix(tostring(name))
|
||||||
|
if forbidden_item_names[name] then
|
||||||
|
error("Unable to register item: Name is forbidden: " .. name)
|
||||||
|
end
|
||||||
|
itemdef.name = name
|
||||||
|
|
||||||
|
-- Apply defaults and add to registered_* table
|
||||||
|
if itemdef.type == "node" then
|
||||||
|
setmetatable(itemdef, {__index = minetest.nodedef_default})
|
||||||
|
minetest.registered_nodes[itemdef.name] = itemdef
|
||||||
|
elseif itemdef.type == "craft" then
|
||||||
|
setmetatable(itemdef, {__index = minetest.craftitemdef_default})
|
||||||
|
minetest.registered_craftitems[itemdef.name] = itemdef
|
||||||
|
elseif itemdef.type == "tool" then
|
||||||
|
setmetatable(itemdef, {__index = minetest.tooldef_default})
|
||||||
|
minetest.registered_tools[itemdef.name] = itemdef
|
||||||
|
elseif itemdef.type == "none" then
|
||||||
|
setmetatable(itemdef, {__index = minetest.noneitemdef_default})
|
||||||
|
else
|
||||||
|
error("Unable to register item: Type is invalid: " .. dump(itemdef))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Flowing liquid uses param2
|
||||||
|
if itemdef.type == "node" and itemdef.liquidtype == "flowing" then
|
||||||
|
itemdef.paramtype2 = "flowingliquid"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- BEGIN Legacy stuff
|
||||||
|
if itemdef.cookresult_itemstring ~= nil and itemdef.cookresult_itemstring ~= "" then
|
||||||
|
minetest.register_craft({
|
||||||
|
type="cooking",
|
||||||
|
output=itemdef.cookresult_itemstring,
|
||||||
|
recipe=itemdef.name,
|
||||||
|
cooktime=itemdef.furnace_cooktime
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if itemdef.furnace_burntime ~= nil and itemdef.furnace_burntime >= 0 then
|
||||||
|
minetest.register_craft({
|
||||||
|
type="fuel",
|
||||||
|
recipe=itemdef.name,
|
||||||
|
burntime=itemdef.furnace_burntime
|
||||||
|
})
|
||||||
|
end
|
||||||
|
-- END Legacy stuff
|
||||||
|
|
||||||
|
-- Disable all further modifications
|
||||||
|
getmetatable(itemdef).__newindex = {}
|
||||||
|
|
||||||
|
--minetest.log("Registering item: " .. itemdef.name)
|
||||||
|
minetest.registered_items[itemdef.name] = itemdef
|
||||||
|
minetest.registered_aliases[itemdef.name] = nil
|
||||||
|
register_item_raw(itemdef)
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.register_node(name, nodedef)
|
||||||
|
nodedef.type = "node"
|
||||||
|
minetest.register_item(name, nodedef)
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.register_craftitem(name, craftitemdef)
|
||||||
|
craftitemdef.type = "craft"
|
||||||
|
|
||||||
|
-- BEGIN Legacy stuff
|
||||||
|
if craftitemdef.inventory_image == nil and craftitemdef.image ~= nil then
|
||||||
|
craftitemdef.inventory_image = craftitemdef.image
|
||||||
|
end
|
||||||
|
-- END Legacy stuff
|
||||||
|
|
||||||
|
minetest.register_item(name, craftitemdef)
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.register_tool(name, tooldef)
|
||||||
|
tooldef.type = "tool"
|
||||||
|
tooldef.stack_max = 1
|
||||||
|
|
||||||
|
-- BEGIN Legacy stuff
|
||||||
|
if tooldef.inventory_image == nil and tooldef.image ~= nil then
|
||||||
|
tooldef.inventory_image = tooldef.image
|
||||||
|
end
|
||||||
|
if tooldef.tool_capabilities == nil and
|
||||||
|
(tooldef.full_punch_interval ~= nil or
|
||||||
|
tooldef.basetime ~= nil or
|
||||||
|
tooldef.dt_weight ~= nil or
|
||||||
|
tooldef.dt_crackiness ~= nil or
|
||||||
|
tooldef.dt_crumbliness ~= nil or
|
||||||
|
tooldef.dt_cuttability ~= nil or
|
||||||
|
tooldef.basedurability ~= nil or
|
||||||
|
tooldef.dd_weight ~= nil or
|
||||||
|
tooldef.dd_crackiness ~= nil or
|
||||||
|
tooldef.dd_crumbliness ~= nil or
|
||||||
|
tooldef.dd_cuttability ~= nil) then
|
||||||
|
tooldef.tool_capabilities = {
|
||||||
|
full_punch_interval = tooldef.full_punch_interval,
|
||||||
|
basetime = tooldef.basetime,
|
||||||
|
dt_weight = tooldef.dt_weight,
|
||||||
|
dt_crackiness = tooldef.dt_crackiness,
|
||||||
|
dt_crumbliness = tooldef.dt_crumbliness,
|
||||||
|
dt_cuttability = tooldef.dt_cuttability,
|
||||||
|
basedurability = tooldef.basedurability,
|
||||||
|
dd_weight = tooldef.dd_weight,
|
||||||
|
dd_crackiness = tooldef.dd_crackiness,
|
||||||
|
dd_crumbliness = tooldef.dd_crumbliness,
|
||||||
|
dd_cuttability = tooldef.dd_cuttability,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
-- END Legacy stuff
|
||||||
|
|
||||||
|
minetest.register_item(name, tooldef)
|
||||||
|
end
|
||||||
|
|
||||||
|
function minetest.register_alias(name, convert_to)
|
||||||
|
if forbidden_item_names[name] then
|
||||||
|
error("Unable to register alias: Name is forbidden: " .. name)
|
||||||
|
end
|
||||||
|
if minetest.registered_items[name] ~= nil then
|
||||||
|
minetest.log("WARNING: Not registering alias, item with same name" ..
|
||||||
|
" is already defined: " .. name .. " -> " .. convert_to)
|
||||||
|
else
|
||||||
|
--minetest.log("Registering alias: " .. name .. " -> " .. convert_to)
|
||||||
|
minetest.registered_aliases[name] = convert_to
|
||||||
|
register_alias_raw(name, convert_to)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Alias the forbidden item names to "" so they can't be
|
||||||
|
-- created via itemstrings (e.g. /give)
|
||||||
|
local name
|
||||||
|
for name in pairs(forbidden_item_names) do
|
||||||
|
minetest.registered_aliases[name] = ""
|
||||||
|
register_alias_raw(name, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Deprecated:
|
||||||
|
-- Aliases for minetest.register_alias (how ironic...)
|
||||||
|
--minetest.alias_node = minetest.register_alias
|
||||||
|
--minetest.alias_tool = minetest.register_alias
|
||||||
|
--minetest.alias_craftitem = minetest.register_alias
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Built-in node definitions. Also defined in C.
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.register_item(":unknown", {
|
||||||
|
type = "none",
|
||||||
|
description = "Unknown Item",
|
||||||
|
inventory_image = "unknown_item.png",
|
||||||
|
on_place = minetest.item_place,
|
||||||
|
on_drop = minetest.item_drop,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_node(":air", {
|
||||||
|
description = "Air (you hacker you!)",
|
||||||
|
inventory_image = "unknown_block.png",
|
||||||
|
wield_image = "unknown_block.png",
|
||||||
|
drawtype = "airlike",
|
||||||
|
paramtype = "light",
|
||||||
|
sunlight_propagates = true,
|
||||||
|
walkable = false,
|
||||||
|
pointable = false,
|
||||||
|
diggable = false,
|
||||||
|
buildable_to = true,
|
||||||
|
air_equivalent = true,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_node(":ignore", {
|
||||||
|
description = "Ignore (you hacker you!)",
|
||||||
|
inventory_image = "unknown_block.png",
|
||||||
|
wield_image = "unknown_block.png",
|
||||||
|
drawtype = "airlike",
|
||||||
|
paramtype = "none",
|
||||||
|
sunlight_propagates = false,
|
||||||
|
walkable = false,
|
||||||
|
pointable = false,
|
||||||
|
diggable = false,
|
||||||
|
buildable_to = true, -- A way to remove accidentally placed ignores
|
||||||
|
air_equivalent = true,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- The hand (bare definition)
|
||||||
|
minetest.register_item(":", {
|
||||||
|
type = "none",
|
||||||
|
})
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Creative inventory
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.creative_inventory = {}
|
||||||
|
|
||||||
|
minetest.add_to_creative_inventory = function(itemstring)
|
||||||
|
table.insert(minetest.creative_inventory, itemstring)
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Callback registration
|
||||||
|
--
|
||||||
|
|
||||||
|
local function make_registration()
|
||||||
|
local t = {}
|
||||||
|
local registerfunc = function(func) table.insert(t, func) end
|
||||||
|
return t, registerfunc
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
|
||||||
|
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
|
||||||
|
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
|
||||||
|
minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
|
||||||
|
minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
|
||||||
|
minetest.registered_on_dieplayers, minetest.register_on_dieplayer = make_registration()
|
||||||
|
minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
|
||||||
|
minetest.registered_on_joinplayers, minetest.register_on_joinplayer = make_registration()
|
||||||
|
minetest.registered_on_leaveplayers, minetest.register_on_leaveplayer = make_registration()
|
||||||
|
|
||||||
|
minetest.registered_on_placenodes = {}
|
||||||
|
minetest.register_on_placenode = function(callback)
|
||||||
|
minetest.log("info", debug.traceback())
|
||||||
|
minetest.log("info", "WARNING: minetest.register_on_placenode is deprecated. Use on_construct or after_place_node in node definition instead.")
|
||||||
|
table.insert(minetest.registered_on_placenodes, callback)
|
||||||
|
end
|
||||||
|
minetest.registered_on_dignodes = {}
|
||||||
|
minetest.register_on_dignode = function(callback)
|
||||||
|
minetest.log("info", debug.traceback())
|
||||||
|
minetest.log("info", "WARNING: minetest.register_on_dignode is deprecated. Use on_destruct or after_dig_node in node definition instead.")
|
||||||
|
table.insert(minetest.registered_on_dignodes, callback)
|
||||||
|
end
|
||||||
|
|
||||||
48
builtin/privileges.lua
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
-- Minetest: builtin/privileges.lua
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Privileges
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.registered_privileges = {}
|
||||||
|
|
||||||
|
function minetest.register_privilege(name, param)
|
||||||
|
local function fill_defaults(def)
|
||||||
|
if def.give_to_singleplayer == nil then
|
||||||
|
def.give_to_singleplayer = true
|
||||||
|
end
|
||||||
|
if def.description == nil then
|
||||||
|
def.description = "(no description)"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local def = {}
|
||||||
|
if type(param) == "table" then
|
||||||
|
def = param
|
||||||
|
else
|
||||||
|
def = {description = param}
|
||||||
|
end
|
||||||
|
fill_defaults(def)
|
||||||
|
minetest.registered_privileges[name] = def
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_privilege("interact", "Can interact with things and modify the world")
|
||||||
|
minetest.register_privilege("teleport", "Can use /teleport command")
|
||||||
|
minetest.register_privilege("bring", "Can teleport other players")
|
||||||
|
minetest.register_privilege("settime", "Can use /time")
|
||||||
|
minetest.register_privilege("privs", "Can modify privileges")
|
||||||
|
minetest.register_privilege("basic_privs", "Can modify 'shout' and 'interact' privileges")
|
||||||
|
minetest.register_privilege("server", "Can do server maintenance stuff")
|
||||||
|
minetest.register_privilege("shout", "Can speak in chat")
|
||||||
|
minetest.register_privilege("ban", "Can ban and unban players")
|
||||||
|
minetest.register_privilege("give", "Can use /give and /giveme")
|
||||||
|
minetest.register_privilege("password", "Can use /setpassword and /clearpassword")
|
||||||
|
minetest.register_privilege("fly", {
|
||||||
|
description = "Can fly using the free_move mode",
|
||||||
|
give_to_singleplayer = false,
|
||||||
|
})
|
||||||
|
minetest.register_privilege("fast", {
|
||||||
|
description = "Can walk fast using the fast_move mode",
|
||||||
|
give_to_singleplayer = false,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
33
builtin/static_spawn.lua
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
-- Minetest: builtin/static_spawn.lua
|
||||||
|
|
||||||
|
local function warn_invalid_static_spawnpoint()
|
||||||
|
if minetest.setting_get("static_spawnpoint") and
|
||||||
|
not minetest.setting_get_pos("static_spawnpoint") then
|
||||||
|
minetest.log('error', "The static_spawnpoint setting is invalid: \""..
|
||||||
|
minetest.setting_get("static_spawnpoint").."\"")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
warn_invalid_static_spawnpoint()
|
||||||
|
|
||||||
|
local function put_player_in_spawn(obj)
|
||||||
|
warn_invalid_static_spawnpoint()
|
||||||
|
local static_spawnpoint = minetest.setting_get_pos("static_spawnpoint")
|
||||||
|
if not static_spawnpoint then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
minetest.log('action', "Moving "..obj:get_player_name()..
|
||||||
|
" to static spawnpoint at "..
|
||||||
|
minetest.pos_to_string(static_spawnpoint))
|
||||||
|
obj:setpos(static_spawnpoint)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_newplayer(function(obj)
|
||||||
|
put_player_in_spawn(obj)
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_respawnplayer(function(obj)
|
||||||
|
return put_player_in_spawn(obj)
|
||||||
|
end)
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ ENDIF()
|
|||||||
IF(GETTEXT_FOUND)
|
IF(GETTEXT_FOUND)
|
||||||
SET(GETTEXT_PO_PATH ${CMAKE_SOURCE_DIR}/po)
|
SET(GETTEXT_PO_PATH ${CMAKE_SOURCE_DIR}/po)
|
||||||
SET(GETTEXT_MO_BUILD_PATH ${CMAKE_BINARY_DIR}/locale/<locale>/LC_MESSAGES)
|
SET(GETTEXT_MO_BUILD_PATH ${CMAKE_BINARY_DIR}/locale/<locale>/LC_MESSAGES)
|
||||||
SET(GETTEXT_MO_DEST_PATH ${DATADIR}/../locale/<locale>/LC_MESSAGES)
|
SET(GETTEXT_MO_DEST_PATH ${LOCALEDIR}/<locale>/LC_MESSAGES)
|
||||||
FILE(GLOB GETTEXT_AVAILABLE_LOCALES RELATIVE ${GETTEXT_PO_PATH} "${GETTEXT_PO_PATH}/*")
|
FILE(GLOB GETTEXT_AVAILABLE_LOCALES RELATIVE ${GETTEXT_PO_PATH} "${GETTEXT_PO_PATH}/*")
|
||||||
LIST(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES minetest.pot)
|
LIST(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES minetest.pot)
|
||||||
MACRO(SET_MO_PATHS _buildvar _destvar _locale)
|
MACRO(SET_MO_PATHS _buildvar _destvar _locale)
|
||||||
|
|||||||
46
cmake/Modules/FindVorbis.cmake
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# - Find vorbis
|
||||||
|
# Find the native vorbis includes and libraries
|
||||||
|
#
|
||||||
|
# VORBIS_INCLUDE_DIR - where to find vorbis.h, etc.
|
||||||
|
# OGG_INCLUDE_DIR - where to find ogg/ogg.h, etc.
|
||||||
|
# VORBIS_LIBRARIES - List of libraries when using vorbis(file).
|
||||||
|
# VORBIS_FOUND - True if vorbis found.
|
||||||
|
|
||||||
|
if(NOT GP2XWIZ)
|
||||||
|
if(VORBIS_INCLUDE_DIR)
|
||||||
|
# Already in cache, be silent
|
||||||
|
set(VORBIS_FIND_QUIETLY TRUE)
|
||||||
|
endif(VORBIS_INCLUDE_DIR)
|
||||||
|
find_path(OGG_INCLUDE_DIR ogg/ogg.h)
|
||||||
|
find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h)
|
||||||
|
# MSVC built ogg/vorbis may be named ogg_static and vorbis_static
|
||||||
|
find_library(OGG_LIBRARY NAMES ogg ogg_static)
|
||||||
|
find_library(VORBIS_LIBRARY NAMES vorbis vorbis_static)
|
||||||
|
find_library(VORBISFILE_LIBRARY NAMES vorbisfile vorbisfile_static)
|
||||||
|
# Handle the QUIETLY and REQUIRED arguments and set VORBIS_FOUND
|
||||||
|
# to TRUE if all listed variables are TRUE.
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(VORBIS DEFAULT_MSG
|
||||||
|
OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR
|
||||||
|
OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY)
|
||||||
|
else(NOT GP2XWIZ)
|
||||||
|
find_path(VORBIS_INCLUDE_DIR tremor/ivorbisfile.h)
|
||||||
|
find_library(VORBIS_LIBRARY NAMES vorbis_dec)
|
||||||
|
find_package_handle_standard_args(VORBIS DEFAULT_MSG
|
||||||
|
VORBIS_INCLUDE_DIR VORBIS_LIBRARY)
|
||||||
|
endif(NOT GP2XWIZ)
|
||||||
|
|
||||||
|
if(VORBIS_FOUND)
|
||||||
|
if(NOT GP2XWIZ)
|
||||||
|
set(VORBIS_LIBRARIES ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY}
|
||||||
|
${OGG_LIBRARY})
|
||||||
|
else(NOT GP2XWIZ)
|
||||||
|
set(VORBIS_LIBRARIES ${VORBIS_LIBRARY})
|
||||||
|
endif(NOT GP2XWIZ)
|
||||||
|
else(VORBIS_FOUND)
|
||||||
|
set(VORBIS_LIBRARIES)
|
||||||
|
endif(VORBIS_FOUND)
|
||||||
|
|
||||||
|
mark_as_advanced(OGG_INCLUDE_DIR VORBIS_INCLUDE_DIR)
|
||||||
|
mark_as_advanced(OGG_LIBRARY VORBIS_LIBRARY VORBISFILE_LIBRARY)
|
||||||
|
|
||||||
359
data/builtin.lua
@@ -1,359 +0,0 @@
|
|||||||
--
|
|
||||||
-- This file contains built-in stuff in Minetest implemented in Lua.
|
|
||||||
--
|
|
||||||
-- It is always loaded and executed after registration of the C API,
|
|
||||||
-- before loading and running any mods.
|
|
||||||
--
|
|
||||||
|
|
||||||
function basic_dump2(o)
|
|
||||||
if type(o) == "number" then
|
|
||||||
return tostring(o)
|
|
||||||
elseif type(o) == "string" then
|
|
||||||
return string.format("%q", o)
|
|
||||||
elseif type(o) == "boolean" then
|
|
||||||
return tostring(o)
|
|
||||||
elseif type(o) == "function" then
|
|
||||||
return "<function>"
|
|
||||||
elseif type(o) == "userdata" then
|
|
||||||
return "<userdata>"
|
|
||||||
elseif type(o) == "nil" then
|
|
||||||
return "nil"
|
|
||||||
else
|
|
||||||
error("cannot dump a " .. type(o))
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function dump2(o, name, dumped)
|
|
||||||
name = name or "_"
|
|
||||||
dumped = dumped or {}
|
|
||||||
io.write(name, " = ")
|
|
||||||
if type(o) == "number" or type(o) == "string" or type(o) == "boolean"
|
|
||||||
or type(o) == "function" or type(o) == "nil"
|
|
||||||
or type(o) == "userdata" then
|
|
||||||
io.write(basic_dump2(o), "\n")
|
|
||||||
elseif type(o) == "table" then
|
|
||||||
if dumped[o] then
|
|
||||||
io.write(dumped[o], "\n")
|
|
||||||
else
|
|
||||||
dumped[o] = name
|
|
||||||
io.write("{}\n") -- new table
|
|
||||||
for k,v in pairs(o) do
|
|
||||||
local fieldname = string.format("%s[%s]", name, basic_dump2(k))
|
|
||||||
dump2(v, fieldname, dumped)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
error("cannot dump a " .. type(o))
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function dump(o, dumped)
|
|
||||||
dumped = dumped or {}
|
|
||||||
if type(o) == "number" then
|
|
||||||
return tostring(o)
|
|
||||||
elseif type(o) == "string" then
|
|
||||||
return string.format("%q", o)
|
|
||||||
elseif type(o) == "table" then
|
|
||||||
if dumped[o] then
|
|
||||||
return "<circular reference>"
|
|
||||||
end
|
|
||||||
dumped[o] = true
|
|
||||||
local t = {}
|
|
||||||
for k,v in pairs(o) do
|
|
||||||
t[#t+1] = "" .. k .. " = " .. dump(v, dumped)
|
|
||||||
end
|
|
||||||
return "{" .. table.concat(t, ", ") .. "}"
|
|
||||||
elseif type(o) == "boolean" then
|
|
||||||
return tostring(o)
|
|
||||||
elseif type(o) == "function" then
|
|
||||||
return "<function>"
|
|
||||||
elseif type(o) == "userdata" then
|
|
||||||
return "<userdata>"
|
|
||||||
elseif type(o) == "nil" then
|
|
||||||
return "nil"
|
|
||||||
else
|
|
||||||
error("cannot dump a " .. type(o))
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Built-in node definitions. Also defined in C.
|
|
||||||
--
|
|
||||||
|
|
||||||
minetest.register_nodedef_defaults({
|
|
||||||
-- name intentionally not defined here
|
|
||||||
drawtype = "normal",
|
|
||||||
visual_scale = 1.0,
|
|
||||||
tile_images = {"unknown_block.png"},
|
|
||||||
inventory_image = "unknown_block.png",
|
|
||||||
special_materials = {
|
|
||||||
{image="", backface_culling=true},
|
|
||||||
{image="", backface_culling=true},
|
|
||||||
},
|
|
||||||
alpha = 255,
|
|
||||||
post_effect_color = {a=0, r=0, g=0, b=0},
|
|
||||||
paramtype = "none",
|
|
||||||
is_ground_content = false,
|
|
||||||
light_propagates = false,
|
|
||||||
sunlight_propagates = false,
|
|
||||||
walkable = true,
|
|
||||||
pointable = true,
|
|
||||||
diggable = true,
|
|
||||||
climbable = false,
|
|
||||||
buildable_to = false,
|
|
||||||
wall_mounted = false,
|
|
||||||
often_contains_mineral = false,
|
|
||||||
dug_item = "",
|
|
||||||
extra_dug_item = "",
|
|
||||||
extra_dug_item_rarity = 2,
|
|
||||||
metadata_name = "",
|
|
||||||
liquidtype = "none",
|
|
||||||
liquid_alternative_flowing = "",
|
|
||||||
liquid_alternative_source = "",
|
|
||||||
liquid_viscosity = 0,
|
|
||||||
light_source = 0,
|
|
||||||
damage_per_second = 0,
|
|
||||||
selection_box = {type="regular"},
|
|
||||||
material = {
|
|
||||||
diggablity = "normal",
|
|
||||||
weight = 0,
|
|
||||||
crackiness = 0,
|
|
||||||
crumbliness = 0,
|
|
||||||
cuttability = 0,
|
|
||||||
flammability = 0,
|
|
||||||
},
|
|
||||||
cookresult_item = "", -- Cannot be cooked
|
|
||||||
furnace_cooktime = 3.0,
|
|
||||||
furnace_burntime = -1, -- Cannot be used as fuel
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("air", {
|
|
||||||
drawtype = "airlike",
|
|
||||||
paramtype = "light",
|
|
||||||
light_propagates = true,
|
|
||||||
sunlight_propagates = true,
|
|
||||||
walkable = false,
|
|
||||||
pointable = false,
|
|
||||||
diggable = false,
|
|
||||||
buildable_to = true,
|
|
||||||
air_equivalent = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("ignore", {
|
|
||||||
drawtype = "airlike",
|
|
||||||
paramtype = "none",
|
|
||||||
light_propagates = false,
|
|
||||||
sunlight_propagates = false,
|
|
||||||
walkable = false,
|
|
||||||
pointable = false,
|
|
||||||
diggable = false,
|
|
||||||
buildable_to = true, -- A way to remove accidentally placed ignores
|
|
||||||
air_equivalent = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
|
||||||
-- stackstring manipulation functions
|
|
||||||
-- example stackstring: 'craft "apple" 4'
|
|
||||||
-- example item: {type="craft", name="apple"}
|
|
||||||
-- example item: {type="tool", name="SteelPick", wear="23272"}
|
|
||||||
--
|
|
||||||
|
|
||||||
function stackstring_take_item(stackstring)
|
|
||||||
if stackstring == nil then
|
|
||||||
return '', nil
|
|
||||||
end
|
|
||||||
local stacktype = nil
|
|
||||||
stacktype = string.match(stackstring,
|
|
||||||
'([%a%d]+)')
|
|
||||||
if stacktype == "node" or stacktype == "craft" then
|
|
||||||
local itemtype = nil
|
|
||||||
local itemname = nil
|
|
||||||
local itemcount = nil
|
|
||||||
itemtype, itemname, itemcount = string.match(stackstring,
|
|
||||||
'([%a%d]+) "([^"]*)" (%d+)')
|
|
||||||
itemcount = tonumber(itemcount)
|
|
||||||
if itemcount == 0 then
|
|
||||||
return '', nil
|
|
||||||
elseif itemcount == 1 then
|
|
||||||
return '', {type=itemtype, name=itemname}
|
|
||||||
else
|
|
||||||
return itemtype.." \""..itemname.."\" "..(itemcount-1),
|
|
||||||
{type=itemtype, name=itemname}
|
|
||||||
end
|
|
||||||
elseif stacktype == "tool" then
|
|
||||||
local itemtype = nil
|
|
||||||
local itemname = nil
|
|
||||||
local itemwear = nil
|
|
||||||
itemtype, itemname, itemwear = string.match(stackstring,
|
|
||||||
'([%a%d]+) "([^"]*)" (%d+)')
|
|
||||||
itemwear = tonumber(itemwear)
|
|
||||||
return '', {type=itemtype, name=itemname, wear=itemwear}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function stackstring_put_item(stackstring, item)
|
|
||||||
if item == nil then
|
|
||||||
return stackstring, false
|
|
||||||
end
|
|
||||||
stackstring = stackstring or ''
|
|
||||||
local stacktype = nil
|
|
||||||
stacktype = string.match(stackstring,
|
|
||||||
'([%a%d]+)')
|
|
||||||
stacktype = stacktype or ''
|
|
||||||
if stacktype ~= '' and stacktype ~= item.type then
|
|
||||||
return stackstring, false
|
|
||||||
end
|
|
||||||
if item.type == "node" or item.type == "craft" then
|
|
||||||
local itemtype = nil
|
|
||||||
local itemname = nil
|
|
||||||
local itemcount = nil
|
|
||||||
itemtype, itemname, itemcount = string.match(stackstring,
|
|
||||||
'([%a%d]+) "([^"]*)" (%d+)')
|
|
||||||
itemtype = itemtype or item.type
|
|
||||||
itemname = itemname or item.name
|
|
||||||
if itemcount == nil then
|
|
||||||
itemcount = 0
|
|
||||||
end
|
|
||||||
itemcount = itemcount + 1
|
|
||||||
return itemtype.." \""..itemname.."\" "..itemcount, true
|
|
||||||
elseif item.type == "tool" then
|
|
||||||
if stacktype ~= nil then
|
|
||||||
return stackstring, false
|
|
||||||
end
|
|
||||||
local itemtype = nil
|
|
||||||
local itemname = nil
|
|
||||||
local itemwear = nil
|
|
||||||
itemtype, itemname, itemwear = string.match(stackstring,
|
|
||||||
'([%a%d]+) "([^"]*)" (%d+)')
|
|
||||||
itemwear = tonumber(itemwear)
|
|
||||||
return itemtype.." \""..itemname.."\" "..itemwear, true
|
|
||||||
end
|
|
||||||
return stackstring, false
|
|
||||||
end
|
|
||||||
|
|
||||||
function stackstring_put_stackstring(stackstring, src)
|
|
||||||
while src ~= '' do
|
|
||||||
--print("src="..dump(src))
|
|
||||||
src, item = stackstring_take_item(src)
|
|
||||||
--print("src="..dump(src).." item="..dump(item))
|
|
||||||
local success
|
|
||||||
stackstring, success = stackstring_put_item(stackstring, item)
|
|
||||||
if not success then
|
|
||||||
return stackstring, false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return stackstring, true
|
|
||||||
end
|
|
||||||
|
|
||||||
function test_stackstring()
|
|
||||||
local stack
|
|
||||||
local item
|
|
||||||
local success
|
|
||||||
|
|
||||||
stack, item = stackstring_take_item('node "TNT" 3')
|
|
||||||
assert(stack == 'node "TNT" 2')
|
|
||||||
assert(item.type == 'node')
|
|
||||||
assert(item.name == 'TNT')
|
|
||||||
|
|
||||||
stack, item = stackstring_take_item('craft "with spaces" 2')
|
|
||||||
assert(stack == 'craft "with spaces" 1')
|
|
||||||
assert(item.type == 'craft')
|
|
||||||
assert(item.name == 'with spaces')
|
|
||||||
|
|
||||||
stack, item = stackstring_take_item('craft "with spaces" 1')
|
|
||||||
assert(stack == '')
|
|
||||||
assert(item.type == 'craft')
|
|
||||||
assert(item.name == 'with spaces')
|
|
||||||
|
|
||||||
stack, item = stackstring_take_item('craft "s8df2kj3" 0')
|
|
||||||
assert(stack == '')
|
|
||||||
assert(item == nil)
|
|
||||||
|
|
||||||
stack, item = stackstring_take_item('tool "With Spaces" 32487')
|
|
||||||
assert(stack == '')
|
|
||||||
assert(item.type == 'tool')
|
|
||||||
assert(item.name == 'With Spaces')
|
|
||||||
assert(item.wear == 32487)
|
|
||||||
|
|
||||||
stack, success = stackstring_put_item('node "With Spaces" 40',
|
|
||||||
{type='node', name='With Spaces'})
|
|
||||||
assert(stack == 'node "With Spaces" 41')
|
|
||||||
assert(success == true)
|
|
||||||
|
|
||||||
stack, success = stackstring_put_item('craft "With Spaces" 40',
|
|
||||||
{type='craft', name='With Spaces'})
|
|
||||||
assert(stack == 'craft "With Spaces" 41')
|
|
||||||
assert(success == true)
|
|
||||||
|
|
||||||
stack, success = stackstring_put_item('tool "With Spaces" 32487',
|
|
||||||
{type='tool', name='With Spaces'})
|
|
||||||
assert(stack == 'tool "With Spaces" 32487')
|
|
||||||
assert(success == false)
|
|
||||||
|
|
||||||
stack, success = stackstring_put_item('node "With Spaces" 40',
|
|
||||||
{type='tool', name='With Spaces'})
|
|
||||||
assert(stack == 'node "With Spaces" 40')
|
|
||||||
assert(success == false)
|
|
||||||
|
|
||||||
assert(stackstring_put_stackstring('node "With Spaces" 2',
|
|
||||||
'node "With Spaces" 1') == 'node "With Spaces" 3')
|
|
||||||
end
|
|
||||||
test_stackstring()
|
|
||||||
|
|
||||||
--
|
|
||||||
-- craftitem helpers
|
|
||||||
--
|
|
||||||
|
|
||||||
minetest.craftitem_place_item = function(item, placer, pos)
|
|
||||||
--print("craftitem_place_item")
|
|
||||||
--print("item: " .. dump(item))
|
|
||||||
--print("placer: " .. dump(placer))
|
|
||||||
--print("pos: " .. dump(pos))
|
|
||||||
minetest.env:add_item(pos, 'craft "' .. item .. '" 1')
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.craftitem_eat = function(hp_change)
|
|
||||||
return function(item, user, pointed_thing) -- closure
|
|
||||||
--print("craftitem_eat(" .. hp_change .. ")")
|
|
||||||
--print("item: " .. dump(item))
|
|
||||||
--print("user: " .. dump(user))
|
|
||||||
--print("pointed_thing: " .. dump(pointed_thing))
|
|
||||||
user:set_hp(user:get_hp() + hp_change)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Creative inventory
|
|
||||||
--
|
|
||||||
|
|
||||||
minetest.creative_inventory = {}
|
|
||||||
|
|
||||||
minetest.add_to_creative_inventory = function(itemstring)
|
|
||||||
table.insert(minetest.creative_inventory, itemstring)
|
|
||||||
end
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Callback registration
|
|
||||||
--
|
|
||||||
|
|
||||||
function make_registration()
|
|
||||||
local t = {}
|
|
||||||
local registerfunc = function(func) table.insert(t, func) end
|
|
||||||
return t, registerfunc
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
|
|
||||||
minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
|
|
||||||
minetest.registered_on_placenodes, minetest.register_on_placenode = make_registration()
|
|
||||||
minetest.registered_on_dignodes, minetest.register_on_dignode = make_registration()
|
|
||||||
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
|
|
||||||
minetest.registered_on_generateds, minetest.register_on_generated = make_registration()
|
|
||||||
minetest.registered_on_newplayers, minetest.register_on_newplayer = make_registration()
|
|
||||||
minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
|
|
||||||
|
|
||||||
-- END
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
minetest.register_craft({
|
|
||||||
output = 'craft "bucket" 1',
|
|
||||||
recipe = {
|
|
||||||
{'craft "steel_ingot"', '', 'craft "steel_ingot"'},
|
|
||||||
{'', 'craft "steel_ingot"', ''},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craftitem("bucket", {
|
|
||||||
image = "bucket.png",
|
|
||||||
stack_max = 1,
|
|
||||||
liquids_pointable = true,
|
|
||||||
on_place_on_ground = minetest.craftitem_place_item,
|
|
||||||
on_use = function(item, player, pointed_thing)
|
|
||||||
if pointed_thing.type == "node" then
|
|
||||||
n = minetest.env:get_node(pointed_thing.under)
|
|
||||||
if n.name == "water_source" then
|
|
||||||
minetest.env:add_node(pointed_thing.under, {name="air"})
|
|
||||||
player:add_to_inventory_later('craft "bucket_water" 1')
|
|
||||||
return true
|
|
||||||
elseif n.name == "lava_source" then
|
|
||||||
minetest.env:add_node(pointed_thing.under, {name="air"})
|
|
||||||
player:add_to_inventory_later('craft "bucket_lava" 1')
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craftitem("bucket_water", {
|
|
||||||
image = "bucket_water.png",
|
|
||||||
stack_max = 1,
|
|
||||||
liquids_pointable = true,
|
|
||||||
on_place_on_ground = minetest.craftitem_place_item,
|
|
||||||
on_use = function(item, player, pointed_thing)
|
|
||||||
if pointed_thing.type == "node" then
|
|
||||||
n = minetest.env:get_node(pointed_thing.under)
|
|
||||||
if n.name == "water_source" then
|
|
||||||
-- unchanged
|
|
||||||
elseif n.name == "water_flowing" or n.name == "lava_source" or n.name == "lava_flowing" then
|
|
||||||
minetest.env:add_node(pointed_thing.under, {name="water_source"})
|
|
||||||
else
|
|
||||||
minetest.env:add_node(pointed_thing.above, {name="water_source"})
|
|
||||||
end
|
|
||||||
player:add_to_inventory_later('craft "bucket" 1')
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craftitem("bucket_lava", {
|
|
||||||
image = "bucket_lava.png",
|
|
||||||
stack_max = 1,
|
|
||||||
liquids_pointable = true,
|
|
||||||
on_place_on_ground = minetest.craftitem_place_item,
|
|
||||||
on_use = function(item, player, pointed_thing)
|
|
||||||
if pointed_thing.type == "node" then
|
|
||||||
n = minetest.env:get_node(pointed_thing.under)
|
|
||||||
if n.name == "lava_source" then
|
|
||||||
-- unchanged
|
|
||||||
elseif n.name == "water_source" or n.name == "water_flowing" or n.name == "lava_flowing" then
|
|
||||||
minetest.env:add_node(pointed_thing.under, {name="lava_source"})
|
|
||||||
else
|
|
||||||
minetest.env:add_node(pointed_thing.above, {name="lava_source"})
|
|
||||||
end
|
|
||||||
player:add_to_inventory_later('craft "bucket" 1')
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 236 B |
|
Before Width: | Height: | Size: 598 B |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 231 B |
|
Before Width: | Height: | Size: 199 B |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 190 B |
|
Before Width: | Height: | Size: 190 B |
|
Before Width: | Height: | Size: 190 B |
@@ -1,398 +0,0 @@
|
|||||||
--
|
|
||||||
-- Experimental things
|
|
||||||
--
|
|
||||||
|
|
||||||
-- An example furnace-thing implemented in Lua
|
|
||||||
|
|
||||||
minetest.register_node("luafurnace", {
|
|
||||||
tile_images = {"lava.png", "furnace_side.png", "furnace_side.png",
|
|
||||||
"furnace_side.png", "furnace_side.png", "furnace_front.png"},
|
|
||||||
--inventory_image = "furnace_front.png",
|
|
||||||
inventory_image = inventorycube("furnace_front.png"),
|
|
||||||
paramtype = "facedir_simple",
|
|
||||||
metadata_name = "generic",
|
|
||||||
material = digprop_stonelike(3.0),
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_on_placenode(function(pos, newnode, placer)
|
|
||||||
if newnode.name == "luafurnace" then
|
|
||||||
print("get_meta");
|
|
||||||
local meta = minetest.env:get_meta(pos)
|
|
||||||
print("inventory_set_list");
|
|
||||||
meta:inventory_set_list("fuel", {""})
|
|
||||||
print("inventory_set_list");
|
|
||||||
meta:inventory_set_list("src", {""})
|
|
||||||
print("inventory_set_list");
|
|
||||||
meta:inventory_set_list("dst", {"","","",""})
|
|
||||||
print("set_inventory_draw_spec");
|
|
||||||
meta:set_inventory_draw_spec(
|
|
||||||
"invsize[8,9;]"
|
|
||||||
.."list[current_name;fuel;2,3;1,1;]"
|
|
||||||
.."list[current_name;src;2,1;1,1;]"
|
|
||||||
.."list[current_name;dst;5,1;2,2;]"
|
|
||||||
.."list[current_player;main;0,5;8,4;]"
|
|
||||||
)
|
|
||||||
|
|
||||||
local total_cooked = 0;
|
|
||||||
print("set_string")
|
|
||||||
meta:set_string("total_cooked", total_cooked)
|
|
||||||
print("set_infotext");
|
|
||||||
meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_abm({
|
|
||||||
nodenames = {"luafurnace"},
|
|
||||||
interval = 1.0,
|
|
||||||
chance = 1,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
local meta = minetest.env:get_meta(pos)
|
|
||||||
local fuellist = meta:inventory_get_list("fuel")
|
|
||||||
local srclist = meta:inventory_get_list("src")
|
|
||||||
local dstlist = meta:inventory_get_list("dst")
|
|
||||||
if fuellist == nil or srclist == nil or dstlist == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
_, srcitem = stackstring_take_item(srclist[1])
|
|
||||||
_, fuelitem = stackstring_take_item(fuellist[1])
|
|
||||||
if not srcitem or not fuelitem then return end
|
|
||||||
if fuelitem.type == "node" then
|
|
||||||
local prop = minetest.registered_nodes[fuelitem.name]
|
|
||||||
if prop == nil then return end
|
|
||||||
if prop.furnace_burntime < 0 then return end
|
|
||||||
else
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local resultstack = nil
|
|
||||||
if srcitem.type == "node" then
|
|
||||||
local prop = minetest.registered_nodes[srcitem.name]
|
|
||||||
if prop == nil then return end
|
|
||||||
if prop.cookresult_item == "" then return end
|
|
||||||
resultstack = prop.cookresult_item
|
|
||||||
else
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if resultstack == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
dstlist[1], success = stackstring_put_stackstring(dstlist[1], resultstack)
|
|
||||||
if not success then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
fuellist[1], _ = stackstring_take_item(fuellist[1])
|
|
||||||
srclist[1], _ = stackstring_take_item(srclist[1])
|
|
||||||
|
|
||||||
meta:inventory_set_list("fuel", fuellist)
|
|
||||||
meta:inventory_set_list("src", srclist)
|
|
||||||
meta:inventory_set_list("dst", dstlist)
|
|
||||||
|
|
||||||
local total_cooked = meta:get_string("total_cooked")
|
|
||||||
total_cooked = tonumber(total_cooked) + 1
|
|
||||||
meta:set_string("total_cooked", total_cooked)
|
|
||||||
meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'node "luafurnace" 1',
|
|
||||||
recipe = {
|
|
||||||
{'node "cobble"', 'node "cobble"', 'node "cobble"'},
|
|
||||||
{'node "cobble"', 'node "cobble"', 'node "cobble"'},
|
|
||||||
{'node "cobble"', 'node "cobble"', 'node "cobble"'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Random stuff
|
|
||||||
--
|
|
||||||
|
|
||||||
--[[
|
|
||||||
minetest.register_tool("horribletool", {
|
|
||||||
image = "lava.png",
|
|
||||||
basetime = 2.0
|
|
||||||
dt_weight = 0.2
|
|
||||||
dt_crackiness = 0.2
|
|
||||||
dt_crumbliness = 0.2
|
|
||||||
dt_cuttability = 0.2
|
|
||||||
basedurability = 50
|
|
||||||
dd_weight = -5
|
|
||||||
dd_crackiness = -5
|
|
||||||
dd_crumbliness = -5
|
|
||||||
dd_cuttability = -5
|
|
||||||
})
|
|
||||||
--]]
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'node "somenode" 4',
|
|
||||||
recipe = {
|
|
||||||
{'craft "Stick" 1'},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("somenode", {
|
|
||||||
tile_images = {"lava.png", "mese.png", "stone.png", "grass.png", "cobble.png", "tree_top.png"},
|
|
||||||
inventory_image = "treeprop.png",
|
|
||||||
material = {
|
|
||||||
diggability = "normal",
|
|
||||||
weight = 0,
|
|
||||||
crackiness = 0,
|
|
||||||
crumbliness = 0,
|
|
||||||
cuttability = 0,
|
|
||||||
flammability = 0
|
|
||||||
},
|
|
||||||
metadata_name = "chest",
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
|
||||||
-- TNT (not functional)
|
|
||||||
--
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = 'node "TNT" 4',
|
|
||||||
recipe = {
|
|
||||||
{'node "wood" 1'},
|
|
||||||
{'craft "lump_of_coal" 1'},
|
|
||||||
{'node "wood" 1'}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("TNT", {
|
|
||||||
tile_images = {"tnt_top.png", "tnt_bottom.png", "tnt_side.png", "tnt_side.png", "tnt_side.png", "tnt_side.png"},
|
|
||||||
inventory_image = "tnt_side.png",
|
|
||||||
dug_item = '', -- Get nothing
|
|
||||||
material = {
|
|
||||||
diggability = "not",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
local TNT = {
|
|
||||||
-- Static definition
|
|
||||||
physical = true, -- Collides with things
|
|
||||||
-- weight = 5,
|
|
||||||
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
|
||||||
visual = "cube",
|
|
||||||
textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"},
|
|
||||||
-- Initial value for our timer
|
|
||||||
timer = 0,
|
|
||||||
-- Number of punches required to defuse
|
|
||||||
health = 1,
|
|
||||||
blinktimer = 0,
|
|
||||||
blinkstatus = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Called when a TNT object is created
|
|
||||||
function TNT:on_activate(staticdata)
|
|
||||||
print("TNT:on_activate()")
|
|
||||||
self.object:setvelocity({x=0, y=4, z=0})
|
|
||||||
self.object:setacceleration({x=0, y=-10, z=0})
|
|
||||||
self.object:settexturemod("^[brighten")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Called periodically
|
|
||||||
function TNT:on_step(dtime)
|
|
||||||
--print("TNT:on_step()")
|
|
||||||
self.timer = self.timer + dtime
|
|
||||||
self.blinktimer = self.blinktimer + dtime
|
|
||||||
if self.blinktimer > 0.5 then
|
|
||||||
self.blinktimer = self.blinktimer - 0.5
|
|
||||||
if self.blinkstatus then
|
|
||||||
self.object:settexturemod("")
|
|
||||||
else
|
|
||||||
self.object:settexturemod("^[brighten")
|
|
||||||
end
|
|
||||||
self.blinkstatus = not self.blinkstatus
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Called when object is punched
|
|
||||||
function TNT:on_punch(hitter)
|
|
||||||
print("TNT:on_punch()")
|
|
||||||
self.health = self.health - 1
|
|
||||||
if self.health <= 0 then
|
|
||||||
self.object:remove()
|
|
||||||
hitter:add_to_inventory("node TNT 1")
|
|
||||||
hitter:set_hp(hitter:get_hp() - 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Called when object is right-clicked
|
|
||||||
function TNT:on_rightclick(clicker)
|
|
||||||
--pos = self.object:getpos()
|
|
||||||
--pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
|
|
||||||
--self.object:moveto(pos, false)
|
|
||||||
end
|
|
||||||
|
|
||||||
print("TNT dump: "..dump(TNT))
|
|
||||||
|
|
||||||
print("Registering TNT");
|
|
||||||
minetest.register_entity("TNT", TNT)
|
|
||||||
|
|
||||||
--
|
|
||||||
-- A test entity for testing animated and yaw-modulated sprites
|
|
||||||
--
|
|
||||||
|
|
||||||
minetest.register_entity("testentity", {
|
|
||||||
-- Static definition
|
|
||||||
physical = true, -- Collides with things
|
|
||||||
-- weight = 5,
|
|
||||||
collisionbox = {-0.7,-1.35,-0.7, 0.7,1.0,0.7},
|
|
||||||
--collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
|
||||||
visual = "sprite",
|
|
||||||
visual_size = {x=2, y=3},
|
|
||||||
textures = {"dungeon_master.png^[makealpha:128,0,0^[makealpha:128,128,0"},
|
|
||||||
spritediv = {x=6, y=5},
|
|
||||||
initial_sprite_basepos = {x=0, y=0},
|
|
||||||
|
|
||||||
on_activate = function(self, staticdata)
|
|
||||||
print("testentity.on_activate")
|
|
||||||
self.object:setsprite({x=0,y=0}, 1, 0, true)
|
|
||||||
--self.object:setsprite({x=0,y=0}, 4, 0.3, true)
|
|
||||||
|
|
||||||
-- Set gravity
|
|
||||||
self.object:setacceleration({x=0, y=-10, z=0})
|
|
||||||
-- Jump a bit upwards
|
|
||||||
self.object:setvelocity({x=0, y=10, z=0})
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_punch = function(self, hitter)
|
|
||||||
self.object:remove()
|
|
||||||
hitter:add_to_inventory('craft testobject1 1')
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
|
||||||
-- More random stuff
|
|
||||||
--
|
|
||||||
|
|
||||||
minetest.register_on_respawnplayer(function(player)
|
|
||||||
print("on_respawnplayer")
|
|
||||||
-- player:setpos({x=0, y=30, z=0})
|
|
||||||
-- return true
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_generated(function(minp, maxp)
|
|
||||||
--print("on_generated: minp="..dump(minp).." maxp="..dump(maxp))
|
|
||||||
--cp = {x=(minp.x+maxp.x)/2, y=(minp.y+maxp.y)/2, z=(minp.z+maxp.z)/2}
|
|
||||||
--minetest.env:add_node(cp, {name="sand"})
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Example setting get
|
|
||||||
print("setting max_users = " .. dump(minetest.setting_get("max_users")))
|
|
||||||
print("setting asdf = " .. dump(minetest.setting_get("asdf")))
|
|
||||||
|
|
||||||
minetest.register_on_chat_message(function(name, message)
|
|
||||||
--[[print("on_chat_message: name="..dump(name).." message="..dump(message))
|
|
||||||
local cmd = "/testcommand"
|
|
||||||
if message:sub(0, #cmd) == cmd then
|
|
||||||
print(cmd.." invoked")
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
local cmd = "/help"
|
|
||||||
if message:sub(0, #cmd) == cmd then
|
|
||||||
print("script-overridden help command")
|
|
||||||
minetest.chat_send_all("script-overridden help command")
|
|
||||||
return true
|
|
||||||
end]]
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Grow papyrus on TNT every 10 seconds
|
|
||||||
--[[minetest.register_abm({
|
|
||||||
nodenames = {"TNT"},
|
|
||||||
interval = 10.0,
|
|
||||||
chance = 1,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
print("TNT ABM action")
|
|
||||||
pos.y = pos.y + 1
|
|
||||||
minetest.env:add_node(pos, {name="papyrus"})
|
|
||||||
end,
|
|
||||||
})]]
|
|
||||||
|
|
||||||
-- Replace texts of alls signs with "foo" every 10 seconds
|
|
||||||
--[[minetest.register_abm({
|
|
||||||
nodenames = {"sign_wall"},
|
|
||||||
interval = 10.0,
|
|
||||||
chance = 1,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
print("ABM: Sign text changed")
|
|
||||||
local meta = minetest.env:get_meta(pos)
|
|
||||||
meta:set_text("foo")
|
|
||||||
end,
|
|
||||||
})]]
|
|
||||||
|
|
||||||
--[[local ncpos = nil
|
|
||||||
local ncq = 1
|
|
||||||
local ncstuff = {
|
|
||||||
{2, 1, 0, 3}, {3, 0, 1, 2}, {4, -1, 0, 1}, {5, -1, 0, 1}, {6, 0, -1, 0},
|
|
||||||
{7, 0, -1, 0}, {8, 1, 0, 3}, {9, 1, 0, 3}, {10, 1, 0, 3}, {11, 0, 1, 2},
|
|
||||||
{12, 0, 1, 2}, {13, 0, 1, 2}, {14, -1, 0, 1}, {15, -1, 0, 1}, {16, -1, 0, 1},
|
|
||||||
{17, -1, 0, 1}, {18, 0, -1, 0}, {19, 0, -1, 0}, {20, 0, -1, 0}, {21, 0, -1, 0},
|
|
||||||
{22, 1, 0, 3}, {23, 1, 0, 3}, {24, 1, 0, 3}, {25, 1, 0, 3}, {10, 0, 1, 2}
|
|
||||||
}
|
|
||||||
local ncold = {}
|
|
||||||
local nctime = nil
|
|
||||||
|
|
||||||
minetest.register_abm({
|
|
||||||
nodenames = {"dirt_with_grass"},
|
|
||||||
interval = 100000.0,
|
|
||||||
chance = 1,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
if ncpos ~= nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if pos.x % 16 ~= 8 or pos.z % 16 ~= 8 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
pos.y = pos.y + 1
|
|
||||||
n = minetest.env:get_node(pos)
|
|
||||||
print(dump(n))
|
|
||||||
if n.name ~= "air" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
pos.y = pos.y + 2
|
|
||||||
ncpos = pos
|
|
||||||
nctime = os.clock()
|
|
||||||
minetest.env:add_node(ncpos, {name="nyancat"})
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_abm({
|
|
||||||
nodenames = {"nyancat"},
|
|
||||||
interval = 1.0,
|
|
||||||
chance = 1,
|
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
||||||
if ncpos == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if pos.x == ncpos.x and pos.y == ncpos.y and pos.z == ncpos.z then
|
|
||||||
clock = os.clock()
|
|
||||||
if clock - nctime < 0.1 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
nctime = clock
|
|
||||||
|
|
||||||
s0 = ncstuff[ncq]
|
|
||||||
ncq = s0[1]
|
|
||||||
s1 = ncstuff[ncq]
|
|
||||||
p0 = pos
|
|
||||||
p1 = {x = p0.x + s0[2], y = p0.y, z = p0.z + s0[3]}
|
|
||||||
p2 = {x = p1.x + s1[2], y = p1.y, z = p1.z + s1[3]}
|
|
||||||
table.insert(ncold, 1, p0)
|
|
||||||
while #ncold >= 10 do
|
|
||||||
minetest.env:add_node(ncold[#ncold], {name="air"})
|
|
||||||
table.remove(ncold, #ncold)
|
|
||||||
end
|
|
||||||
minetest.env:add_node(p0, {name="nyancat_rainbow"})
|
|
||||||
minetest.env:add_node(p1, {name="nyancat", param1=s0[4]})
|
|
||||||
minetest.env:add_node(p2, {name="air"})
|
|
||||||
ncpos = p1
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})--]]
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
minetest.register_on_newplayer(function(player)
|
|
||||||
print("on_newplayer")
|
|
||||||
if minetest.setting_getbool("give_initial_stuff") then
|
|
||||||
print("giving give_initial_stuff to player")
|
|
||||||
player:add_to_inventory('tool "SteelPick" 0')
|
|
||||||
player:add_to_inventory('node "torch" 99')
|
|
||||||
player:add_to_inventory('tool "SteelAxe" 0')
|
|
||||||
player:add_to_inventory('tool "SteelShovel" 0')
|
|
||||||
player:add_to_inventory('node "cobble" 99')
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
1253
doc/lua_api.txt
Normal file
@@ -1,7 +1,462 @@
|
|||||||
I'll try to quickly document the newest block format in here (might contain
|
=================================================
|
||||||
errors). Refer to the mapgen or minetestmapper script for the directory
|
Minetest World Format used as of 0.4.dev-20120322
|
||||||
structure and file naming. There are two sector namings possible,
|
=================================================
|
||||||
sector/XXXXZZZZ and sector/XXX/ZZZ.
|
|
||||||
|
This applies to a world format carrying the block serialization version 22
|
||||||
|
which is used at least in version 0.4.dev-20120322.
|
||||||
|
|
||||||
|
The block serialization version used is 22. It does not fully specify every
|
||||||
|
aspect of this format; if compliance with this format is to be checked, it
|
||||||
|
needs to be done by detecting if the files and data indeed follows it.
|
||||||
|
|
||||||
|
Legacy stuff
|
||||||
|
=============
|
||||||
|
Data can, in theory, be contained in the flat file directory structure
|
||||||
|
described below in Version 17, but it is not officially supported. Also you
|
||||||
|
may stumble upon all kinds of oddities in not-so-recent formats.
|
||||||
|
|
||||||
|
Files
|
||||||
|
======
|
||||||
|
Everything is contained in a directory, the name of which is freeform, but
|
||||||
|
often serves as the name of the world.
|
||||||
|
|
||||||
|
Currently the authentication and ban data is stored on a per-world basis. It
|
||||||
|
can be copied over from an old world to a newly created world.
|
||||||
|
|
||||||
|
World
|
||||||
|
|-- auth.txt ----- Authentication data
|
||||||
|
|-- env_meta.txt - Environment metadata
|
||||||
|
|-- ipban.txt ---- Banned ips/users
|
||||||
|
|-- map_meta.txt - Map metadata
|
||||||
|
|-- map.sqlite --- Map data
|
||||||
|
|-- players ------ Player directory
|
||||||
|
| |-- player1 -- Player file
|
||||||
|
| '-- Foo ------ Player file
|
||||||
|
`-- world.mt ----- World metadata
|
||||||
|
|
||||||
|
auth.txt
|
||||||
|
---------
|
||||||
|
Contains authentication data, player per line.
|
||||||
|
<name>:<password hash>:<privilege1,...>
|
||||||
|
Format of password hash is <name><password> SHA1'd, in the base64 encoding.
|
||||||
|
|
||||||
|
Example lines:
|
||||||
|
- Player "celeron55", no password, privileges "interact" and "shout":
|
||||||
|
celeron55::interact,shout
|
||||||
|
- Player "Foo", password "bar", privilege "shout":
|
||||||
|
foo:iEPX+SQWIR3p67lj/0zigSWTKHg:shout
|
||||||
|
- Player "bar", no password, no privileges:
|
||||||
|
bar::
|
||||||
|
|
||||||
|
env_meta.txt
|
||||||
|
-------------
|
||||||
|
Simple global environment variables.
|
||||||
|
Example content (added indentation):
|
||||||
|
game_time = 73471
|
||||||
|
time_of_day = 19118
|
||||||
|
EnvArgsEnd
|
||||||
|
|
||||||
|
ipban.txt
|
||||||
|
----------
|
||||||
|
Banned IP addresses and usernames.
|
||||||
|
Example content (added indentation):
|
||||||
|
123.456.78.9|foo
|
||||||
|
123.456.78.10|bar
|
||||||
|
|
||||||
|
map_meta.txt
|
||||||
|
-------------
|
||||||
|
Simple global map variables.
|
||||||
|
Example content (added indentation):
|
||||||
|
seed = 7980462765762429666
|
||||||
|
[end_of_params]
|
||||||
|
|
||||||
|
map.sqlite
|
||||||
|
-----------
|
||||||
|
Map data.
|
||||||
|
See Map File Format below.
|
||||||
|
|
||||||
|
player1, Foo
|
||||||
|
-------------
|
||||||
|
Player data.
|
||||||
|
Filename can be anything.
|
||||||
|
See Player File Format below.
|
||||||
|
|
||||||
|
world.mt
|
||||||
|
---------
|
||||||
|
World metadata.
|
||||||
|
Example content (added indentation):
|
||||||
|
gameid = mesetint
|
||||||
|
|
||||||
|
Player File Format
|
||||||
|
===================
|
||||||
|
|
||||||
|
- Should be pretty self-explanatory.
|
||||||
|
- Note: position is in nodes * 10
|
||||||
|
|
||||||
|
Example content (added indentation):
|
||||||
|
hp = 11
|
||||||
|
name = celeron55
|
||||||
|
pitch = 39.77
|
||||||
|
position = (-5231.97,15,1961.41)
|
||||||
|
version = 1
|
||||||
|
yaw = 101.37
|
||||||
|
PlayerArgsEnd
|
||||||
|
List main 32
|
||||||
|
Item default:torch 13
|
||||||
|
Item default:pick_steel 1 50112
|
||||||
|
Item experimental:tnt
|
||||||
|
Item default:cobble 99
|
||||||
|
Item default:pick_stone 1 13104
|
||||||
|
Item default:shovel_steel 1 51838
|
||||||
|
Item default:dirt 61
|
||||||
|
Item default:rail 78
|
||||||
|
Item default:coal_lump 3
|
||||||
|
Item default:cobble 99
|
||||||
|
Item default:leaves 22
|
||||||
|
Item default:gravel 52
|
||||||
|
Item default:axe_steel 1 2045
|
||||||
|
Item default:cobble 98
|
||||||
|
Item default:sand 61
|
||||||
|
Item default:water_source 94
|
||||||
|
Item default:glass 2
|
||||||
|
Item default:mossycobble
|
||||||
|
Item default:pick_steel 1 64428
|
||||||
|
Item animalmaterials:bone
|
||||||
|
Item default:sword_steel
|
||||||
|
Item default:sapling
|
||||||
|
Item default:sword_stone 1 10647
|
||||||
|
Item default:dirt 99
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
EndInventoryList
|
||||||
|
List craft 9
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
EndInventoryList
|
||||||
|
List craftpreview 1
|
||||||
|
Empty
|
||||||
|
EndInventoryList
|
||||||
|
List craftresult 1
|
||||||
|
Empty
|
||||||
|
EndInventoryList
|
||||||
|
EndInventory
|
||||||
|
|
||||||
|
Map File Format
|
||||||
|
================
|
||||||
|
|
||||||
|
Minetest maps consist of MapBlocks, chunks of 16x16x16 nodes.
|
||||||
|
|
||||||
|
In addition to the bulk node data, MapBlocks stored on disk also contain
|
||||||
|
other things.
|
||||||
|
|
||||||
|
History
|
||||||
|
--------
|
||||||
|
We need a bit of history in here. Initially Minetest stored maps in a
|
||||||
|
format called the "sectors" format. It was a directory/file structure like
|
||||||
|
this:
|
||||||
|
sectors2/XXX/ZZZ/YYYY
|
||||||
|
For example, the MapBlock at (0,1,-2) was this file:
|
||||||
|
sectors2/000/ffd/0001
|
||||||
|
|
||||||
|
Eventually Minetest outgrow this directory structure, as filesystems were
|
||||||
|
struggling under the amount of files and directories.
|
||||||
|
|
||||||
|
Large servers seriously needed a new format, and thus the base of the
|
||||||
|
current format was invented, suggested by celeron55 and implemented by
|
||||||
|
JacobF.
|
||||||
|
|
||||||
|
SQLite3 was slammed in, and blocks files were directly inserted as blobs
|
||||||
|
in a single table, indexed by integer primary keys, oddly mangled from
|
||||||
|
coordinates.
|
||||||
|
|
||||||
|
Today we know that SQLite3 allows multiple primary keys (which would allow
|
||||||
|
storing coordinates separately), but the format has been kept unchanged for
|
||||||
|
that part. So, this is where it has come.
|
||||||
|
</history>
|
||||||
|
|
||||||
|
So here goes
|
||||||
|
-------------
|
||||||
|
map.sqlite is an sqlite3 database, containg a single table, called
|
||||||
|
"blocks". It looks like this:
|
||||||
|
|
||||||
|
CREATE TABLE `blocks` (`pos` INT NOT NULL PRIMARY KEY,`data` BLOB);
|
||||||
|
|
||||||
|
The key
|
||||||
|
--------
|
||||||
|
"pos" is created from the three coordinates of a MapBlock using this
|
||||||
|
algorithm, defined here in Python:
|
||||||
|
|
||||||
|
def getBlockAsInteger(p):
|
||||||
|
return int64(p[2]*16777216 + p[1]*4096 + p[0])
|
||||||
|
|
||||||
|
def int64(u):
|
||||||
|
while u >= 2**63:
|
||||||
|
u -= 2**64
|
||||||
|
while u <= -2**63:
|
||||||
|
u += 2**64
|
||||||
|
return u
|
||||||
|
|
||||||
|
It can be converted the other way by using this code:
|
||||||
|
|
||||||
|
def getIntegerAsBlock(i):
|
||||||
|
x = unsignedToSigned(i % 4096, 2048)
|
||||||
|
i = int((i - x) / 4096)
|
||||||
|
y = unsignedToSigned(i % 4096, 2048)
|
||||||
|
i = int((i - y) / 4096)
|
||||||
|
z = unsignedToSigned(i % 4096, 2048)
|
||||||
|
return x,y,z
|
||||||
|
|
||||||
|
def unsignedToSigned(i, max_positive):
|
||||||
|
if i < max_positive:
|
||||||
|
return i
|
||||||
|
else:
|
||||||
|
return i - 2*max_positive
|
||||||
|
|
||||||
|
The blob
|
||||||
|
---------
|
||||||
|
The blob is the data that would have otherwise gone into the file.
|
||||||
|
|
||||||
|
See below for description.
|
||||||
|
|
||||||
|
MapBlock serialization format
|
||||||
|
==============================
|
||||||
|
NOTE: Byte order is MSB first (big-endian).
|
||||||
|
NOTE: Zlib data is in such a format that Python's zlib at least can
|
||||||
|
directly decompress.
|
||||||
|
|
||||||
|
u8 version
|
||||||
|
- map format version number, this one is version 22
|
||||||
|
|
||||||
|
u8 flags
|
||||||
|
- Flag bitmasks:
|
||||||
|
- 0x01: is_underground: Should be set to 0 if there will be no light
|
||||||
|
obstructions above the block. If/when sunlight of a block is updated
|
||||||
|
and there is no block above it, this value is checked for determining
|
||||||
|
whether sunlight comes from the top.
|
||||||
|
- 0x02: day_night_differs: Whether the lighting of the block is different
|
||||||
|
on day and night. Only blocks that have this bit set are updated when
|
||||||
|
day transforms to night.
|
||||||
|
- 0x04: lighting_expired: If true, lighting is invalid and should be
|
||||||
|
updated. If you can't calculate lighting in your generator properly,
|
||||||
|
you could try setting this 1 to everything and setting the uppermost
|
||||||
|
block in every sector as is_underground=0. I am quite sure it doesn't
|
||||||
|
work properly, though.
|
||||||
|
- 0x08: generated: True if the block has been generated. If false, block
|
||||||
|
is mostly filled with CONTENT_IGNORE and is likely to contain eg. parts
|
||||||
|
of trees of neighboring blocks.
|
||||||
|
|
||||||
|
u8 content_width
|
||||||
|
- Number of bytes in the content (param0) fields of nodes
|
||||||
|
- Always 1
|
||||||
|
|
||||||
|
u8 params_width
|
||||||
|
- Number of bytes used for parameters per node
|
||||||
|
- Always 2
|
||||||
|
|
||||||
|
zlib-compressed node data:
|
||||||
|
- content:
|
||||||
|
u8[4096]: param0 fields
|
||||||
|
u8[4096]: param1 fields
|
||||||
|
u8[4096]: param2 fields
|
||||||
|
- The location of a node in each of those arrays is (z*16*16 + y*16 + x).
|
||||||
|
|
||||||
|
zlib-compressed node metadata list
|
||||||
|
- content:
|
||||||
|
u16 version (=1)
|
||||||
|
u16 count of metadata
|
||||||
|
foreach count:
|
||||||
|
u16 position (p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X)
|
||||||
|
u16 type_id
|
||||||
|
u16 content_size
|
||||||
|
u8[content_size] (content of metadata)
|
||||||
|
|
||||||
|
u16 mapblockobject_count
|
||||||
|
- Always 0
|
||||||
|
- Should be removed in version 23 (TODO)
|
||||||
|
|
||||||
|
u8 static object version:
|
||||||
|
- Always 0
|
||||||
|
|
||||||
|
u16 static_object_count
|
||||||
|
|
||||||
|
foreach static_object_count:
|
||||||
|
u8 type (object type-id)
|
||||||
|
s32 pos_x_nodes * 10000
|
||||||
|
s32 pos_y_nodes * 10000
|
||||||
|
s32 pos_z_nodes * 10000
|
||||||
|
u16 data_size
|
||||||
|
u8[data_size] data
|
||||||
|
|
||||||
|
u32 timestamp
|
||||||
|
- Timestamp when last saved, as seconds from starting the game.
|
||||||
|
- 0xffffffff = invalid/unknown timestamp, nothing should be done with the time
|
||||||
|
difference when loaded
|
||||||
|
|
||||||
|
u8 name-id-mapping version
|
||||||
|
- Always 0
|
||||||
|
|
||||||
|
u16 num_name_id_mappings
|
||||||
|
|
||||||
|
foreach num_name_id_mappings
|
||||||
|
u16 id
|
||||||
|
u16 name_len
|
||||||
|
u8[name_len] name
|
||||||
|
|
||||||
|
EOF.
|
||||||
|
|
||||||
|
Format of nodes
|
||||||
|
----------------
|
||||||
|
A node is composed of the u8 fields param0, param1 and param2.
|
||||||
|
|
||||||
|
The content id of a node is determined as so:
|
||||||
|
- If param0 < 0x80,
|
||||||
|
content_id = param0
|
||||||
|
- Otherwise
|
||||||
|
content_id = (param0<<4) + (param2>>4)
|
||||||
|
|
||||||
|
The purpose of param1 and param2 depend on the definition of the node.
|
||||||
|
|
||||||
|
The name-id-mapping
|
||||||
|
--------------------
|
||||||
|
The mapping maps node content ids to node names.
|
||||||
|
|
||||||
|
Node metadata format
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
1: Generic metadata
|
||||||
|
serialized inventory
|
||||||
|
u32 len
|
||||||
|
u8[len] text
|
||||||
|
u16 len
|
||||||
|
u8[len] owner
|
||||||
|
u16 len
|
||||||
|
u8[len] infotext
|
||||||
|
u16 len
|
||||||
|
u8[len] inventory drawspec
|
||||||
|
u8 allow_text_input (bool)
|
||||||
|
u8 removal_disabled (bool)
|
||||||
|
u8 enforce_owner (bool)
|
||||||
|
u32 num_vars
|
||||||
|
foreach num_vars
|
||||||
|
u16 len
|
||||||
|
u8[len] name
|
||||||
|
u32 len
|
||||||
|
u8[len] value
|
||||||
|
|
||||||
|
14: Sign metadata
|
||||||
|
u16 text_len
|
||||||
|
u8[text_len] text
|
||||||
|
|
||||||
|
15: Chest metadata
|
||||||
|
serialized inventory
|
||||||
|
|
||||||
|
16: Furnace metadata
|
||||||
|
TBD
|
||||||
|
|
||||||
|
17: Locked Chest metadata
|
||||||
|
u16 len
|
||||||
|
u8[len] owner
|
||||||
|
serialized inventory
|
||||||
|
|
||||||
|
Static objects
|
||||||
|
---------------
|
||||||
|
Static objects are persistent freely moving objects in the world.
|
||||||
|
|
||||||
|
Object types:
|
||||||
|
1: Test object
|
||||||
|
2: Item
|
||||||
|
3: Rat (deprecated)
|
||||||
|
4: Oerkki (deprecated)
|
||||||
|
5: Firefly (deprecated)
|
||||||
|
6: MobV2 (deprecated)
|
||||||
|
7: LuaEntity
|
||||||
|
|
||||||
|
1: Item:
|
||||||
|
u8 version
|
||||||
|
version 0:
|
||||||
|
u16 len
|
||||||
|
u8[len] itemstring
|
||||||
|
|
||||||
|
7: LuaEntity:
|
||||||
|
u8 version
|
||||||
|
version 1:
|
||||||
|
u16 len
|
||||||
|
u8[len] entity name
|
||||||
|
u32 len
|
||||||
|
u8[len] static data
|
||||||
|
s16 hp
|
||||||
|
s32 velocity.x * 10000
|
||||||
|
s32 velocity.y * 10000
|
||||||
|
s32 velocity.z * 10000
|
||||||
|
s32 yaw * 1000
|
||||||
|
|
||||||
|
Itemstring format
|
||||||
|
------------------
|
||||||
|
eg. 'default:dirt 5'
|
||||||
|
eg. 'default:pick_wood 21323'
|
||||||
|
eg. '"default:apple" 2'
|
||||||
|
eg. 'default:apple'
|
||||||
|
- The wear value in tools is 0...65535
|
||||||
|
- There are also a number of older formats that you might stumble upon:
|
||||||
|
eg. 'node "default:dirt" 5'
|
||||||
|
eg. 'NodeItem default:dirt 5'
|
||||||
|
eg. 'ToolItem WPick 21323'
|
||||||
|
|
||||||
|
Inventory serialization format
|
||||||
|
-------------------------------
|
||||||
|
- The inventory serialization format is line-based
|
||||||
|
- The newline character used is "\n"
|
||||||
|
- The end condition of a serialized inventory is always "EndInventory\n"
|
||||||
|
- All the slots in a list must always be serialized.
|
||||||
|
|
||||||
|
Example (format does not include "---"):
|
||||||
|
---
|
||||||
|
List foo 4
|
||||||
|
Item default:sapling
|
||||||
|
Item default:sword_stone 1 10647
|
||||||
|
Item default:dirt 99
|
||||||
|
Empty
|
||||||
|
EndInventoryList
|
||||||
|
List bar 9
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
Empty
|
||||||
|
EndInventoryList
|
||||||
|
EndInventory
|
||||||
|
---
|
||||||
|
|
||||||
|
==============================================
|
||||||
|
Minetest World Format used as of 2011-05 or so
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
Map data serialization format version 17.
|
||||||
|
|
||||||
|
0.3.1 does not use this format, but a more recent one. This exists here for
|
||||||
|
historical reasons.
|
||||||
|
|
||||||
|
Directory structure:
|
||||||
|
sectors/XXXXZZZZ or sectors2/XXX/ZZZ
|
||||||
|
XXXX, ZZZZ, XXX and ZZZ being the hexadecimal X and Z coordinates.
|
||||||
|
Under these, the block files are stored, called YYYY.
|
||||||
|
|
||||||
There also exists files map_meta.txt and chunk_meta, that are used by the
|
There also exists files map_meta.txt and chunk_meta, that are used by the
|
||||||
generator. If they are not found or invalid, the generator will currently
|
generator. If they are not found or invalid, the generator will currently
|
||||||
|
|||||||
91
doc/minetest.6
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
.\" Minetest man page
|
||||||
|
.TH minetest 6 "11 March 2012" "" ""
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
minetest \- Multiplayer infinite-world block sandbox
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B minetest
|
||||||
|
[ OPTION ... ]
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B Minetest
|
||||||
|
is one of the first InfiniMiner/Minecraft(/whatever) inspired games (started October 2010), with a goal of taking the survival multiplayer gameplay to a slightly different direction.
|
||||||
|
.PP
|
||||||
|
The main design philosophy is to keep it technically simple, stable and portable. It will be kept lightweight enough to run on fairly old hardware.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
\-\-address <value>
|
||||||
|
Address to connect to
|
||||||
|
.TP
|
||||||
|
\-\-config <value>
|
||||||
|
Load configuration from specified file
|
||||||
|
.TP
|
||||||
|
\-\-disable\-unittests
|
||||||
|
Disable unit tests
|
||||||
|
.TP
|
||||||
|
\-\-enable\-unittests
|
||||||
|
Enable unit tests
|
||||||
|
.TP
|
||||||
|
\-\-gameid <value>
|
||||||
|
Set gameid
|
||||||
|
.TP
|
||||||
|
\-\-go
|
||||||
|
Disable main menu
|
||||||
|
.TP
|
||||||
|
\-\-help
|
||||||
|
Show allowed options
|
||||||
|
.TP
|
||||||
|
\-\-logfile <value>
|
||||||
|
Set logfile path (debug.txt)
|
||||||
|
.TP
|
||||||
|
\-\-map\-dir <value>
|
||||||
|
Same as --world (deprecated)
|
||||||
|
.TP
|
||||||
|
\-\-name <value>
|
||||||
|
Set player name
|
||||||
|
.TP
|
||||||
|
\-\-password <value>
|
||||||
|
Set password
|
||||||
|
.TP
|
||||||
|
\-\-port <value>
|
||||||
|
Set network port (UDP) to use
|
||||||
|
.TP
|
||||||
|
\-\-random\-input
|
||||||
|
Enable random user input, for testing
|
||||||
|
.TP
|
||||||
|
\-\-server
|
||||||
|
Run dedicated server
|
||||||
|
.TP
|
||||||
|
\-\-speedtests
|
||||||
|
Run speed tests
|
||||||
|
.TP
|
||||||
|
\-\-info
|
||||||
|
Print more information to console
|
||||||
|
.TP
|
||||||
|
\-\-verbose
|
||||||
|
Print even more information to console
|
||||||
|
.TP
|
||||||
|
\-\-trace
|
||||||
|
Print enormous amounts of information to console
|
||||||
|
.TP
|
||||||
|
\-\-world <value>
|
||||||
|
Set world path
|
||||||
|
|
||||||
|
.SH BUGS
|
||||||
|
Please report all bugs to Perttu Ahola <celeron55@gmail.com>.
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
.PP
|
||||||
|
Perttu Ahola <celeron55@gmail.com>
|
||||||
|
and contributors.
|
||||||
|
.PP
|
||||||
|
This man page was originally written by
|
||||||
|
Juhani Numminen <juhaninumminen0@gmail.com>.
|
||||||
|
|
||||||
|
.SH WWW
|
||||||
|
http://c55.me/minetest/
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR minetestserver(6)
|
||||||
70
doc/minetestserver.6
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
.\" Minetestserver man page
|
||||||
|
.TH minetestserver 6 "11 March 2012" "" ""
|
||||||
|
|
||||||
|
.SH NAME
|
||||||
|
minetestserver \- Minetest server
|
||||||
|
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B minetestserver
|
||||||
|
[ OPTION ... ]
|
||||||
|
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B Minetest
|
||||||
|
is one of the first InfiniMiner/Minecraft(/whatever) inspired games (started October 2010), with a goal of taking the survival multiplayer gameplay to a slightly different direction.
|
||||||
|
.PP
|
||||||
|
The main design philosophy is to keep it technically simple, stable and portable. It will be kept lightweight enough to run on fairly old hardware.
|
||||||
|
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
\-\-config <value>
|
||||||
|
Load configuration from specified file
|
||||||
|
.TP
|
||||||
|
\-\-disable\-unittests
|
||||||
|
Disable unit tests
|
||||||
|
.TP
|
||||||
|
\-\-enable\-unittests
|
||||||
|
Enable unit tests
|
||||||
|
.TP
|
||||||
|
\-\-gameid <value>
|
||||||
|
Set gameid
|
||||||
|
.TP
|
||||||
|
\-\-help
|
||||||
|
Show allowed options
|
||||||
|
.TP
|
||||||
|
\-\-logfile <value>
|
||||||
|
Set logfile path (debug.txt)
|
||||||
|
.TP
|
||||||
|
\-\-map\-dir <value>
|
||||||
|
Same as --world (deprecated)
|
||||||
|
.TP
|
||||||
|
\-\-port <value>
|
||||||
|
Set network port (UDP) to use
|
||||||
|
.TP
|
||||||
|
\-\-info
|
||||||
|
Print more information to console
|
||||||
|
.TP
|
||||||
|
\-\-verbose
|
||||||
|
Print even more information to console
|
||||||
|
.TP
|
||||||
|
\-\-trace
|
||||||
|
Print enormous amounts of information to console
|
||||||
|
.TP
|
||||||
|
\-\-world <value>
|
||||||
|
Set world path
|
||||||
|
|
||||||
|
.SH BUGS
|
||||||
|
Please report all bugs to Perttu Ahola <celeron55@gmail.com>.
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
.PP
|
||||||
|
Perttu Ahola <celeron55@gmail.com>
|
||||||
|
and contributors.
|
||||||
|
.PP
|
||||||
|
This man page was originally written by
|
||||||
|
Juhani Numminen <juhaninumminen0@gmail.com>.
|
||||||
|
|
||||||
|
.SH WWW
|
||||||
|
http://c55.me/minetest/
|
||||||
|
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR minetest(6)
|
||||||
2
games/minimal/game.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
name = Minimal development test
|
||||||
|
|
||||||
95
games/minimal/mods/bucket/init.lua
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
-- bucket (Minetest 0.4 mod)
|
||||||
|
-- A bucket, which can pick up water and lava
|
||||||
|
|
||||||
|
minetest.register_alias("bucket", "bucket:bucket_empty")
|
||||||
|
minetest.register_alias("bucket_water", "bucket:bucket_water")
|
||||||
|
minetest.register_alias("bucket_lava", "bucket:bucket_lava")
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = 'bucket:bucket_empty 1',
|
||||||
|
recipe = {
|
||||||
|
{'default:steel_ingot', '', 'default:steel_ingot'},
|
||||||
|
{'', 'default:steel_ingot', ''},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
bucket = {}
|
||||||
|
bucket.liquids = {}
|
||||||
|
|
||||||
|
-- Register a new liquid
|
||||||
|
-- source = name of the source node
|
||||||
|
-- flowing = name of the flowing node
|
||||||
|
-- itemname = name of the new bucket item (or nil if liquid is not takeable)
|
||||||
|
-- inventory_image = texture of the new bucket item (ignored if itemname == nil)
|
||||||
|
-- This function can be called from any mod (that depends on bucket).
|
||||||
|
function bucket.register_liquid(source, flowing, itemname, inventory_image)
|
||||||
|
bucket.liquids[source] = {
|
||||||
|
source = source,
|
||||||
|
flowing = flowing,
|
||||||
|
itemname = itemname,
|
||||||
|
}
|
||||||
|
bucket.liquids[flowing] = bucket.liquids[source]
|
||||||
|
|
||||||
|
if itemname ~= nil then
|
||||||
|
minetest.register_craftitem(itemname, {
|
||||||
|
inventory_image = inventory_image,
|
||||||
|
stack_max = 1,
|
||||||
|
liquids_pointable = true,
|
||||||
|
on_use = function(itemstack, user, pointed_thing)
|
||||||
|
-- Must be pointing to node
|
||||||
|
if pointed_thing.type ~= "node" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- Check if pointing to a liquid
|
||||||
|
n = minetest.env:get_node(pointed_thing.under)
|
||||||
|
if bucket.liquids[n.name] == nil then
|
||||||
|
-- Not a liquid
|
||||||
|
minetest.env:add_node(pointed_thing.above, {name=source})
|
||||||
|
elseif n.name ~= source then
|
||||||
|
-- It's a liquid
|
||||||
|
minetest.env:add_node(pointed_thing.under, {name=source})
|
||||||
|
end
|
||||||
|
return {name="bucket:bucket_empty"}
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_craftitem("bucket:bucket_empty", {
|
||||||
|
inventory_image = "bucket.png",
|
||||||
|
stack_max = 1,
|
||||||
|
liquids_pointable = true,
|
||||||
|
on_use = function(itemstack, user, pointed_thing)
|
||||||
|
-- Must be pointing to node
|
||||||
|
if pointed_thing.type ~= "node" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- Check if pointing to a liquid source
|
||||||
|
n = minetest.env:get_node(pointed_thing.under)
|
||||||
|
liquiddef = bucket.liquids[n.name]
|
||||||
|
if liquiddef ~= nil and liquiddef.source == n.name and liquiddef.itemname ~= nil then
|
||||||
|
minetest.env:add_node(pointed_thing.under, {name="air"})
|
||||||
|
return {name=liquiddef.itemname}
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
bucket.register_liquid(
|
||||||
|
"default:water_source",
|
||||||
|
"default:water_flowing",
|
||||||
|
"bucket:bucket_water",
|
||||||
|
"bucket_water.png"
|
||||||
|
)
|
||||||
|
|
||||||
|
bucket.register_liquid(
|
||||||
|
"default:lava_source",
|
||||||
|
"default:lava_flowing",
|
||||||
|
"bucket:bucket_lava",
|
||||||
|
"bucket_lava.png"
|
||||||
|
)
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "fuel",
|
||||||
|
recipe = "default:bucket_lava",
|
||||||
|
burntime = 60,
|
||||||
|
})
|
||||||
|
Before Width: | Height: | Size: 329 B After Width: | Height: | Size: 329 B |
|
Before Width: | Height: | Size: 363 B After Width: | Height: | Size: 363 B |
|
Before Width: | Height: | Size: 369 B After Width: | Height: | Size: 369 B |
1882
games/minimal/mods/default/init.lua
Normal file
114
games/minimal/mods/default/mapgen.lua
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
-- minetest/default/mapgen.lua
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Aliases for map generator outputs
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.register_alias("mapgen_air", "air")
|
||||||
|
minetest.register_alias("mapgen_stone", "default:stone")
|
||||||
|
minetest.register_alias("mapgen_tree", "default:tree")
|
||||||
|
minetest.register_alias("mapgen_leaves", "default:leaves")
|
||||||
|
minetest.register_alias("mapgen_apple", "default:apple")
|
||||||
|
minetest.register_alias("mapgen_water_source", "default:water_source")
|
||||||
|
minetest.register_alias("mapgen_dirt", "default:dirt")
|
||||||
|
minetest.register_alias("mapgen_sand", "default:sand")
|
||||||
|
minetest.register_alias("mapgen_gravel", "default:gravel")
|
||||||
|
minetest.register_alias("mapgen_clay", "default:clay")
|
||||||
|
minetest.register_alias("mapgen_lava_source", "default:lava_source")
|
||||||
|
minetest.register_alias("mapgen_cobble", "default:cobble")
|
||||||
|
minetest.register_alias("mapgen_mossycobble", "default:mossycobble")
|
||||||
|
minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass")
|
||||||
|
minetest.register_alias("mapgen_junglegrass", "default:junglegrass")
|
||||||
|
minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
|
||||||
|
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
|
||||||
|
minetest.register_alias("mapgen_mese", "default:mese")
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Ore generation
|
||||||
|
--
|
||||||
|
|
||||||
|
local function generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume, ore_per_chunk, height_min, height_max)
|
||||||
|
if maxp.y < height_min or minp.y > height_max then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local y_min = math.max(minp.y, height_min)
|
||||||
|
local y_max = math.min(maxp.y, height_max)
|
||||||
|
local volume = (maxp.x-minp.x+1)*(y_max-y_min+1)*(maxp.z-minp.z+1)
|
||||||
|
local pr = PseudoRandom(seed)
|
||||||
|
local num_chunks = math.floor(chunks_per_volume * volume)
|
||||||
|
local chunk_size = 3
|
||||||
|
if ore_per_chunk <= 4 then
|
||||||
|
chunk_size = 2
|
||||||
|
end
|
||||||
|
local inverse_chance = math.floor(chunk_size*chunk_size*chunk_size / ore_per_chunk)
|
||||||
|
--print("generate_ore num_chunks: "..dump(num_chunks))
|
||||||
|
for i=1,num_chunks do
|
||||||
|
local y0 = pr:next(y_min, y_max-chunk_size+1)
|
||||||
|
if y0 >= height_min and y0 <= height_max then
|
||||||
|
local x0 = pr:next(minp.x, maxp.x-chunk_size+1)
|
||||||
|
local z0 = pr:next(minp.z, maxp.z-chunk_size+1)
|
||||||
|
local p0 = {x=x0, y=y0, z=z0}
|
||||||
|
for x1=0,chunk_size-1 do
|
||||||
|
for y1=0,chunk_size-1 do
|
||||||
|
for z1=0,chunk_size-1 do
|
||||||
|
if pr:next(1,inverse_chance) == 1 then
|
||||||
|
local x2 = x0+x1
|
||||||
|
local y2 = y0+y1
|
||||||
|
local z2 = z0+z1
|
||||||
|
local p2 = {x=x2, y=y2, z=z2}
|
||||||
|
if minetest.env:get_node(p2).name == wherein then
|
||||||
|
minetest.env:set_node(p2, {name=name})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--print("generate_ore done")
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_generated(function(minp, maxp, seed)
|
||||||
|
generate_ore("default:stone_with_coal", "default:stone", minp, maxp, seed, 1/8/8/8, 5, -31000, 64)
|
||||||
|
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+1, 1/16/16/16, 5, -5, 7)
|
||||||
|
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+2, 1/12/12/12, 5, -16, -5)
|
||||||
|
generate_ore("default:stone_with_iron", "default:stone", minp, maxp, seed+3, 1/9/9/9, 5, -31000, -17)
|
||||||
|
-- Generate clay
|
||||||
|
if maxp.y >= 2 and minp.y <= 0 then
|
||||||
|
-- Assume X and Z lengths are equal
|
||||||
|
local divlen = 4
|
||||||
|
local divs = (maxp.x-minp.x)/divlen+1;
|
||||||
|
for divx=0+1,divs-1-1 do
|
||||||
|
for divz=0+1,divs-1-1 do
|
||||||
|
local cx = minp.x + math.floor((divx+0.5)*divlen)
|
||||||
|
local cz = minp.z + math.floor((divz+0.5)*divlen)
|
||||||
|
if minetest.env:get_node({x=cx,y=1,z=cz}).name == "default:water_source" and
|
||||||
|
minetest.env:get_node({x=cx,y=0,z=cz}).name == "default:sand" then
|
||||||
|
local is_shallow = true
|
||||||
|
local num_water_around = 0
|
||||||
|
if minetest.env:get_node({x=cx-divlen*2,y=1,z=cz+0}).name == "default:water_source" then
|
||||||
|
num_water_around = num_water_around + 1 end
|
||||||
|
if minetest.env:get_node({x=cx+divlen*2,y=1,z=cz+0}).name == "default:water_source" then
|
||||||
|
num_water_around = num_water_around + 1 end
|
||||||
|
if minetest.env:get_node({x=cx+0,y=1,z=cz-divlen*2}).name == "default:water_source" then
|
||||||
|
num_water_around = num_water_around + 1 end
|
||||||
|
if minetest.env:get_node({x=cx+0,y=1,z=cz+divlen*2}).name == "default:water_source" then
|
||||||
|
num_water_around = num_water_around + 1 end
|
||||||
|
if num_water_around >= 2 then
|
||||||
|
is_shallow = false
|
||||||
|
end
|
||||||
|
if is_shallow then
|
||||||
|
for x1=-divlen,divlen do
|
||||||
|
for z1=-divlen,divlen do
|
||||||
|
if minetest.env:get_node({x=cx+x1,y=0,z=cz+z1}).name == "default:sand" then
|
||||||
|
minetest.env:set_node({x=cx+x1,y=0,z=cz+z1}, {name="default:clay"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
BIN
games/minimal/mods/default/sounds/default_grass_footstep.1.ogg
Normal file
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 203 B |
|
Before Width: | Height: | Size: 292 B After Width: | Height: | Size: 292 B |
|
Before Width: | Height: | Size: 597 B After Width: | Height: | Size: 597 B |
|
Before Width: | Height: | Size: 604 B After Width: | Height: | Size: 604 B |
|
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 279 B |
|
Before Width: | Height: | Size: 236 B After Width: | Height: | Size: 236 B |
|
Before Width: | Height: | Size: 167 B After Width: | Height: | Size: 167 B |
|
Before Width: | Height: | Size: 224 B After Width: | Height: | Size: 224 B |
|
Before Width: | Height: | Size: 151 B After Width: | Height: | Size: 151 B |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 613 B After Width: | Height: | Size: 613 B |
|
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 249 B |
|
Before Width: | Height: | Size: 210 B After Width: | Height: | Size: 210 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
|
Before Width: | Height: | Size: 933 B After Width: | Height: | Size: 933 B |
|
Before Width: | Height: | Size: 830 B After Width: | Height: | Size: 830 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 539 B After Width: | Height: | Size: 539 B |
BIN
games/minimal/mods/default/textures/default_furnace_fire_bg.png
Normal file
|
After Width: | Height: | Size: 313 B |
BIN
games/minimal/mods/default/textures/default_furnace_fire_fg.png
Normal file
|
After Width: | Height: | Size: 865 B |
|
Before Width: | Height: | Size: 246 B After Width: | Height: | Size: 246 B |
|
After Width: | Height: | Size: 376 B |
|
Before Width: | Height: | Size: 236 B After Width: | Height: | Size: 236 B |
|
Before Width: | Height: | Size: 978 B After Width: | Height: | Size: 978 B |
|
Before Width: | Height: | Size: 874 B After Width: | Height: | Size: 874 B |
|
Before Width: | Height: | Size: 856 B After Width: | Height: | Size: 856 B |
|
Before Width: | Height: | Size: 878 B After Width: | Height: | Size: 878 B |
|
Before Width: | Height: | Size: 591 B After Width: | Height: | Size: 591 B |
|
Before Width: | Height: | Size: 936 B After Width: | Height: | Size: 936 B |
|
Before Width: | Height: | Size: 672 B After Width: | Height: | Size: 672 B |
|
Before Width: | Height: | Size: 502 B After Width: | Height: | Size: 502 B |
|
Before Width: | Height: | Size: 507 B After Width: | Height: | Size: 507 B |
|
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 395 B |
|
Before Width: | Height: | Size: 357 B After Width: | Height: | Size: 357 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 203 B |
|
Before Width: | Height: | Size: 952 B After Width: | Height: | Size: 952 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 965 B After Width: | Height: | Size: 965 B |
|
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 303 B |
|
Before Width: | Height: | Size: 410 B After Width: | Height: | Size: 410 B |
|
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 203 B |
|
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 260 B |
|
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 242 B |
|
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 366 B |
|
Before Width: | Height: | Size: 507 B After Width: | Height: | Size: 507 B |
|
Before Width: | Height: | Size: 555 B After Width: | Height: | Size: 555 B |
|
Before Width: | Height: | Size: 545 B After Width: | Height: | Size: 545 B |
|
Before Width: | Height: | Size: 542 B After Width: | Height: | Size: 542 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 772 B After Width: | Height: | Size: 772 B |
|
Before Width: | Height: | Size: 502 B After Width: | Height: | Size: 502 B |