Compare commits
998 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80dc961d24 | ||
|
|
e4d3639d40 | ||
|
|
fe046fab8a | ||
|
|
1d4978b881 | ||
|
|
b6eb315262 | ||
|
|
518dbec74c | ||
|
|
2795a2a4db | ||
|
|
03c5dffabe | ||
|
|
c77f0c1065 | ||
|
|
58c0e37501 | ||
|
|
d74ebfbc67 | ||
|
|
c8b0502037 | ||
|
|
87c771e638 | ||
|
|
388930f3dd | ||
|
|
bc73df81d1 | ||
|
|
b5d43d7b18 | ||
|
|
c3775ceb49 | ||
|
|
36bba5b8ca | ||
|
|
98c13746ce | ||
|
|
041553e658 | ||
|
|
83b6a3bcdd | ||
|
|
0f55050038 | ||
|
|
8abca2cf0b | ||
|
|
9295e95990 | ||
|
|
956892c226 | ||
|
|
f2e78f31ab | ||
|
|
c6afe083b3 | ||
|
|
6f02ce1e99 | ||
|
|
6e9ba56708 | ||
|
|
0870b30f3b | ||
|
|
834d445795 | ||
|
|
b5912d7407 | ||
|
|
d7e829f272 | ||
|
|
9d1a3ba668 | ||
|
|
db05c8fd45 | ||
|
|
983bff68e6 | ||
|
|
509ed10328 | ||
|
|
37a3d49621 | ||
|
|
f15b61c146 | ||
|
|
7fffe6d0fa | ||
|
|
8396996ac3 | ||
|
|
b7eb64a4d4 | ||
|
|
c6d5441105 | ||
|
|
72eec0f6f5 | ||
|
|
994802a774 | ||
|
|
7a2b9df970 | ||
|
|
e91ffa0c91 | ||
|
|
1b83b0acfd | ||
|
|
80fe516e4e | ||
|
|
30c51a1115 | ||
|
|
001de6ffba | ||
|
|
1c69476d9f | ||
|
|
a7787bb9d2 | ||
|
|
ed8215042c | ||
|
|
6444963fb1 | ||
|
|
1681a009bc | ||
|
|
ef152428ef | ||
|
|
c09e16ff5b | ||
|
|
210a339dce | ||
|
|
d99b6fed55 | ||
|
|
4d5ce8478c | ||
|
|
5b338638e0 | ||
|
|
2f291e6685 | ||
|
|
099624a513 | ||
|
|
e8fb1f79bc | ||
|
|
649f641f28 | ||
|
|
c445a3d958 | ||
|
|
9ff5302c8b | ||
|
|
05309229b8 | ||
|
|
39f4a2f607 | ||
|
|
ec490abf58 | ||
|
|
a58e00ecfc | ||
|
|
dc9286e2a1 | ||
|
|
c5dda0ae2f | ||
|
|
b74075f2fe | ||
|
|
a3376d4022 | ||
|
|
2a61bfd249 | ||
|
|
1946442481 | ||
|
|
b4916ad233 | ||
|
|
85be5a3e14 | ||
|
|
de840fe271 | ||
|
|
dfa0c15ce0 | ||
|
|
ae483f1bd0 | ||
|
|
4dc97eb99f | ||
|
|
50cb503d77 | ||
|
|
9d0f768cf6 | ||
|
|
90808a4f34 | ||
|
|
358074b296 | ||
|
|
a2bb776ea8 | ||
|
|
60baf8120c | ||
|
|
af2f02552f | ||
|
|
772944daf6 | ||
|
|
7e185068c4 | ||
|
|
dada983ff4 | ||
|
|
8797a0aa4b | ||
|
|
7779bac3a5 | ||
|
|
1ff5ee0b69 | ||
|
|
605599b6f1 | ||
|
|
00972d42d7 | ||
|
|
673ac55a9d | ||
|
|
1469424075 | ||
|
|
d176dabeb4 | ||
|
|
ce9802266e | ||
|
|
35267406aa | ||
|
|
a4a377ecad | ||
|
|
75c393c915 | ||
|
|
674400523e | ||
|
|
e25a38e3fb | ||
|
|
1c6d2f596d | ||
|
|
9b5effffbb | ||
|
|
0443620c5e | ||
|
|
287605ca81 | ||
|
|
0120fe16a7 | ||
|
|
fd32005b0f | ||
|
|
582ee15d8e | ||
|
|
1bf9b25fb4 | ||
|
|
018217f6b2 | ||
|
|
febd07fc0d | ||
|
|
0d4d35ab93 | ||
|
|
6673aff685 | ||
|
|
9b8ca3a746 | ||
|
|
5cb7f6a9b7 | ||
|
|
98327a59c4 | ||
|
|
f286c54908 | ||
|
|
0e0c824ea7 | ||
|
|
441740e021 | ||
|
|
071e114ffa | ||
|
|
6945f807ab | ||
|
|
34c52d0ad7 | ||
|
|
8729e7daec | ||
|
|
a32a06e088 | ||
|
|
da88a18676 | ||
|
|
c07c642ab0 | ||
|
|
5e04f1a335 | ||
|
|
3342dcc4bc | ||
|
|
c1b3ed4180 | ||
|
|
0d7c37943b | ||
|
|
2d5bd7f414 | ||
|
|
d067894816 | ||
|
|
c6e96c645b | ||
|
|
77597c4ff3 | ||
|
|
b6f4a9c7e1 | ||
|
|
43d1f375d1 | ||
|
|
a024042bf5 | ||
|
|
07c17db114 | ||
|
|
45ab62d6a3 | ||
|
|
5ebf8f9450 | ||
|
|
6658ad3d94 | ||
|
|
de028fc056 | ||
|
|
e8b00fdf98 | ||
|
|
7c82f1e5dd | ||
|
|
fe247f38f7 | ||
|
|
21e0a049f8 | ||
|
|
d6cf5450a8 | ||
|
|
6fb27d3b2e | ||
|
|
e2199874a4 | ||
|
|
b71ed1a957 | ||
|
|
87b6458abc | ||
|
|
f441e0d76e | ||
|
|
4cf0bf8ff4 | ||
|
|
733b49b17f | ||
|
|
41e9074c7d | ||
|
|
1b3ea47e99 | ||
|
|
b8993ee5ac | ||
|
|
194df438c2 | ||
|
|
1a9cd99056 | ||
|
|
c874bfa5c3 | ||
|
|
9a9ae7d65c | ||
|
|
dd591119a3 | ||
|
|
76ec6b8313 | ||
|
|
ae0d8f74d7 | ||
|
|
468eeb618e | ||
|
|
ad9fcf859e | ||
|
|
f9fdb48dc8 | ||
|
|
bd921a7916 | ||
|
|
f1d7a26b7c | ||
|
|
95409da87d | ||
|
|
c729543ec4 | ||
|
|
3251e44938 | ||
|
|
3db66b4531 | ||
|
|
f727f54192 | ||
|
|
9762650f97 | ||
|
|
dc5bc6cac7 | ||
|
|
ecf08255b0 | ||
|
|
1ecc8756bc | ||
|
|
19960e26c6 | ||
|
|
b662a4577d | ||
|
|
7f4cdbcbe9 | ||
|
|
e21a1ab3bd | ||
|
|
c761717f11 | ||
|
|
04ba2d2721 | ||
|
|
b82e5ec880 | ||
|
|
1ef9eee311 | ||
|
|
d130e1fdc0 | ||
|
|
1670bc7366 | ||
|
|
ff1ef67dcc | ||
|
|
70ceeb80a1 | ||
|
|
2818d3f224 | ||
|
|
db17225a97 | ||
|
|
a7e131f53e | ||
|
|
af96309621 | ||
|
|
d7ddceac73 | ||
|
|
29ab20c272 | ||
|
|
dda171d292 | ||
|
|
485bf21998 | ||
|
|
91a9382c25 | ||
|
|
0c34fe20a1 | ||
|
|
4c03190ce8 | ||
|
|
f6d1b682d3 | ||
|
|
57eaf62c69 | ||
|
|
58c083f305 | ||
|
|
cca58fe0fd | ||
|
|
8464da7585 | ||
|
|
3e71c8f482 | ||
|
|
4f4e2e3e83 | ||
|
|
113c85a66a | ||
|
|
dc0e9097d3 | ||
|
|
f151b23220 | ||
|
|
900b816162 | ||
|
|
1ffb180868 | ||
|
|
2ad74a9e8b | ||
|
|
370354cc87 | ||
|
|
de5ecc9fa3 | ||
|
|
57e5aa6628 | ||
|
|
6d1e6f8898 | ||
|
|
f98bbe193e | ||
|
|
f3fe62a0bf | ||
|
|
cfe0291b13 | ||
|
|
efd509f796 | ||
|
|
858c722974 | ||
|
|
cf37a55690 | ||
|
|
5f2af7c4e8 | ||
|
|
93c1d511e3 | ||
|
|
eddf16eee9 | ||
|
|
5433e9bd19 | ||
|
|
6120251320 | ||
|
|
04cc9de8f2 | ||
|
|
4323ad163f | ||
|
|
f6da7b3fda | ||
|
|
907be0ab91 | ||
|
|
97988a1044 | ||
|
|
73de17afa8 | ||
|
|
d17636484d | ||
|
|
34d32ce55a | ||
|
|
0f955bf7fa | ||
|
|
a9aad4d061 | ||
|
|
b1e6c2a9b8 | ||
|
|
093e621643 | ||
|
|
b0be7ab61e | ||
|
|
98286a24bc | ||
|
|
e80a83d1cb | ||
|
|
6f641df8a5 | ||
|
|
021e667511 | ||
|
|
8bdf9a44c6 | ||
|
|
83508277ce | ||
|
|
1399678ffd | ||
|
|
4e2479e46a | ||
|
|
a3e7372686 | ||
|
|
59911761ef | ||
|
|
eb587996e4 | ||
|
|
e8d8723320 | ||
|
|
0bc306e337 | ||
|
|
b4106ca58f | ||
|
|
0419552c92 | ||
|
|
0a8834608d | ||
|
|
8ad3dad137 | ||
|
|
58d83a7bb2 | ||
|
|
d4e9dd4643 | ||
|
|
fb4c730708 | ||
|
|
8c8333bf68 | ||
|
|
41c5483024 | ||
|
|
01f9d05f23 | ||
|
|
f73534640a | ||
|
|
ff4fef570e | ||
|
|
4af99b75cf | ||
|
|
271d7c31e6 | ||
|
|
c28a843592 | ||
|
|
71ffe699d0 | ||
|
|
f7088f69ab | ||
|
|
b751c59f43 | ||
|
|
676951d90d | ||
|
|
94358a709b | ||
|
|
a5c9174bad | ||
|
|
08b680d588 | ||
|
|
bce0d458d8 | ||
|
|
351cc2e79a | ||
|
|
63e175dd70 | ||
|
|
3a90b78a03 | ||
|
|
88b9b9652a | ||
|
|
be06636965 | ||
|
|
00138a52d8 | ||
|
|
48ce9c9b30 | ||
|
|
4b15f76ed1 | ||
|
|
503e1d2b7c | ||
|
|
671d37adff | ||
|
|
619d4cf8ae | ||
|
|
49eaa0c5f7 | ||
|
|
649fabcc3d | ||
|
|
aef1aeb3aa | ||
|
|
f8ba6ce94f | ||
|
|
80a5f52634 | ||
|
|
d39828f17c | ||
|
|
e6307b2a6c | ||
|
|
ca94ce7d06 | ||
|
|
7f0ce7a37b | ||
|
|
199872e33c | ||
|
|
1d405406d1 | ||
|
|
93c44550d2 | ||
|
|
43feb1fbab | ||
|
|
8fd6de5c3b | ||
|
|
06bac07df0 | ||
|
|
886789a23e | ||
|
|
ffb22a4f49 | ||
|
|
2cfcd965c7 | ||
|
|
f397466272 | ||
|
|
4ea63aa0ed | ||
|
|
4ad1dd5938 | ||
|
|
e0272635e9 | ||
|
|
8277e63454 | ||
|
|
4ee6be856d | ||
|
|
6da828c471 | ||
|
|
54ffc4e915 | ||
|
|
460e094a9f | ||
|
|
1eca9ecf7d | ||
|
|
b8a4c95971 | ||
|
|
563199698d | ||
|
|
000ec26001 | ||
|
|
859141a0ce | ||
|
|
86b1542181 | ||
|
|
75fb3e4730 | ||
|
|
26f4a5c2d1 | ||
|
|
ef56586ed3 | ||
|
|
987eb2b761 | ||
|
|
63ac62ec8a | ||
|
|
813a9a36b2 | ||
|
|
773efc19b1 | ||
|
|
a4874270f7 | ||
|
|
529ba8002d | ||
|
|
cc1ff26c3f | ||
|
|
ea549bbae3 | ||
|
|
fbc1432fe8 | ||
|
|
b605b95749 | ||
|
|
5e806690fc | ||
|
|
b85301ce69 | ||
|
|
81c3dc32a8 | ||
|
|
1b299b4039 | ||
|
|
7c85405d96 | ||
|
|
4b05feaceb | ||
|
|
a9878a0da5 | ||
|
|
ec0c4d33db | ||
|
|
09f2cd0264 | ||
|
|
53d1b3d924 | ||
|
|
72ce9d7a5d | ||
|
|
aa5549ecc3 | ||
|
|
1139a18c3a | ||
|
|
e70e15134c | ||
|
|
4d5177ff70 | ||
|
|
22567d107f | ||
|
|
5a59ad2307 | ||
|
|
329d654e37 | ||
|
|
dd2f1d7551 | ||
|
|
072bbba69a | ||
|
|
9efc5da0fb | ||
|
|
c4b98deb61 | ||
|
|
d4e0c0f9b8 | ||
|
|
e7246d3f0d | ||
|
|
d3131aeae7 | ||
|
|
525d2a0d51 | ||
|
|
3c4ac70348 | ||
|
|
2e3778ec0c | ||
|
|
f8ad01ab7c | ||
|
|
b8484ef24e | ||
|
|
2cc518dcaf | ||
|
|
9f4916a452 | ||
|
|
a7485e40ff | ||
|
|
ba0a8dabef | ||
|
|
d31750cb93 | ||
|
|
7b74f04a61 | ||
|
|
0891975ad6 | ||
|
|
b52f3005c3 | ||
|
|
40ce538aad | ||
|
|
eb88e5dd4b | ||
|
|
46276414ed | ||
|
|
14aa990cdd | ||
|
|
c05dfac9a3 | ||
|
|
454483f266 | ||
|
|
39fa249f91 | ||
|
|
b539985ab8 | ||
|
|
84f4565e13 | ||
|
|
88df9fb5b6 | ||
|
|
44ca9c9cb2 | ||
|
|
0727bb3ddd | ||
|
|
37df9cb7d7 | ||
|
|
073f5cf03d | ||
|
|
ba66fce833 | ||
|
|
a50d07d39a | ||
|
|
92b45b2a18 | ||
|
|
c42c53fccf | ||
|
|
2c19d51409 | ||
|
|
d7bc346981 | ||
|
|
9978f5af82 | ||
|
|
cb3a61f8db | ||
|
|
2efae3ffd7 | ||
|
|
c9492b4d37 | ||
|
|
7a4878cd0b | ||
|
|
ff80696947 | ||
|
|
ba4b704ebf | ||
|
|
6738c7e9a3 | ||
|
|
f83d8687a7 | ||
|
|
d34f149bdc | ||
|
|
25a24c0cdf | ||
|
|
ab371cc934 | ||
|
|
d785456b3f | ||
|
|
2baa191a64 | ||
|
|
9878ce05e7 | ||
|
|
0e27b4b978 | ||
|
|
e10e5fd16c | ||
|
|
f1ab42fdff | ||
|
|
0a6e53bd31 | ||
|
|
c9ac722ea9 | ||
|
|
6de83a2756 | ||
|
|
22df959343 | ||
|
|
a901a56859 | ||
|
|
4d634ef675 | ||
|
|
2d1fca51e9 | ||
|
|
01b2d2c66c | ||
|
|
00123ee04d | ||
|
|
111e7e1cc8 | ||
|
|
d0a6cacd51 | ||
|
|
e9cd7187e8 | ||
|
|
5db41d4d21 | ||
|
|
d988f9b769 | ||
|
|
3d25914986 | ||
|
|
d0ce27edd8 | ||
|
|
9aabfd5188 | ||
|
|
3955f51253 | ||
|
|
2dcbc01904 | ||
|
|
a5e4273575 | ||
|
|
eb49009d02 | ||
|
|
f17c9c45dc | ||
|
|
2bd10022cb | ||
|
|
984e063374 | ||
|
|
1de08e1961 | ||
|
|
bb4db84bdb | ||
|
|
7760948b7c | ||
|
|
7bd3e2bceb | ||
|
|
f5d4494a51 | ||
|
|
74b670a793 | ||
|
|
5707b739f3 | ||
|
|
3ad68c052b | ||
|
|
a5ee7139a5 | ||
|
|
e2ad76f910 | ||
|
|
607dab2b0d | ||
|
|
ef6feca501 | ||
|
|
0680c47d6c | ||
|
|
8bc6a303b4 | ||
|
|
5da3ed19a3 | ||
|
|
3e30731c1a | ||
|
|
80c75272a6 | ||
|
|
f2f9a92351 | ||
|
|
f2aa2c6a98 | ||
|
|
c2e7b1f579 | ||
|
|
13f94ecad5 | ||
|
|
bbdd869d72 | ||
|
|
de664b1c6d | ||
|
|
047168ca83 | ||
|
|
8e4c11406e | ||
|
|
2d03cfd24c | ||
|
|
03b34cb3dd | ||
|
|
3b9ae409c7 | ||
|
|
326cc5df74 | ||
|
|
d873545ac7 | ||
|
|
3e355ab7d5 | ||
|
|
74afe6fe6b | ||
|
|
cdc538e0a2 | ||
|
|
e761b9f486 | ||
|
|
6642c8583a | ||
|
|
f0e3abc64d | ||
|
|
0c9189d109 | ||
|
|
707e27b5c2 | ||
|
|
3eecc6ff44 | ||
|
|
c93f7f5cea | ||
|
|
79d752ba4f | ||
|
|
814ee971f7 | ||
|
|
953cbb3b15 | ||
|
|
b7a98e9850 | ||
|
|
2a89531071 | ||
|
|
ae929ce2fd | ||
|
|
c268db7b46 | ||
|
|
9f108b56d3 | ||
|
|
08911160aa | ||
|
|
33e0eedbfb | ||
|
|
87e9466caf | ||
|
|
0cde270bf5 | ||
|
|
59fdf57134 | ||
|
|
d413dfe87c | ||
|
|
7fc6719968 | ||
|
|
2d7a6f2cc0 | ||
|
|
d04d8aba70 | ||
|
|
43822de5c6 | ||
|
|
39123fcce5 | ||
|
|
6d5a407133 | ||
|
|
bc29e03b59 | ||
|
|
b9c1a758a1 | ||
|
|
c57b4ff9b5 | ||
|
|
72535d3328 | ||
|
|
0eede97af2 | ||
|
|
2ea6015643 | ||
|
|
0dada51a55 | ||
|
|
efa54f9c46 | ||
|
|
dd282e646c | ||
|
|
7279f0b373 | ||
|
|
c5967f75f0 | ||
|
|
a378e32751 | ||
|
|
51746ca910 | ||
|
|
d218baa3ac | ||
|
|
2f56a00d9e | ||
|
|
d2f5732f89 | ||
|
|
63c892eedf | ||
|
|
f3bd4c405d | ||
|
|
f5070b4454 | ||
|
|
e12019cfd9 | ||
|
|
d03b4fb627 | ||
|
|
c41352a1c7 | ||
|
|
f0c6feca97 | ||
|
|
ee9b59a7fe | ||
|
|
ee6d8c10ce | ||
|
|
8002366097 | ||
|
|
bb154c2e1c | ||
|
|
ef0aa7d5b5 | ||
|
|
e2dd96b432 | ||
|
|
7ae7f1ea4c | ||
|
|
25ba96fcac | ||
|
|
5d60a6c533 | ||
|
|
430d3b28e4 | ||
|
|
6647939403 | ||
|
|
ec30d49e02 | ||
|
|
8e7449e092 | ||
|
|
11df7e886a | ||
|
|
73fdb63597 | ||
|
|
8c1b4f298e | ||
|
|
ddcf8422a2 | ||
|
|
1fee649f15 | ||
|
|
98e36d7d68 | ||
|
|
eb2c19bbed | ||
|
|
b0746834cc | ||
|
|
8f9611bcb2 | ||
|
|
ce106a4113 | ||
|
|
c435eabf3f | ||
|
|
b387f95ed3 | ||
|
|
545c37f613 | ||
|
|
8f22272df5 | ||
|
|
e8b7179ccd | ||
|
|
ca3629637c | ||
|
|
ad10b8b762 | ||
|
|
3f8261830e | ||
|
|
8aadc62856 | ||
|
|
7387b19021 | ||
|
|
6718a95103 | ||
|
|
a07b032245 | ||
|
|
7057c196c4 | ||
|
|
523f0e8c5b | ||
|
|
e2e8da5ee4 | ||
|
|
52ba1f867e | ||
|
|
a1346c916e | ||
|
|
dd3cda6bed | ||
|
|
abd68d3466 | ||
|
|
e509ead680 | ||
|
|
094a5a73d3 | ||
|
|
5a0a59ad46 | ||
|
|
084cdea686 | ||
|
|
b16252dcae | ||
|
|
b95f543da9 | ||
|
|
e3cbe521fc | ||
|
|
f4d718c538 | ||
|
|
4d4b8bb8a4 | ||
|
|
2f59a0c840 | ||
|
|
923a8f1983 | ||
|
|
a76e7698b2 | ||
|
|
a95f983ea8 | ||
|
|
231ac33d34 | ||
|
|
5114329ada | ||
|
|
a17bcb1767 | ||
|
|
3fa7c5a476 | ||
|
|
ceba12e5aa | ||
|
|
34e69e5479 | ||
|
|
ab1d98bc8f | ||
|
|
2acd3ad663 | ||
|
|
70579dc7c3 | ||
|
|
1dd361f37c | ||
|
|
5e4d6468a3 | ||
|
|
ba52a34f94 | ||
|
|
09f1a0c1ff | ||
|
|
cc7c31a5bc | ||
|
|
04f68a87ee | ||
|
|
bdf8f85493 | ||
|
|
0f0502109e | ||
|
|
f522e7351a | ||
|
|
59f84ca0a0 | ||
|
|
24edfb77af | ||
|
|
e4f7ce1985 | ||
|
|
6d4e7f223a | ||
|
|
78bf7c46e5 | ||
|
|
0614da3aff | ||
|
|
f8408398f5 | ||
|
|
c67f2b2965 | ||
|
|
211d919b54 | ||
|
|
646159159f | ||
|
|
55cb5a1983 | ||
|
|
1c4bc0d46c | ||
|
|
b898ab6486 | ||
|
|
eac6323e80 | ||
|
|
571ed96c8e | ||
|
|
3a0ded274e | ||
|
|
bb9fe6eb2b | ||
|
|
728909284a | ||
|
|
47b1a118ef | ||
|
|
51210d317d | ||
|
|
f18cebdd07 | ||
|
|
68d24fb74b | ||
|
|
3aabb6587d | ||
|
|
735581bad1 | ||
|
|
e36ae4ec0a | ||
|
|
66fe077d07 | ||
|
|
eb1d7cdb3d | ||
|
|
faea229da7 | ||
|
|
8785827990 | ||
|
|
46ac92b1a1 | ||
|
|
428cebc25d | ||
|
|
a5ec1ddcac | ||
|
|
18a7d3e754 | ||
|
|
64969ef41a | ||
|
|
9f476fd66d | ||
|
|
f8456dde51 | ||
|
|
289cf93d4b | ||
|
|
ef4eb46b61 | ||
|
|
a2c4467255 | ||
|
|
ef68a506aa | ||
|
|
715fba6f39 | ||
|
|
593eaf3b88 | ||
|
|
5f41ae2a16 | ||
|
|
ab8fbd970f | ||
|
|
f8c87a4496 | ||
|
|
ec7e23d780 | ||
|
|
6752dda856 | ||
|
|
7af9442ea3 | ||
|
|
22ad774ff4 | ||
|
|
1e6130d128 | ||
|
|
7958bda9d8 | ||
|
|
1c8d43cab5 | ||
|
|
05f6b274a5 | ||
|
|
0d94bfabcc | ||
|
|
540071002e | ||
|
|
0fdf24d64a | ||
|
|
d9675d3d92 | ||
|
|
c98ae2a91f | ||
|
|
02112f84e2 | ||
|
|
38abc91802 | ||
|
|
60772071e9 | ||
|
|
2886f0ccb0 | ||
|
|
3f88d776dc | ||
|
|
5a2431a9bd | ||
|
|
24719c6908 | ||
|
|
bbe8386a66 | ||
|
|
2e69711613 | ||
|
|
075833e393 | ||
|
|
9714cdcf4b | ||
|
|
cc36f5e99a | ||
|
|
2829742ae8 | ||
|
|
8a7dc838a8 | ||
|
|
e2cbfa82e8 | ||
|
|
fb1406bdff | ||
|
|
8b63fbefba | ||
|
|
144da5f522 | ||
|
|
105676b952 | ||
|
|
6c9f10e132 | ||
|
|
5dc6198878 | ||
|
|
c38985825f | ||
|
|
2fe3bf5a18 | ||
|
|
bb06d377a1 | ||
|
|
785a9a6c1a | ||
|
|
e4ee6548af | ||
|
|
3af5eef964 | ||
|
|
9e10f9f49a | ||
|
|
0d1c9598a0 | ||
|
|
dbeb322f62 | ||
|
|
4bf4154cad | ||
|
|
c6ca7a81cc | ||
|
|
681d127ff1 | ||
|
|
4a0a6723af | ||
|
|
afc48c802a | ||
|
|
5f0dc8e78a | ||
|
|
8e61c1dfd9 | ||
|
|
bc3980e1d6 | ||
|
|
5fd1ef9b58 | ||
|
|
93e3555eae | ||
|
|
649448a2a9 | ||
|
|
6707d622bb | ||
|
|
1980d9ea31 | ||
|
|
e4031156f1 | ||
|
|
67ec2fa92d | ||
|
|
68f5b877c7 | ||
|
|
8a1a9fdc24 | ||
|
|
b98f98b367 | ||
|
|
7e17eaedb2 | ||
|
|
c05aac3766 | ||
|
|
c79370023b | ||
|
|
739ef175aa | ||
|
|
e7c62edec9 | ||
|
|
2b21cac1d8 | ||
|
|
45eab340b9 | ||
|
|
3c5da70d7c | ||
|
|
e82bd3f067 | ||
|
|
295232667e | ||
|
|
ad4bf2ccf9 | ||
|
|
1c570cb390 | ||
|
|
66bb295436 | ||
|
|
b5c84c34ce | ||
|
|
6bb4347208 | ||
|
|
dde66a82ed | ||
|
|
f8fd432dca | ||
|
|
bf315c05f1 | ||
|
|
7607b0ac20 | ||
|
|
70e2df4f86 | ||
|
|
380a4b6d60 | ||
|
|
e1842ed370 | ||
|
|
595932a860 | ||
|
|
9d25242c5c | ||
|
|
d43326021a | ||
|
|
6d7b95d763 | ||
|
|
7252c803e0 | ||
|
|
361e687f3a | ||
|
|
bcb06aeb85 | ||
|
|
be39f61359 | ||
|
|
c071efaa43 | ||
|
|
1fd9a07497 | ||
|
|
198ed60cab | ||
|
|
6eb6e75fff | ||
|
|
3db2f08ff9 | ||
|
|
a1e1323d6e | ||
|
|
98176481c1 | ||
|
|
779d2c5f64 | ||
|
|
74eb7f50c9 | ||
|
|
0c76303186 | ||
|
|
63a3bb229a | ||
|
|
c7d569b863 | ||
|
|
91250c1078 | ||
|
|
0d740c5d82 | ||
|
|
a291cd6132 | ||
|
|
3253b6bd22 | ||
|
|
2ff054d041 | ||
|
|
c31e354342 | ||
|
|
4b17105dc4 | ||
|
|
adad6e0a1c | ||
|
|
9a3129da5e | ||
|
|
a468acce2c | ||
|
|
0ad40fd484 | ||
|
|
c9e7a27eeb | ||
|
|
0b27a70b29 | ||
|
|
4f684b589d | ||
|
|
b6569f1c69 | ||
|
|
a4a9ee94f3 | ||
|
|
1b450861f0 | ||
|
|
70f104be07 | ||
|
|
b3fc133442 | ||
|
|
569b89b36f | ||
|
|
7bbd716426 | ||
|
|
edba6e50d9 | ||
|
|
fd5a130b86 | ||
|
|
067766eec2 | ||
|
|
0baea8c25c | ||
|
|
656faf7373 | ||
|
|
9393e4a0a8 | ||
|
|
3de9ae4e60 | ||
|
|
ad163ee5c3 | ||
|
|
9978d0796f | ||
|
|
09cefc3dfd | ||
|
|
8bcd10b872 | ||
|
|
0264e38bff | ||
|
|
d4a2e23793 | ||
|
|
0a16e53b40 | ||
|
|
155288ee98 | ||
|
|
b66a5d2f88 | ||
|
|
667975fe3a | ||
|
|
997fc59c7e | ||
|
|
009a9f1c6e | ||
|
|
de83c29ba0 | ||
|
|
61d1751dff | ||
|
|
7fab86a49d | ||
|
|
613797a304 | ||
|
|
5f084cd98d | ||
|
|
d4c76258e3 | ||
|
|
1079aeaa13 | ||
|
|
61e112b43b | ||
|
|
fcfa418c4c | ||
|
|
89dbc0a25d | ||
|
|
2516c516bc | ||
|
|
077b6cfa21 | ||
|
|
eb0e9d5661 | ||
|
|
3a95054db5 | ||
|
|
c0e56c6011 | ||
|
|
56ea77ea96 | ||
|
|
33a606c034 | ||
|
|
45a9145a4b | ||
|
|
cc0b3c1cd1 | ||
|
|
c3e1ab859e | ||
|
|
cd2c8ade2d | ||
|
|
9fa562f888 | ||
|
|
af4c2107e0 | ||
|
|
3a57e52500 | ||
|
|
5091cb5ecd | ||
|
|
679c8de63f | ||
|
|
abb6fba24f | ||
|
|
3aefa5d3ce | ||
|
|
297546af3d | ||
|
|
1475c1b1c8 | ||
|
|
6e30dd05f4 | ||
|
|
b88595050f | ||
|
|
b77cee146b | ||
|
|
9dd22aebc7 | ||
|
|
d83bcf2c50 | ||
|
|
af4b63ff21 | ||
|
|
403dada85a | ||
|
|
c0cd7aa351 | ||
|
|
2de8c22a99 | ||
|
|
aa33166386 | ||
|
|
7eacdc7bb8 | ||
|
|
fe497573f6 | ||
|
|
6cf0ab376c | ||
|
|
7f8703ef74 | ||
|
|
048ba0d22d | ||
|
|
03ba583264 | ||
|
|
efa2635d56 | ||
|
|
45f8ae9e55 | ||
|
|
bc1fcc4584 | ||
|
|
9f326ea9c8 | ||
|
|
6cd2ccb35b | ||
|
|
f9d5ea4322 | ||
|
|
f3ee6b992b | ||
|
|
3b0f7659c7 | ||
|
|
1f2ff860f5 | ||
|
|
78ff5c1936 | ||
|
|
fbe4a9267f | ||
|
|
51e13ae588 | ||
|
|
e10fee0001 | ||
|
|
4330c63ea4 | ||
|
|
fb20b45100 | ||
|
|
e58a55aa82 | ||
|
|
d767f025cb | ||
|
|
0b0075e6ad | ||
|
|
cafa400fa5 | ||
|
|
f092dac979 | ||
|
|
6590140260 | ||
|
|
ba50127309 | ||
|
|
a4962240bd | ||
|
|
7f4c6f32da | ||
|
|
5c0e659516 | ||
|
|
986d70ccec | ||
|
|
f21dae6339 | ||
|
|
c4e77b406a | ||
|
|
b11720af45 | ||
|
|
35f47e5461 | ||
|
|
48b3bb980d | ||
|
|
1be3894e6f | ||
|
|
82494b8cc1 | ||
|
|
d1df09841d | ||
|
|
2c31b79235 | ||
|
|
c013c73f33 | ||
|
|
4503b5097f | ||
|
|
058a869b70 | ||
|
|
8df89db30e | ||
|
|
b6d845adb4 | ||
|
|
ea12da939f | ||
|
|
fca8e53842 | ||
|
|
4ec6671909 | ||
|
|
9edc984b09 | ||
|
|
e559f8714b | ||
|
|
927adf9bdd | ||
|
|
573b50ab2c | ||
|
|
cc01c3cb4d | ||
|
|
6b74e196ae | ||
|
|
919d9d791c | ||
|
|
8a98cbda84 | ||
|
|
2cb0f649f4 | ||
|
|
c8b4bedaa8 | ||
|
|
58eb5f39d4 | ||
|
|
f833159a68 | ||
|
|
2ba8ad1dfe | ||
|
|
97c763158c | ||
|
|
6621daee50 | ||
|
|
d7060c212f | ||
|
|
d6865c4d8d | ||
|
|
91f68e7d11 | ||
|
|
7eeb735cab | ||
|
|
24ca754bd5 | ||
|
|
e323ba4f27 | ||
|
|
23933dcb24 | ||
|
|
bda12ddd7d | ||
|
|
8667566f78 | ||
|
|
18c2aed1c9 | ||
|
|
e07247f8da | ||
|
|
c9c07ae754 | ||
|
|
ac20a5182f | ||
|
|
235d2ed246 | ||
|
|
c7cd76f69a | ||
|
|
4c530dea1a | ||
|
|
27905f1a4a | ||
|
|
9db78dc4c4 | ||
|
|
483cca78a1 | ||
|
|
795f1c75cb | ||
|
|
281e9f39fd | ||
|
|
7a532056e2 | ||
|
|
6014e7257e | ||
|
|
538af97d8d | ||
|
|
5d4d3f8366 | ||
|
|
c1bdb552bc | ||
|
|
1dfd977ec4 | ||
|
|
f649147080 | ||
|
|
e1aa98fe07 | ||
|
|
3c63c3044d | ||
|
|
92705306bf | ||
|
|
70e2c1c7d4 | ||
|
|
b6eef1c0c2 | ||
|
|
80cebdc23c | ||
|
|
ab7a5c4ff1 | ||
|
|
9997e2030c | ||
|
|
fa0bbbf96d | ||
|
|
04fb10914c | ||
|
|
39a9e9874e | ||
|
|
1b8dbf072a | ||
|
|
a39d536282 | ||
|
|
559dd99469 | ||
|
|
27aff22a9b | ||
|
|
33b874fea3 | ||
|
|
817fea6330 | ||
|
|
dac40af6ee | ||
|
|
b24d21d1ae | ||
|
|
3ef71edd81 | ||
|
|
c7297e552b | ||
|
|
d4457ef420 | ||
|
|
d24f384174 | ||
|
|
7841f1c509 | ||
|
|
109c7e3349 | ||
|
|
8ed467d438 | ||
|
|
dfbdb5bcd7 | ||
|
|
2060fd9cbe | ||
|
|
1e86c89f36 | ||
|
|
7ea4a03c83 | ||
|
|
569998011e | ||
|
|
14ef2b445a | ||
|
|
1d40385d4a | ||
|
|
0e44af9f70 | ||
|
|
6792447dfa | ||
|
|
5e9663d3d4 | ||
|
|
30cd77a30b | ||
|
|
dc33ecad6d | ||
|
|
526c978f96 | ||
|
|
3842c3de65 | ||
|
|
27db929252 | ||
|
|
4134d8ad13 | ||
|
|
a9bc7dc405 | ||
|
|
d499ec4838 | ||
|
|
62d15ac7c1 | ||
|
|
c4e083f7e1 | ||
|
|
c8fd232678 | ||
|
|
fd0efb21c3 | ||
|
|
0810901766 | ||
|
|
0df5c01a8c | ||
|
|
c5968049bb | ||
|
|
548d99bb45 | ||
|
|
6151f7bc4b | ||
|
|
b1eb757e60 | ||
|
|
5b05f75a27 | ||
|
|
db1b4dc890 | ||
|
|
68b1cd8d1b | ||
|
|
a605d69092 | ||
|
|
bf25837617 | ||
|
|
1bb5eb1da2 | ||
|
|
9b5c492be5 | ||
|
|
87bc39dca7 | ||
|
|
76f4856479 | ||
|
|
fa6b21a15b | ||
|
|
ef100f12a1 | ||
|
|
22f78ea38e | ||
|
|
725edc78b2 | ||
|
|
423d8c1b0d | ||
|
|
f64a6259b2 | ||
|
|
ce42ff9cf7 | ||
|
|
0f184d77c8 | ||
|
|
643ac9dd7a | ||
|
|
88acda0256 | ||
|
|
8ba6d9f227 | ||
|
|
8b940c005f | ||
|
|
143401451c | ||
|
|
decbd396df | ||
|
|
7a828de1bc | ||
|
|
01a784bd11 | ||
|
|
fb31bd3806 |
28
.clang-format
Normal file
28
.clang-format
Normal file
@@ -0,0 +1,28 @@
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 8
|
||||
UseTab: Always
|
||||
BreakBeforeBraces: Custom
|
||||
Standard: Cpp03
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
IndentCaseLabels: false
|
||||
AccessModifierOffset: -8
|
||||
ColumnLimit: 90
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
SortIncludes: false
|
||||
IncludeCategories:
|
||||
- Regex: '^".*'
|
||||
Priority: 2
|
||||
- Regex: '^<.*'
|
||||
Priority: 1
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
ContinuationIndentWidth: 16
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -21,9 +21,13 @@
|
||||
tags
|
||||
!tags/
|
||||
gtags.files
|
||||
.idea/*
|
||||
# Codelite
|
||||
*.project
|
||||
|
||||
## Files related to minetest development cycle
|
||||
/*.patch
|
||||
*.diff
|
||||
# GNU Patch reject file
|
||||
*.rej
|
||||
|
||||
@@ -42,11 +46,17 @@ gtags.files
|
||||
!/mods/minetest/mods_here.txt
|
||||
/worlds
|
||||
/world/
|
||||
/clientmods/*
|
||||
!/clientmods/preview/
|
||||
/client/mod_storage/
|
||||
|
||||
## Configuration/log files
|
||||
minetest.conf
|
||||
debug.txt
|
||||
|
||||
## Other files generated by minetest
|
||||
screenshot_*.png
|
||||
|
||||
## Doxygen files
|
||||
doc/Doxyfile
|
||||
doc/html/
|
||||
@@ -71,16 +81,21 @@ locale/
|
||||
*.layout
|
||||
*.o
|
||||
*.a
|
||||
*.ninja
|
||||
.ninja*
|
||||
*.gch
|
||||
cmake-build-debug/
|
||||
cmake-build-release/
|
||||
|
||||
## Android build files
|
||||
build/android/src/main/assets
|
||||
build/android/build
|
||||
build/android/deps
|
||||
build/android/libs
|
||||
build/android/jni/lib
|
||||
build/android/jni/src
|
||||
build/android/src/main/jniLibs
|
||||
build/android/obj
|
||||
build/android/local.properties
|
||||
build/android/.gradle
|
||||
timestamp
|
||||
|
||||
|
||||
223
.gitlab-ci.yml
Normal file
223
.gitlab-ci.yml
Normal file
@@ -0,0 +1,223 @@
|
||||
---
|
||||
# Github repository is cloned every day on Gitlab.com
|
||||
# https://gitlab.com/minetest/minetest
|
||||
# Pipelines URL: https://gitlab.com/minetest/minetest/pipelines
|
||||
|
||||
stages:
|
||||
- build
|
||||
- package
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
MINETEST_GAME_REPO: "https://github.com/minetest/minetest_game.git"
|
||||
|
||||
.build_template: &build_definition
|
||||
stage: build
|
||||
script:
|
||||
- mkdir cmakebuild
|
||||
- mkdir -p artifact/minetest/usr/
|
||||
- cd cmakebuild
|
||||
- cmake -DCMAKE_INSTALL_PREFIX=../artifact/minetest/usr/ -DCMAKE_BUILD_TYPE=Release -DRUN_IN_PLACE=FALSE -DENABLE_GETTEXT=TRUE -DBUILD_SERVER=TRUE ..
|
||||
- make -j2
|
||||
- make install
|
||||
artifacts:
|
||||
when: on_success
|
||||
expire_in: 1h
|
||||
paths:
|
||||
- artifact/*
|
||||
|
||||
.debpkg_template: &debpkg_template
|
||||
stage: package
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get install -y git
|
||||
- mkdir -p build/deb/minetest/DEBIAN/
|
||||
- cp misc/debpkg-control build/deb/minetest/DEBIAN/control
|
||||
- cp -Rp artifact/minetest/usr build/deb/minetest/
|
||||
script:
|
||||
- git clone $MINETEST_GAME_REPO build/deb/minetest/usr/share/minetest/games/minetest
|
||||
- rm -Rf build/deb/minetest/usr/share/minetest/games/minetest/.git
|
||||
- sed -i 's/DATEPLACEHOLDER/'$(date +%y.%m.%d)'/g' build/deb/minetest/DEBIAN/control
|
||||
- sed -i 's/LEVELDB_PLACEHOLDER/'$LEVELDB_PKG'/g' build/deb/minetest/DEBIAN/control
|
||||
- cd build/deb/ && dpkg-deb -b minetest/
|
||||
artifacts:
|
||||
when: on_success
|
||||
expire_in: 30 day
|
||||
paths:
|
||||
- build/deb/*.deb
|
||||
|
||||
.debpkg_install: &debpkg_install
|
||||
stage: deploy
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get install -y libc6 libcurl3-gnutls libfreetype6 libirrlicht1.8 $LEVELDB_PKG liblua5.1-0 libluajit-5.1-2 libopenal1 libstdc++6 libvorbisfile3 libx11-6 zlib1g
|
||||
script:
|
||||
- dpkg -i build/deb/*.deb
|
||||
|
||||
##
|
||||
## Debian
|
||||
##
|
||||
|
||||
# Jessie
|
||||
|
||||
build:debian-8:
|
||||
<<: *build_definition
|
||||
image: debian:8
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:debian-8:
|
||||
image: debian:8
|
||||
dependencies:
|
||||
- build:debian-8
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1
|
||||
<<: *debpkg_template
|
||||
|
||||
deploy:debian-8:
|
||||
image: debian:8
|
||||
dependencies:
|
||||
- package:debian-8
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1
|
||||
<<: *debpkg_install
|
||||
|
||||
# Stretch
|
||||
|
||||
build:debian-9:
|
||||
<<: *build_definition
|
||||
image: debian:9
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:debian-9:
|
||||
image: debian:9
|
||||
dependencies:
|
||||
- build:debian-9
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
<<: *debpkg_template
|
||||
|
||||
deploy:debian-9:
|
||||
image: debian:9
|
||||
dependencies:
|
||||
- package:debian-9
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
<<: *debpkg_install
|
||||
|
||||
##
|
||||
## Ubuntu
|
||||
##
|
||||
|
||||
# Trusty
|
||||
|
||||
build:ubuntu-14.04:
|
||||
<<: *build_definition
|
||||
image: ubuntu:trusty
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:ubuntu-14.04:
|
||||
image: ubuntu:trusty
|
||||
dependencies:
|
||||
- build:ubuntu-14.04
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1
|
||||
<<: *debpkg_template
|
||||
|
||||
deploy:ubuntu-14.04:
|
||||
image: ubuntu:trusty
|
||||
dependencies:
|
||||
- package:ubuntu-14.04
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1
|
||||
<<: *debpkg_install
|
||||
|
||||
# Xenial
|
||||
|
||||
build:ubuntu-16.04:
|
||||
<<: *build_definition
|
||||
image: ubuntu:xenial
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:ubuntu-16.04:
|
||||
image: ubuntu:xenial
|
||||
dependencies:
|
||||
- build:ubuntu-16.04
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
<<: *debpkg_template
|
||||
|
||||
deploy:ubuntu-16.04:
|
||||
image: ubuntu:xenial
|
||||
dependencies:
|
||||
- package:ubuntu-16.04
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
<<: *debpkg_install
|
||||
|
||||
# Yakkety
|
||||
|
||||
build:ubuntu-16.10:
|
||||
<<: *build_definition
|
||||
image: ubuntu:yakkety
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:ubuntu-16.10:
|
||||
image: ubuntu:yakkety
|
||||
dependencies:
|
||||
- build:ubuntu-16.10
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
<<: *debpkg_template
|
||||
|
||||
deploy:ubuntu-16.10:
|
||||
image: ubuntu:yakkety
|
||||
dependencies:
|
||||
- package:ubuntu-16.10
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
<<: *debpkg_install
|
||||
|
||||
# Zesty
|
||||
|
||||
build:ubuntu-17.04:
|
||||
<<: *build_definition
|
||||
image: ubuntu:zesty
|
||||
before_script:
|
||||
- apt-get update -y
|
||||
- apt-get -y install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
package:ubuntu-17.04:
|
||||
image: ubuntu:zesty
|
||||
dependencies:
|
||||
- build:ubuntu-17.04
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
<<: *debpkg_template
|
||||
|
||||
deploy:ubuntu-17.04:
|
||||
image: ubuntu:zesty
|
||||
dependencies:
|
||||
- package:ubuntu-17.04
|
||||
variables:
|
||||
LEVELDB_PKG: libleveldb1v5
|
||||
<<: *debpkg_install
|
||||
|
||||
##
|
||||
## Fedora
|
||||
##
|
||||
|
||||
build:fedora-24:
|
||||
<<: *build_definition
|
||||
image: fedora:24
|
||||
before_script:
|
||||
- dnf -y install make automake gcc gcc-c++ kernel-devel cmake libcurl* openal* libvorbis* libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel bzip2-libs gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel doxygen spatialindex-devel bzip2-devel
|
||||
44
.travis.yml
44
.travis.yml
@@ -1,14 +1,4 @@
|
||||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
os:
|
||||
- osx
|
||||
- linux
|
||||
env:
|
||||
- PLATFORM=Win32
|
||||
- PLATFORM=Win64
|
||||
- PLATFORM=Unix
|
||||
before_install: ./util/travis/before_install.sh
|
||||
script: ./util/travis/script.sh
|
||||
sudo: required
|
||||
@@ -16,14 +6,34 @@ notifications:
|
||||
email: false
|
||||
matrix:
|
||||
fast_finish: true
|
||||
exclude:
|
||||
include:
|
||||
- env: PLATFORM=Win32
|
||||
compiler: clang
|
||||
compiler: gcc
|
||||
os: linux
|
||||
- env: PLATFORM=Win64
|
||||
compiler: gcc
|
||||
os: linux
|
||||
- env: PLATFORM=Unix COMPILER=clang
|
||||
compiler: clang
|
||||
- env: PLATFORM=Win32
|
||||
os: osx
|
||||
- env: PLATFORM=Win64
|
||||
os: osx
|
||||
- compiler: gcc
|
||||
os: osx
|
||||
- env: PLATFORM=Unix COMPILER=g++
|
||||
compiler: gcc
|
||||
os: linux
|
||||
- env: PLATFORM=Unix COMPILER=clang
|
||||
compiler: clang
|
||||
os: linux
|
||||
- env: PLATFORM=Unix COMPILER=clang VALGRIND=1
|
||||
compiler: clang
|
||||
os: linux
|
||||
dist: trusty
|
||||
- env: COMPILER=none LINT=1
|
||||
compiler: clang
|
||||
os: linux
|
||||
dist: trusty
|
||||
- env: PLATFORM=Unix COMPILER=g++-6
|
||||
compiler: gcc
|
||||
os: linux
|
||||
addons:
|
||||
apt:
|
||||
sources: &sources
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
@@ -13,7 +13,7 @@ set(PROJECT_NAME_CAPITALIZED "Minetest")
|
||||
# Also remember to set PROTOCOL_VERSION in network/networkprotocol.h when releasing
|
||||
set(VERSION_MAJOR 0)
|
||||
set(VERSION_MINOR 4)
|
||||
set(VERSION_PATCH 14)
|
||||
set(VERSION_PATCH 16)
|
||||
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||
|
||||
# Change to false for releases
|
||||
@@ -26,6 +26,11 @@ elseif(DEVELOPMENT_BUILD)
|
||||
set(VERSION_STRING "${VERSION_STRING}-dev")
|
||||
endif()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
# Append "-debug" to version string
|
||||
set(VERSION_STRING "${VERSION_STRING}-debug")
|
||||
endif()
|
||||
|
||||
message(STATUS "*** Will build version ${VERSION_STRING} ***")
|
||||
|
||||
|
||||
@@ -49,7 +54,6 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type: Debug or Release" FORCE)
|
||||
endif()
|
||||
|
||||
|
||||
# Included stuff
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
|
||||
|
||||
@@ -82,7 +86,7 @@ elseif(UNIX) # Linux, BSD etc
|
||||
set(EXAMPLE_CONF_DIR ".")
|
||||
set(MANDIR "unix/man")
|
||||
set(XDG_APPS_DIR "unix/applications")
|
||||
set(APPDATADIR "unix/appdata")
|
||||
set(APPDATADIR "unix/metainfo")
|
||||
set(ICONDIR "unix/icons")
|
||||
set(LOCALEDIR "locale")
|
||||
else()
|
||||
@@ -92,7 +96,7 @@ elseif(UNIX) # Linux, BSD etc
|
||||
set(MANDIR "${CMAKE_INSTALL_PREFIX}/share/man")
|
||||
set(EXAMPLE_CONF_DIR ${DOCDIR})
|
||||
set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
|
||||
set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/appdata")
|
||||
set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/metainfo")
|
||||
set(ICONDIR "${CMAKE_INSTALL_PREFIX}/share/icons")
|
||||
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/locale")
|
||||
endif()
|
||||
@@ -152,6 +156,7 @@ endif()
|
||||
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/builtin" DESTINATION "${SHAREDIR}")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/client" DESTINATION "${SHAREDIR}")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/clientmods" DESTINATION "${SHAREDIR}")
|
||||
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/games" DESTINATION "${SHAREDIR}" PATTERN ".git*" EXCLUDE)
|
||||
|
||||
if(BUILD_CLIENT)
|
||||
@@ -167,14 +172,18 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/fonts" DESTINATION "${SHAREDIR}")
|
||||
install(FILES "README.txt" DESTINATION "${DOCDIR}")
|
||||
install(FILES "doc/lua_api.txt" DESTINATION "${DOCDIR}")
|
||||
install(FILES "doc/menu_lua_api.txt" DESTINATION "${DOCDIR}")
|
||||
install(FILES "doc/texture_packs.txt" DESTINATION "${DOCDIR}")
|
||||
install(FILES "doc/world_format.txt" DESTINATION "${DOCDIR}")
|
||||
install(FILES "minetest.conf.example" DESTINATION "${EXAMPLE_CONF_DIR}")
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
install(FILES "doc/minetest.6" "doc/minetestserver.6" DESTINATION "${MANDIR}/man6")
|
||||
install(FILES "misc/minetest.desktop" DESTINATION "${XDG_APPS_DIR}")
|
||||
install(FILES "misc/minetest.appdata.xml" DESTINATION "${APPDATADIR}")
|
||||
install(FILES "misc/net.minetest.minetest.desktop" DESTINATION "${XDG_APPS_DIR}")
|
||||
install(FILES "misc/net.minetest.minetest.appdata.xml" DESTINATION "${APPDATADIR}")
|
||||
install(FILES "misc/minetest.svg" DESTINATION "${ICONDIR}/hicolor/scalable/apps")
|
||||
install(FILES "misc/minetest-xorg-icon-128.png"
|
||||
DESTINATION "${ICONDIR}/hicolor/128x128/apps"
|
||||
RENAME "minetest.png")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
@@ -182,6 +191,10 @@ if(APPLE)
|
||||
install(FILES "misc/Info.plist" DESTINATION "${BUNDLE_PATH}/Contents")
|
||||
endif()
|
||||
|
||||
# Library pack
|
||||
find_package(GMP REQUIRED)
|
||||
find_package(Json REQUIRED)
|
||||
find_package(Lua REQUIRED)
|
||||
|
||||
# Subdirectories
|
||||
# Be sure to add all relevant definitions above this
|
||||
|
||||
@@ -25,7 +25,6 @@ If you are planning to start some significant coding, you would benefit from ask
|
||||
- Have a title which begins with a capital letter
|
||||
- Be descriptive. (e.g. no `Update init.lua` or `Fix a problem`)
|
||||
- Have a first line with less than *80 characters* and have a second line that is *empty*
|
||||
- Do **not** [sign your commits](https://git-scm.com/book/uz/v2/Git-Tools-Signing-Your-Work), as Minetest offers automatically built ppas over launchpad and it [would break](https://bugs.launchpad.net/bzr-git/+bug/1084403) if there were signed commits in master
|
||||
|
||||
4. Once you are happy with your changes, submit a pull request.
|
||||
- Open the [pull-request form](https://github.com/minetest/minetest/pull/new/master)
|
||||
|
||||
129
README.txt
129
README.txt
@@ -3,7 +3,7 @@ Minetest
|
||||
|
||||
An InfiniMiner/Minecraft inspired game.
|
||||
|
||||
Copyright (c) 2010-2013 Perttu Ahola <celeron55@gmail.com>
|
||||
Copyright (c) 2010-2017 Perttu Ahola <celeron55@gmail.com>
|
||||
and contributors (see source file comments and the version control log)
|
||||
|
||||
In case you downloaded the source code:
|
||||
@@ -27,39 +27,47 @@ This game is not finished
|
||||
- Don't expect it to work as well as a finished game will.
|
||||
- Please report any bugs. When doing that, debug.txt is useful.
|
||||
|
||||
Default Controls
|
||||
Default controls
|
||||
-----------------
|
||||
- WASD: move
|
||||
- Space: jump/climb
|
||||
- Shift: sneak/go down
|
||||
- Q: drop itemstack (+ SHIFT for single item)
|
||||
- I: inventory
|
||||
- Mouse: turn/look
|
||||
- Mouse left: dig/punch
|
||||
- Mouse right: place/use
|
||||
- Mouse wheel: select item
|
||||
- T: chat
|
||||
- 1-8: select item
|
||||
- Move mouse: Look around
|
||||
- W, A, S, D: Move
|
||||
- Space: Jump/move up
|
||||
- Shift: Sneak/move down
|
||||
- Q: Drop itemstack
|
||||
- Shift + Q: Drop single item
|
||||
- Left mouse button: Dig/punch/take item
|
||||
- Right mouse button: Place/use
|
||||
- Shift + right mouse button: Build (without using)
|
||||
- I: Inventory menu
|
||||
- Mouse wheel: Select item
|
||||
- 0-9: Select item
|
||||
- Z: Zoom (needs zoom privilege)
|
||||
- T: Chat
|
||||
- /: Command
|
||||
|
||||
- Esc: pause menu (pauses only singleplayer game)
|
||||
- R: Enable/Disable full range view
|
||||
- Esc: Pause menu/abort/exit (pauses only singleplayer game)
|
||||
- R: Enable/disable full range view
|
||||
- +: Increase view range
|
||||
- -: Decrease view range
|
||||
- K: Enable/Disable fly (needs fly privilege)
|
||||
- J: Enable/Disable fast (needs fast privilege)
|
||||
- H: Enable/Disable noclip (needs noclip privilege)
|
||||
- K: Enable/disable fly mode (needs fly privilege)
|
||||
- J: Enable/disable fast mode (needs fast privilege)
|
||||
- H: Enable/disable noclip mode (needs noclip privilege)
|
||||
|
||||
- F1: Hide/Show HUD
|
||||
- F2: Hide/Show Chat
|
||||
- F3: Disable/Enable Fog
|
||||
- F4: Disable/Enable Camera update (Mapblocks are not updated anymore when disabled)
|
||||
- F5: Toogle through debug info screens
|
||||
- F6: Toogle through output data
|
||||
- F7: Toggle through camera modes
|
||||
- F10: Show/Hide console
|
||||
- F1: Hide/show HUD
|
||||
- F2: Hide/show chat
|
||||
- F3: Disable/enable fog
|
||||
- F4: Disable/enable camera update (Mapblocks are not updated anymore when disabled, disabled in release builds)
|
||||
- F5: Cycle through debug info screens
|
||||
- F6: Cycle through profiler info screens
|
||||
- F7: Cycle through camera modes
|
||||
- F8: Toggle cinematic mode
|
||||
- F9: Cycle through minimap modes
|
||||
- Shift + F9: Change minimap orientation
|
||||
- F10: Show/hide console
|
||||
- F12: Take screenshot
|
||||
- P: Write stack traces into debug.txt
|
||||
|
||||
- Settable in the configuration file, see the section below.
|
||||
Most controls are settable in the configuration file, see the section below.
|
||||
|
||||
Paths
|
||||
------
|
||||
@@ -77,7 +85,7 @@ $bin = /usr/bin
|
||||
$share = /usr/share/minetest
|
||||
$user = ~/.minetest
|
||||
|
||||
OS X:
|
||||
macOS:
|
||||
$bin = Contents/MacOS
|
||||
$share = Contents/Resources
|
||||
$user = Contents/User OR ~/Library/Application Support/minetest
|
||||
@@ -93,7 +101,9 @@ Configuration file:
|
||||
$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>
|
||||
- A run-in-place build will look for the configuration file in
|
||||
$location_of_exe/../minetest.conf and also $location_of_exe/../../minetest.conf
|
||||
|
||||
Command-line options:
|
||||
---------------------
|
||||
@@ -103,18 +113,18 @@ Compiling on GNU/Linux:
|
||||
-----------------------
|
||||
|
||||
Install dependencies. Here's an example for Debian/Ubuntu:
|
||||
$ sudo apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng12-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
$ sudo apt-get install build-essential libirrlicht-dev cmake libbz2-dev libpng-dev libjpeg-dev libxxf86vm-dev libgl1-mesa-dev libsqlite3-dev libogg-dev libvorbis-dev libopenal-dev libcurl4-gnutls-dev libfreetype6-dev zlib1g-dev libgmp-dev libjsoncpp-dev
|
||||
|
||||
For Fedora users:
|
||||
$ sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libcurl* openal* libvorbis* libXxf86vm-devel libogg-devel freetype-devel mesa-libGL-devel zlib-devel jsoncpp-devel irrlicht-devel bzip2-libs gmp-devel sqlite-devel luajit-devel leveldb-devel ncurses-devel doxygen spatialindex-devel bzip2-devel
|
||||
|
||||
You can install git for easily keeping your copy up to date.
|
||||
If you dont want git, read below on how to get the source without git.
|
||||
If you don’t want git, read below on how to get the source without git.
|
||||
This is an example for installing git on Debian/Ubuntu:
|
||||
$ sudo apt-get install git-core
|
||||
$ sudo apt-get install git
|
||||
|
||||
For Fedora users:
|
||||
$ sudo dnf install git-core
|
||||
$ sudo dnf install git
|
||||
|
||||
Download source (this is the URL to the latest of source repository, which might not work at all times) using git:
|
||||
$ git clone --depth 1 https://github.com/minetest/minetest.git
|
||||
@@ -169,7 +179,8 @@ ENABLE_CURSES - Build with (n)curses; Enables a server side terminal (comm
|
||||
ENABLE_FREETYPE - Build with FreeType2; Allows using TTF fonts
|
||||
ENABLE_GETTEXT - Build with Gettext; Allows using translations
|
||||
ENABLE_GLES - Search for Open GLES headers & libraries and use them
|
||||
ENABLE_LEVELDB - Build with LevelDB; Enables use of LevelDB map backend (faster than SQLite3)
|
||||
ENABLE_LEVELDB - Build with LevelDB; Enables use of LevelDB map backend
|
||||
ENABLE_POSTGRESQL - Build with libpq; Enables use of PostgreSQL map backend (PostgreSQL 9.5 or greater recommended)
|
||||
ENABLE_REDIS - Build with libhiredis; Enables use of Redis map backend
|
||||
ENABLE_SPATIAL - Build with LibSpatial; Speeds up AreaStores
|
||||
ENABLE_SOUND - Build with OpenAL, libogg & libvorbis; in-game Sounds
|
||||
@@ -203,6 +214,8 @@ IRRLICHT_LIBRARY - Path to libIrrlicht.a/libIrrlicht.so/libIrrlic
|
||||
LEVELDB_INCLUDE_DIR - Only when building with LevelDB; directory that contains db.h
|
||||
LEVELDB_LIBRARY - Only when building with LevelDB; path to libleveldb.a/libleveldb.so/libleveldb.dll.a
|
||||
LEVELDB_DLL - Only when building with LevelDB on Windows; path to libleveldb.dll
|
||||
PostgreSQL_INCLUDE_DIR - Only when building with PostgreSQL; directory that contains libpq-fe.h
|
||||
POSTGRESQL_LIBRARY - Only when building with PostgreSQL; path to libpq.a/libpq.so
|
||||
REDIS_INCLUDE_DIR - Only when building with Redis; directory that contains hiredis.h
|
||||
REDIS_LIBRARY - Only when building with Redis; path to libhiredis.a/libhiredis.so
|
||||
SPATIAL_INCLUDE_DIR - Only when building with LibSpatial; directory that contains spatialindex/SpatialIndex.h
|
||||
@@ -249,6 +262,8 @@ Compiling on Windows:
|
||||
http://www.winimage.com/zLibDll/index.html
|
||||
* Zlib library (zlibwapi.lib and zlibwapi.dll from zlib125dll.zip):
|
||||
http://www.winimage.com/zLibDll/index.html
|
||||
* SQLite3 headers and library
|
||||
https://www.sqlite.org/download.html
|
||||
* Optional: gettext library and tools:
|
||||
http://gnuwin32.sourceforge.net/downlinks/gettext.php
|
||||
- This is used for other UI languages. Feel free to leave it out.
|
||||
@@ -260,6 +275,10 @@ Compiling on Windows:
|
||||
- Download all the other stuff to DIR and extract them into there.
|
||||
("extract here", not "extract to packagename/")
|
||||
NOTE: zlib125dll.zip needs to be extracted into zlib125dll
|
||||
NOTE: You need to extract sqlite3.h & sqlite3ext.h from sqlite3 source
|
||||
and sqlite3.dll & sqlite3.def from sqlite3 precompiled binaries
|
||||
into "sqlite3" directory, and generate sqlite3.lib using command
|
||||
"LIB /DEF:sqlite3.def /OUT:sqlite3.lib"
|
||||
- All those packages contain a nice base directory in them, which
|
||||
should end up being the direct subdirectories of DIR.
|
||||
- You will end up with a directory structure like this (+=dir, -=file):
|
||||
@@ -267,7 +286,9 @@ Compiling on Windows:
|
||||
+ DIR
|
||||
- zlib-1.2.5.tar.gz
|
||||
- zlib125dll.zip
|
||||
- irrlicht-1.7.1.zip
|
||||
- irrlicht-1.8.3.zip
|
||||
- sqlite-amalgamation-3130000.zip (SQLite3 headers)
|
||||
- sqlite-dll-win32-x86-3130000.zip (SQLite3 library for 32bit system)
|
||||
- 110214175330.zip (or whatever, this is the minetest source)
|
||||
+ zlib-1.2.5
|
||||
- zlib.h
|
||||
@@ -277,10 +298,15 @@ Compiling on Windows:
|
||||
- readme.txt
|
||||
+ dll32
|
||||
...
|
||||
+ irrlicht-1.7.1
|
||||
+ irrlicht-1.8.3
|
||||
+ lib
|
||||
+ include
|
||||
...
|
||||
+ sqlite3
|
||||
sqlite3.h
|
||||
sqlite3ext.h
|
||||
sqlite3.lib
|
||||
sqlite3.dll
|
||||
+ gettext (optional)
|
||||
+bin
|
||||
+include
|
||||
@@ -307,7 +333,7 @@ Compiling on Windows:
|
||||
BUILD_SERVER [ ]
|
||||
CMAKE_BUILD_TYPE Release
|
||||
CMAKE_INSTALL_PREFIX DIR/minetest-install
|
||||
IRRLICHT_SOURCE_DIR DIR/irrlicht-1.7.1
|
||||
IRRLICHT_SOURCE_DIR DIR/irrlicht-1.8.3
|
||||
RUN_IN_PLACE [X]
|
||||
WARN_ALL [ ]
|
||||
ZLIB_DLL DIR/zlib125dll/dll32/zlibwapi.dll
|
||||
@@ -318,6 +344,11 @@ Compiling on Windows:
|
||||
GETTEXT_LIBRARIES DIR/gettext/lib/intl.lib
|
||||
GETTEXT_MSGFMT DIR/gettext/bin/msgfmt
|
||||
-----------------
|
||||
- If CMake complains it couldn't find SQLITE3, choose "Advanced" box on the
|
||||
right top corner, then specify the location of SQLITE3_INCLUDE_DIR and
|
||||
SQLITE3_LIBRARY manually.
|
||||
- If you want to build 64-bit minetest, you will need to build 64-bit version
|
||||
of irrlicht engine manually, as only 32-bit pre-built library is provided.
|
||||
- Hit "Configure"
|
||||
- Hit "Configure" once again 8)
|
||||
- If something is still coloured red, you have a problem.
|
||||
@@ -382,6 +413,9 @@ Authors of media files
|
||||
Everything not listed in here:
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
ShadowNinja:
|
||||
textures/base/pack/smoke_puff.png
|
||||
|
||||
Paramat:
|
||||
textures/base/pack/menu_header.png
|
||||
|
||||
@@ -395,7 +429,7 @@ License of Minetest source code
|
||||
-------------------------------
|
||||
|
||||
Minetest
|
||||
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
Copyright (C) 2010-2017 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
@@ -470,7 +504,7 @@ 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 .
|
||||
For details and rationale, see https://www.lua.org/license.html .
|
||||
|
||||
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
|
||||
|
||||
@@ -495,25 +529,18 @@ 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:
|
||||
Arimo - Apache License, version 2.0
|
||||
Digitized data copyright (c) 2010-2012 Google Corporation.
|
||||
|
||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||
Cousine - Apache License, version 2.0
|
||||
Digitized data copyright (c) 2010-2012 Google Corporation.
|
||||
|
||||
Liberation Fonts Copyright:
|
||||
|
||||
Copyright (c) 2007 Red Hat, Inc. All rights reserved. LIBERATION is a trademark of Red Hat, Inc.
|
||||
|
||||
DroidSansFallback:
|
||||
DroidSansFallBackFull:
|
||||
|
||||
Copyright (C) 2008 The Android Open Source Project
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ TARGET_CXXFLAGS_ADDON = $(TARGET_CFLAGS_ADDON)
|
||||
TARGET_ARCH = armv7
|
||||
CROSS_PREFIX = arm-linux-androideabi-
|
||||
COMPILER_VERSION = 4.9
|
||||
HAVE_LEVELDB = 1
|
||||
HAVE_LEVELDB = 0
|
||||
|
||||
################################################################################
|
||||
# toolchain config for little endian mips
|
||||
@@ -59,7 +59,7 @@ HAVE_LEVELDB = 1
|
||||
#CROSS_PREFIX = i686-linux-android-
|
||||
#TARGET_ARCH = x86
|
||||
#COMPILER_VERSION = 4.9
|
||||
#HAVE_LEVELDB = 1
|
||||
#HAVE_LEVELDB = 0
|
||||
|
||||
################################################################################
|
||||
ASSETS_TIMESTAMP = deps/assets_timestamp
|
||||
@@ -84,14 +84,14 @@ OGG_TIMESTAMP = $(OGG_DIR)timestamp
|
||||
OGG_TIMESTAMP_INT = $(ANDR_ROOT)/deps/ogg_timestamp
|
||||
OGG_URL_GIT = https://github.com/vincentjames501/libvorbis-libogg-android
|
||||
|
||||
IRRLICHT_REVISION = 5122
|
||||
IRRLICHT_REVISION = 5145
|
||||
IRRLICHT_DIR = $(ANDR_ROOT)/deps/irrlicht/
|
||||
IRRLICHT_LIB = $(IRRLICHT_DIR)lib/Android/libIrrlicht.a
|
||||
IRRLICHT_TIMESTAMP = $(IRRLICHT_DIR)timestamp
|
||||
IRRLICHT_TIMESTAMP_INT = $(ANDR_ROOT)/deps/irrlicht_timestamp
|
||||
IRRLICHT_URL_SVN = https://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@$(IRRLICHT_REVISION)
|
||||
|
||||
OPENSSL_VERSION = 1.0.2h
|
||||
OPENSSL_VERSION = 1.0.2k
|
||||
OPENSSL_BASEDIR = openssl-$(OPENSSL_VERSION)
|
||||
OPENSSL_DIR = $(ANDR_ROOT)/deps/$(OPENSSL_BASEDIR)/
|
||||
OPENSSL_LIB = $(OPENSSL_DIR)/libssl.so.1.0.0
|
||||
@@ -99,14 +99,14 @@ OPENSSL_TIMESTAMP = $(OPENSSL_DIR)timestamp
|
||||
OPENSSL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/openssl_timestamp
|
||||
OPENSSL_URL = https://www.openssl.org/source/openssl-$(OPENSSL_VERSION).tar.gz
|
||||
|
||||
CURL_VERSION = 7.48.0
|
||||
CURL_VERSION = 7.54.0
|
||||
CURL_DIR = $(ANDR_ROOT)/deps/curl-$(CURL_VERSION)
|
||||
CURL_LIB = $(CURL_DIR)/lib/.libs/libcurl.a
|
||||
CURL_TIMESTAMP = $(CURL_DIR)/timestamp
|
||||
CURL_TIMESTAMP_INT = $(ANDR_ROOT)/deps/curl_timestamp
|
||||
CURL_URL_HTTP = https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.bz2
|
||||
|
||||
GMP_VERSION = 6.1.0
|
||||
GMP_VERSION = 6.1.2
|
||||
GMP_DIR = $(ANDR_ROOT)/deps/gmp-$(GMP_VERSION)
|
||||
GMP_LIB = $(GMP_DIR)/usr/lib/libgmp.so
|
||||
GMP_TIMESTAMP = $(GMP_DIR)/timestamp
|
||||
@@ -126,8 +126,8 @@ ICONV_TIMESTAMP = $(ICONV_DIR)timestamp
|
||||
ICONV_TIMESTAMP_INT = $(ANDR_ROOT)/deps/iconv_timestamp
|
||||
ICONV_URL_HTTP = https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$(ICONV_VERSION).tar.gz
|
||||
|
||||
SQLITE3_FOLDER = sqlite-amalgamation-3120200
|
||||
SQLITE3_URL = https://www.sqlite.org/2016/$(SQLITE3_FOLDER).zip
|
||||
SQLITE3_FOLDER = sqlite-amalgamation-3180000
|
||||
SQLITE3_URL = https://www.sqlite.org/2017/$(SQLITE3_FOLDER).zip
|
||||
|
||||
ANDROID_SDK = $(shell grep '^sdk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
|
||||
ANDROID_NDK = $(shell grep '^ndk\.dir' local.properties | sed 's/^.*=[[:space:]]*//')
|
||||
@@ -220,6 +220,8 @@ $(OPENAL_LIB): $(OPENAL_TIMESTAMP)
|
||||
${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \
|
||||
NDK_MODULE_PATH=${NDK_MODULE_PATH} APP_ABI=${TARGET_ABI} \
|
||||
TARGET_ARCH_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \
|
||||
PRIVATE_CC=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}gcc \
|
||||
PRIVATE_CXX=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}g++ \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
@@ -266,6 +268,8 @@ $(OGG_LIB): $(OGG_TIMESTAMP)
|
||||
${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \
|
||||
NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \
|
||||
PRIVATE_CC=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}gcc \
|
||||
PRIVATE_CXX=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}g++ \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
@@ -313,6 +317,7 @@ $(OPENSSL_LIB): $(OPENSSL_TIMESTAMP) $(GMP_LIB)
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-openssl; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--platform=android-9 \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
CC=${CROSS_PREFIX}gcc ./Configure enable-gmp -DL_ENDIAN -I${GMP_DIR} -L${GMP_DIR}/usr/lib android-${TARGET_ARCH};\
|
||||
@@ -347,7 +352,7 @@ leveldb_download :
|
||||
fi
|
||||
|
||||
leveldb : $(LEVELDB_LIB)
|
||||
|
||||
ifeq ($(HAVE_LEVELDB),1)
|
||||
$(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
|
||||
@REFRESH=0; \
|
||||
if [ ! -e ${LEVELDB_TIMESTAMP_INT} ] ; then \
|
||||
@@ -363,6 +368,7 @@ $(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-leveldb; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--platform=android-9 \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
export CC=${CROSS_PREFIX}gcc; \
|
||||
@@ -378,6 +384,7 @@ $(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
|
||||
else \
|
||||
echo "nothing to be done for leveldb"; \
|
||||
fi
|
||||
endif
|
||||
|
||||
clean_leveldb :
|
||||
$(RM) -rf deps/leveldb
|
||||
@@ -416,6 +423,8 @@ $(FREETYPE_LIB) : $(FREETYPE_TIMESTAMP)
|
||||
${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \
|
||||
NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_PLATFORM=${APP_PLATFORM} APP_ABI=${TARGET_ABI} \
|
||||
PRIVATE_CC=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}gcc \
|
||||
PRIVATE_CXX=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}g++ \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
@@ -469,6 +478,7 @@ $(ICONV_LIB) : $(ICONV_TIMESTAMP)
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-iconv; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--platform=android-9 \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
export CC=${CROSS_PREFIX}gcc; \
|
||||
@@ -531,6 +541,8 @@ $(IRRLICHT_LIB): $(IRRLICHT_TIMESTAMP) $(FREETYPE_LIB)
|
||||
${ANDROID_NDK}/ndk-build NDEBUG=${NDEBUG} \
|
||||
NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
APP_ABI=${TARGET_ABI} APP_PLATFORM=${APP_PLATFORM} \
|
||||
PRIVATE_CC=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}gcc \
|
||||
PRIVATE_CXX=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}g++ \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
TARGET_CXXFLAGS+="${TARGET_CXXFLAGS_ADDON}" || exit 1; \
|
||||
@@ -581,6 +593,7 @@ $(CURL_LIB): $(CURL_TIMESTAMP) $(OPENSSL_LIB)
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-curl; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--platform=android-9 \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
export CC=${CROSS_PREFIX}gcc; \
|
||||
@@ -640,6 +653,7 @@ $(GMP_LIB): $(GMP_TIMESTAMP)
|
||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-gmp; \
|
||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||
--platform=android-9 \
|
||||
--install-dir=$${TOOLCHAIN}; \
|
||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||
export CC=${CROSS_PREFIX}gcc; \
|
||||
@@ -665,7 +679,8 @@ deps/${SQLITE3_FOLDER}/sqlite3.c :
|
||||
cd deps; \
|
||||
wget ${SQLITE3_URL}; \
|
||||
unzip ${SQLITE3_FOLDER}.zip; \
|
||||
ln -s ${SQLITE3_FOLDER} sqlite
|
||||
ln -s ${SQLITE3_FOLDER} sqlite; \
|
||||
cd ${SQLITE3_FOLDER};
|
||||
|
||||
clean_sqlite3:
|
||||
cd deps && $(RM) -rf ${SQLITE3_FOLDER} && $(RM) -f ${SQLITE3_FOLDER}.zip && \
|
||||
@@ -752,9 +767,11 @@ clean_assets :
|
||||
apk: local.properties assets $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(GMP_LIB) $(LEVELDB_TARGET) \
|
||||
$(OPENAL_LIB) $(OGG_LIB) prep_srcdir $(ANDR_ROOT)/jni/src/android_version.h \
|
||||
$(ANDR_ROOT)/jni/src/android_version_githash.h sqlite3_download
|
||||
@${ANDROID_NDK}/ndk-build NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
+ @${ANDROID_NDK}/ndk-build NDK_MODULE_PATH=${NDK_MODULE_PATH} \
|
||||
GPROF=${GPROF} APP_ABI=${TARGET_ABI} HAVE_LEVELDB=${HAVE_LEVELDB} \
|
||||
APP_PLATFORM=${APP_PLATFORM} \
|
||||
PRIVATE_CC=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}gcc \
|
||||
PRIVATE_CXX=${NDK_MODULE_PATH}/${TARGET_TOOLCHAIN}${COMPILER_VERSION}/prebuilt/linux-x86_64/bin/${TARGET_TOOLCHAIN}g++ \
|
||||
TARGET_LIBDIR=${TARGET_LIBDIR} \
|
||||
TARGET_CFLAGS+="${TARGET_CFLAGS_ADDON}" \
|
||||
TARGET_LDFLAGS+="${TARGET_LDFLAGS_ADDON}" \
|
||||
@@ -764,7 +781,7 @@ apk: local.properties assets $(ICONV_LIB) $(IRRLICHT_LIB) $(CURL_LIB) $(GMP_LIB)
|
||||
fi; \
|
||||
export VERSION_STR="${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" && \
|
||||
export BUILD_TYPE_C=$$(echo "$${BUILD_TYPE}" | sed 's/./\U&/') && \
|
||||
gradle assemble$$BUILD_TYPE_C && \
|
||||
./gradlew assemble$$BUILD_TYPE_C && \
|
||||
echo "APK stored at: build/outputs/apk/Minetest-$$BUILD_TYPE.apk" && \
|
||||
echo "You can install it with \`make install_$$BUILD_TYPE\`"
|
||||
|
||||
@@ -778,11 +795,14 @@ install_release:
|
||||
|
||||
prep_srcdir :
|
||||
@if [ ! -e ${ANDR_ROOT}/jni/src ]; then \
|
||||
ln -s ${PROJ_ROOT}/src ${ANDR_ROOT}/jni/src; \
|
||||
ln -s ${PROJ_ROOT}/src ${ANDR_ROOT}/jni/src; \
|
||||
fi; \
|
||||
if [ ! -e ${ANDR_ROOT}/jni/lib ]; then \
|
||||
ln -s ${PROJ_ROOT}/lib ${ANDR_ROOT}/jni/lib; \
|
||||
fi
|
||||
|
||||
clean_apk :
|
||||
gradle clean
|
||||
./gradlew clean
|
||||
|
||||
clean_all :
|
||||
@$(MAKE) clean_apk; \
|
||||
@@ -831,4 +851,3 @@ $(ANDR_ROOT)/jni/src/android_version.h : prep_srcdir
|
||||
fi
|
||||
|
||||
clean : clean_apk clean_assets
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ buildscript {
|
||||
apply plugin: "com.android.application"
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.3"
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.3"
|
||||
|
||||
defaultConfig {
|
||||
versionCode 14
|
||||
versionCode 17
|
||||
versionName "${System.env.VERSION_STR}.${versionCode}"
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 9
|
||||
@@ -46,4 +46,3 @@ android {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
build/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
build/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
build/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
build/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Sat Aug 27 20:10:09 CEST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
||||
164
build/android/gradlew
vendored
Executable file
164
build/android/gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
build/android/gradlew.bat
vendored
Normal file
90
build/android/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -98,8 +98,8 @@ endif
|
||||
LOCAL_C_INCLUDES := \
|
||||
jni/src \
|
||||
jni/src/script \
|
||||
jni/src/lua/src \
|
||||
jni/src/json \
|
||||
jni/lib/lua/src \
|
||||
jni/lib/jsoncpp \
|
||||
jni/src/cguittfont \
|
||||
deps/irrlicht/include \
|
||||
deps/libiconv/include \
|
||||
@@ -117,6 +117,7 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/cavegen.cpp \
|
||||
jni/src/chat.cpp \
|
||||
jni/src/client.cpp \
|
||||
jni/src/clientenvironment.cpp \
|
||||
jni/src/clientiface.cpp \
|
||||
jni/src/clientmap.cpp \
|
||||
jni/src/clientmedia.cpp \
|
||||
@@ -133,6 +134,7 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/convert_json.cpp \
|
||||
jni/src/craftdef.cpp \
|
||||
jni/src/database-dummy.cpp \
|
||||
jni/src/database-files.cpp \
|
||||
jni/src/database-sqlite3.cpp \
|
||||
jni/src/database.cpp \
|
||||
jni/src/debug.cpp \
|
||||
@@ -141,6 +143,7 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/dungeongen.cpp \
|
||||
jni/src/emerge.cpp \
|
||||
jni/src/environment.cpp \
|
||||
jni/src/face_position_cache.cpp \
|
||||
jni/src/filecache.cpp \
|
||||
jni/src/filesys.cpp \
|
||||
jni/src/fontengine.cpp \
|
||||
@@ -163,12 +166,14 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/inventory.cpp \
|
||||
jni/src/inventorymanager.cpp \
|
||||
jni/src/itemdef.cpp \
|
||||
jni/src/itemstackmetadata.cpp \
|
||||
jni/src/keycode.cpp \
|
||||
jni/src/light.cpp \
|
||||
jni/src/localplayer.cpp \
|
||||
jni/src/log.cpp \
|
||||
jni/src/main.cpp \
|
||||
jni/src/map.cpp \
|
||||
jni/src/map_settings_manager.cpp \
|
||||
jni/src/mapblock.cpp \
|
||||
jni/src/mapblock_mesh.cpp \
|
||||
jni/src/mapgen.cpp \
|
||||
@@ -182,6 +187,8 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/mapnode.cpp \
|
||||
jni/src/mapsector.cpp \
|
||||
jni/src/mesh.cpp \
|
||||
jni/src/mesh_generator_thread.cpp \
|
||||
jni/src/metadata.cpp \
|
||||
jni/src/mg_biome.cpp \
|
||||
jni/src/mg_decoration.cpp \
|
||||
jni/src/mg_ore.cpp \
|
||||
@@ -202,10 +209,14 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/porting.cpp \
|
||||
jni/src/profiler.cpp \
|
||||
jni/src/quicktune.cpp \
|
||||
jni/src/raycast.cpp \
|
||||
jni/src/reflowscan.cpp \
|
||||
jni/src/remoteplayer.cpp \
|
||||
jni/src/rollback.cpp \
|
||||
jni/src/rollback_interface.cpp \
|
||||
jni/src/serialization.cpp \
|
||||
jni/src/server.cpp \
|
||||
jni/src/serverenvironment.cpp \
|
||||
jni/src/serverlist.cpp \
|
||||
jni/src/serverobject.cpp \
|
||||
jni/src/shader.cpp \
|
||||
@@ -215,6 +226,7 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/sound_openal.cpp \
|
||||
jni/src/staticobject.cpp \
|
||||
jni/src/subgame.cpp \
|
||||
jni/src/tileanimation.cpp \
|
||||
jni/src/tool.cpp \
|
||||
jni/src/treegen.cpp \
|
||||
jni/src/version.cpp \
|
||||
@@ -224,6 +236,7 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/util/auth.cpp \
|
||||
jni/src/util/base64.cpp \
|
||||
jni/src/util/directiontables.cpp \
|
||||
jni/src/util/enriched_string.cpp \
|
||||
jni/src/util/numeric.cpp \
|
||||
jni/src/util/pointedthing.cpp \
|
||||
jni/src/util/serialize.cpp \
|
||||
@@ -237,6 +250,7 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/unittest/test_connection.cpp \
|
||||
jni/src/unittest/test_filepath.cpp \
|
||||
jni/src/unittest/test_inventory.cpp \
|
||||
jni/src/unittest/test_map_settings_manager.cpp \
|
||||
jni/src/unittest/test_mapnode.cpp \
|
||||
jni/src/unittest/test_nodedef.cpp \
|
||||
jni/src/unittest/test_noderesolver.cpp \
|
||||
@@ -256,7 +270,10 @@ LOCAL_SRC_FILES := \
|
||||
jni/src/settings.cpp \
|
||||
jni/src/wieldmesh.cpp \
|
||||
jni/src/client/clientlauncher.cpp \
|
||||
jni/src/client/tile.cpp
|
||||
jni/src/client/inputhandler.cpp \
|
||||
jni/src/client/tile.cpp \
|
||||
jni/src/client/joystick_controller.cpp \
|
||||
jni/src/irrlicht_changes/static_text.cpp
|
||||
|
||||
# intentionally kept out (we already build openssl itself): jni/src/util/sha256.c
|
||||
|
||||
@@ -277,6 +294,7 @@ LOCAL_SRC_FILES += \
|
||||
jni/src/script/common/c_types.cpp \
|
||||
jni/src/script/cpp_api/s_async.cpp \
|
||||
jni/src/script/cpp_api/s_base.cpp \
|
||||
jni/src/script/cpp_api/s_client.cpp \
|
||||
jni/src/script/cpp_api/s_entity.cpp \
|
||||
jni/src/script/cpp_api/s_env.cpp \
|
||||
jni/src/script/cpp_api/s_inventory.cpp \
|
||||
@@ -289,12 +307,18 @@ LOCAL_SRC_FILES += \
|
||||
jni/src/script/cpp_api/s_server.cpp \
|
||||
jni/src/script/lua_api/l_areastore.cpp \
|
||||
jni/src/script/lua_api/l_base.cpp \
|
||||
jni/src/script/lua_api/l_camera.cpp \
|
||||
jni/src/script/lua_api/l_client.cpp \
|
||||
jni/src/script/lua_api/l_craft.cpp \
|
||||
jni/src/script/lua_api/l_env.cpp \
|
||||
jni/src/script/lua_api/l_inventory.cpp \
|
||||
jni/src/script/lua_api/l_item.cpp \
|
||||
jni/src/script/lua_api/l_itemstackmeta.cpp\
|
||||
jni/src/script/lua_api/l_localplayer.cpp \
|
||||
jni/src/script/lua_api/l_mainmenu.cpp \
|
||||
jni/src/script/lua_api/l_mapgen.cpp \
|
||||
jni/src/script/lua_api/l_metadata.cpp \
|
||||
jni/src/script/lua_api/l_minimap.cpp \
|
||||
jni/src/script/lua_api/l_nodemeta.cpp \
|
||||
jni/src/script/lua_api/l_nodetimer.cpp \
|
||||
jni/src/script/lua_api/l_noise.cpp \
|
||||
@@ -303,10 +327,13 @@ LOCAL_SRC_FILES += \
|
||||
jni/src/script/lua_api/l_rollback.cpp \
|
||||
jni/src/script/lua_api/l_server.cpp \
|
||||
jni/src/script/lua_api/l_settings.cpp \
|
||||
jni/src/script/lua_api/l_sound.cpp \
|
||||
jni/src/script/lua_api/l_http.cpp \
|
||||
jni/src/script/lua_api/l_storage.cpp \
|
||||
jni/src/script/lua_api/l_util.cpp \
|
||||
jni/src/script/lua_api/l_vmanip.cpp \
|
||||
jni/src/script/scripting_game.cpp \
|
||||
jni/src/script/scripting_client.cpp \
|
||||
jni/src/script/scripting_server.cpp \
|
||||
jni/src/script/scripting_mainmenu.cpp
|
||||
|
||||
#freetype2 support
|
||||
@@ -314,36 +341,36 @@ LOCAL_SRC_FILES += jni/src/cguittfont/xCGUITTFont.cpp
|
||||
|
||||
# Lua
|
||||
LOCAL_SRC_FILES += \
|
||||
jni/src/lua/src/lapi.c \
|
||||
jni/src/lua/src/lauxlib.c \
|
||||
jni/src/lua/src/lbaselib.c \
|
||||
jni/src/lua/src/lcode.c \
|
||||
jni/src/lua/src/ldblib.c \
|
||||
jni/src/lua/src/ldebug.c \
|
||||
jni/src/lua/src/ldo.c \
|
||||
jni/src/lua/src/ldump.c \
|
||||
jni/src/lua/src/lfunc.c \
|
||||
jni/src/lua/src/lgc.c \
|
||||
jni/src/lua/src/linit.c \
|
||||
jni/src/lua/src/liolib.c \
|
||||
jni/src/lua/src/llex.c \
|
||||
jni/src/lua/src/lmathlib.c \
|
||||
jni/src/lua/src/lmem.c \
|
||||
jni/src/lua/src/loadlib.c \
|
||||
jni/src/lua/src/lobject.c \
|
||||
jni/src/lua/src/lopcodes.c \
|
||||
jni/src/lua/src/loslib.c \
|
||||
jni/src/lua/src/lparser.c \
|
||||
jni/src/lua/src/lstate.c \
|
||||
jni/src/lua/src/lstring.c \
|
||||
jni/src/lua/src/lstrlib.c \
|
||||
jni/src/lua/src/ltable.c \
|
||||
jni/src/lua/src/ltablib.c \
|
||||
jni/src/lua/src/ltm.c \
|
||||
jni/src/lua/src/lundump.c \
|
||||
jni/src/lua/src/lvm.c \
|
||||
jni/src/lua/src/lzio.c \
|
||||
jni/src/lua/src/print.c
|
||||
jni/lib/lua/src/lapi.c \
|
||||
jni/lib/lua/src/lauxlib.c \
|
||||
jni/lib/lua/src/lbaselib.c \
|
||||
jni/lib/lua/src/lcode.c \
|
||||
jni/lib/lua/src/ldblib.c \
|
||||
jni/lib/lua/src/ldebug.c \
|
||||
jni/lib/lua/src/ldo.c \
|
||||
jni/lib/lua/src/ldump.c \
|
||||
jni/lib/lua/src/lfunc.c \
|
||||
jni/lib/lua/src/lgc.c \
|
||||
jni/lib/lua/src/linit.c \
|
||||
jni/lib/lua/src/liolib.c \
|
||||
jni/lib/lua/src/llex.c \
|
||||
jni/lib/lua/src/lmathlib.c \
|
||||
jni/lib/lua/src/lmem.c \
|
||||
jni/lib/lua/src/loadlib.c \
|
||||
jni/lib/lua/src/lobject.c \
|
||||
jni/lib/lua/src/lopcodes.c \
|
||||
jni/lib/lua/src/loslib.c \
|
||||
jni/lib/lua/src/lparser.c \
|
||||
jni/lib/lua/src/lstate.c \
|
||||
jni/lib/lua/src/lstring.c \
|
||||
jni/lib/lua/src/lstrlib.c \
|
||||
jni/lib/lua/src/ltable.c \
|
||||
jni/lib/lua/src/ltablib.c \
|
||||
jni/lib/lua/src/ltm.c \
|
||||
jni/lib/lua/src/lundump.c \
|
||||
jni/lib/lua/src/lvm.c \
|
||||
jni/lib/lua/src/lzio.c \
|
||||
jni/lib/lua/src/print.c
|
||||
|
||||
# SQLite3
|
||||
LOCAL_SRC_FILES += deps/sqlite/sqlite3.c
|
||||
@@ -356,7 +383,7 @@ LOCAL_SRC_FILES += \
|
||||
jni/src/threading/thread.cpp
|
||||
|
||||
# JSONCPP
|
||||
LOCAL_SRC_FILES += jni/src/json/jsoncpp.cpp
|
||||
LOCAL_SRC_FILES += jni/lib/jsoncpp/jsoncpp.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := iconv openal ogg vorbis gmp
|
||||
LOCAL_STATIC_LIBRARIES := Irrlicht freetype curl ssl crypto android_native_app_glue $(PROFILER_LIBS)
|
||||
@@ -373,4 +400,3 @@ ifdef GPROF
|
||||
$(call import-module,android-ndk-profiler)
|
||||
endif
|
||||
$(call import-module,android/native_app_glue)
|
||||
|
||||
|
||||
@@ -19,11 +19,6 @@ public class MtNativeActivity extends NativeActivity {
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
}
|
||||
|
||||
|
||||
public void copyAssets() {
|
||||
Intent intent = new Intent(this, MinetestAssetCopy.class);
|
||||
|
||||
65
builtin/client/chatcommands.lua
Normal file
65
builtin/client/chatcommands.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
-- Minetest: builtin/client/chatcommands.lua
|
||||
|
||||
|
||||
core.register_on_sending_chat_messages(function(message)
|
||||
if message:sub(1,2) == ".." then
|
||||
return false
|
||||
end
|
||||
|
||||
local first_char = message:sub(1,1)
|
||||
if first_char == "/" or first_char == "." then
|
||||
core.display_chat_message(core.gettext("issued command: ") .. message)
|
||||
end
|
||||
|
||||
if first_char ~= "." then
|
||||
return false
|
||||
end
|
||||
|
||||
local cmd, param = string.match(message, "^%.([^ ]+) *(.*)")
|
||||
param = param or ""
|
||||
|
||||
if not cmd then
|
||||
core.display_chat_message(core.gettext("-!- Empty command"))
|
||||
return true
|
||||
end
|
||||
|
||||
local cmd_def = core.registered_chatcommands[cmd]
|
||||
if cmd_def then
|
||||
core.set_last_run_mod(cmd_def.mod_origin)
|
||||
local _, message = cmd_def.func(param)
|
||||
if message then
|
||||
core.display_chat_message(message)
|
||||
end
|
||||
else
|
||||
core.display_chat_message(core.gettext("-!- Invalid command: ") .. cmd)
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
core.register_chatcommand("list_players", {
|
||||
description = core.gettext("List online players"),
|
||||
func = function(param)
|
||||
local players = table.concat(core.get_player_names(), ", ")
|
||||
core.display_chat_message(core.gettext("Online players: ") .. players)
|
||||
end
|
||||
})
|
||||
|
||||
core.register_chatcommand("disconnect", {
|
||||
description = core.gettext("Exit to main menu"),
|
||||
func = function(param)
|
||||
core.disconnect()
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("clear_chat_queue", {
|
||||
description = core.gettext("Clear the out chat queue"),
|
||||
func = function(param)
|
||||
core.clear_out_chat_queue()
|
||||
return true, core.gettext("The out chat queue is now empty")
|
||||
end,
|
||||
})
|
||||
|
||||
function core.run_server_chatcommand(cmd, param)
|
||||
core.send_chat_message("/" .. cmd .. " " .. param)
|
||||
end
|
||||
23
builtin/client/init.lua
Normal file
23
builtin/client/init.lua
Normal file
@@ -0,0 +1,23 @@
|
||||
-- Minetest: builtin/client/init.lua
|
||||
local scriptpath = core.get_builtin_path()..DIR_DELIM
|
||||
local clientpath = scriptpath.."client"..DIR_DELIM
|
||||
local commonpath = scriptpath.."common"..DIR_DELIM
|
||||
|
||||
dofile(clientpath .. "register.lua")
|
||||
dofile(commonpath .. "after.lua")
|
||||
dofile(commonpath .. "chatcommands.lua")
|
||||
dofile(clientpath .. "chatcommands.lua")
|
||||
dofile(commonpath .. "vector.lua")
|
||||
|
||||
core.register_on_death(function()
|
||||
core.display_chat_message("You died.")
|
||||
local formspec = "size[11,5.5]bgcolor[#320000b4;true]" ..
|
||||
"label[4.85,1.35;" .. fgettext("You died.") .. "]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]"
|
||||
core.show_formspec("bultin:death", formspec)
|
||||
end)
|
||||
|
||||
core.register_on_formspec_input(function(formname, fields)
|
||||
if formname == "bultin:death" then
|
||||
core.send_respawn()
|
||||
end
|
||||
end)
|
||||
73
builtin/client/register.lua
Normal file
73
builtin/client/register.lua
Normal file
@@ -0,0 +1,73 @@
|
||||
|
||||
core.callback_origins = {}
|
||||
|
||||
local getinfo = debug.getinfo
|
||||
debug.getinfo = nil
|
||||
|
||||
function core.run_callbacks(callbacks, mode, ...)
|
||||
assert(type(callbacks) == "table")
|
||||
local cb_len = #callbacks
|
||||
if cb_len == 0 then
|
||||
if mode == 2 or mode == 3 then
|
||||
return true
|
||||
elseif mode == 4 or mode == 5 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
local ret
|
||||
for i = 1, cb_len do
|
||||
local cb_ret = callbacks[i](...)
|
||||
|
||||
if mode == 0 and i == 1 or mode == 1 and i == cb_len then
|
||||
ret = cb_ret
|
||||
elseif mode == 2 then
|
||||
if not cb_ret or i == 1 then
|
||||
ret = cb_ret
|
||||
end
|
||||
elseif mode == 3 then
|
||||
if cb_ret then
|
||||
return cb_ret
|
||||
end
|
||||
ret = cb_ret
|
||||
elseif mode == 4 then
|
||||
if (cb_ret and not ret) or i == 1 then
|
||||
ret = cb_ret
|
||||
end
|
||||
elseif mode == 5 and cb_ret then
|
||||
return cb_ret
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
--
|
||||
-- Callback registration
|
||||
--
|
||||
|
||||
local function make_registration()
|
||||
local t = {}
|
||||
local registerfunc = function(func)
|
||||
t[#t + 1] = func
|
||||
core.callback_origins[func] = {
|
||||
mod = core.get_current_modname() or "??",
|
||||
name = getinfo(1, "n").name or "??"
|
||||
}
|
||||
--local origin = core.callback_origins[func]
|
||||
--print(origin.name .. ": " .. origin.mod .. " registering cbk " .. tostring(func))
|
||||
end
|
||||
return t, registerfunc
|
||||
end
|
||||
|
||||
core.registered_globalsteps, core.register_globalstep = make_registration()
|
||||
core.registered_on_shutdown, core.register_on_shutdown = make_registration()
|
||||
core.registered_on_connect, core.register_on_connect = make_registration()
|
||||
core.registered_on_receiving_chat_messages, core.register_on_receiving_chat_messages = make_registration()
|
||||
core.registered_on_sending_chat_messages, core.register_on_sending_chat_messages = make_registration()
|
||||
core.registered_on_death, core.register_on_death = make_registration()
|
||||
core.registered_on_hp_modification, core.register_on_hp_modification = make_registration()
|
||||
core.registered_on_damage_taken, core.register_on_damage_taken = make_registration()
|
||||
core.registered_on_formspec_input, core.register_on_formspec_input = make_registration()
|
||||
core.registered_on_dignode, core.register_on_dignode = make_registration()
|
||||
core.registered_on_punchnode, core.register_on_punchnode = make_registration()
|
||||
core.registered_on_placenode, core.register_on_placenode = make_registration()
|
||||
core.registered_on_item_use, core.register_on_item_use = make_registration()
|
||||
33
builtin/common/after.lua
Normal file
33
builtin/common/after.lua
Normal file
@@ -0,0 +1,33 @@
|
||||
local jobs = {}
|
||||
local time = 0.0
|
||||
|
||||
core.register_globalstep(function(dtime)
|
||||
time = time + dtime
|
||||
|
||||
if #jobs < 1 then
|
||||
return
|
||||
end
|
||||
|
||||
-- Iterate backwards so that we miss any new timers added by
|
||||
-- a timer callback, and so that we don't skip the next timer
|
||||
-- in the list if we remove one.
|
||||
for i = #jobs, 1, -1 do
|
||||
local job = jobs[i]
|
||||
if time >= job.expire then
|
||||
core.set_last_run_mod(job.mod_origin)
|
||||
job.func(unpack(job.arg))
|
||||
table.remove(jobs, i)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function core.after(after, func, ...)
|
||||
assert(tonumber(after) and type(func) == "function",
|
||||
"Invalid core.after invocation")
|
||||
jobs[#jobs + 1] = {
|
||||
func = func,
|
||||
expire = time + after,
|
||||
arg = {...},
|
||||
mod_origin = core.get_last_run_mod()
|
||||
}
|
||||
end
|
||||
112
builtin/common/chatcommands.lua
Normal file
112
builtin/common/chatcommands.lua
Normal file
@@ -0,0 +1,112 @@
|
||||
-- Minetest: builtin/common/chatcommands.lua
|
||||
|
||||
core.registered_chatcommands = {}
|
||||
|
||||
function core.register_chatcommand(cmd, def)
|
||||
def = def or {}
|
||||
def.params = def.params or ""
|
||||
def.description = def.description or ""
|
||||
def.privs = def.privs or {}
|
||||
def.mod_origin = core.get_current_modname() or "??"
|
||||
core.registered_chatcommands[cmd] = def
|
||||
end
|
||||
|
||||
function core.unregister_chatcommand(name)
|
||||
if core.registered_chatcommands[name] then
|
||||
core.registered_chatcommands[name] = nil
|
||||
else
|
||||
core.log("warning", "Not unregistering chatcommand " ..name..
|
||||
" because it doesn't exist.")
|
||||
end
|
||||
end
|
||||
|
||||
function core.override_chatcommand(name, redefinition)
|
||||
local chatcommand = core.registered_chatcommands[name]
|
||||
assert(chatcommand, "Attempt to override non-existent chatcommand "..name)
|
||||
for k, v in pairs(redefinition) do
|
||||
rawset(chatcommand, k, v)
|
||||
end
|
||||
core.registered_chatcommands[name] = chatcommand
|
||||
end
|
||||
|
||||
local cmd_marker = "/"
|
||||
|
||||
local function gettext(...)
|
||||
return ...
|
||||
end
|
||||
|
||||
local function gettext_replace(text, replace)
|
||||
return text:gsub("$1", replace)
|
||||
end
|
||||
|
||||
|
||||
if INIT == "client" then
|
||||
cmd_marker = "."
|
||||
gettext = core.gettext
|
||||
gettext_replace = fgettext_ne
|
||||
end
|
||||
|
||||
local function do_help_cmd(name, param)
|
||||
local function format_help_line(cmd, def)
|
||||
local msg = core.colorize("#00ffff", cmd_marker .. 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 cmds = {}
|
||||
for cmd, def in pairs(core.registered_chatcommands) do
|
||||
if INIT == "client" or core.check_player_privs(name, def.privs) then
|
||||
cmds[#cmds + 1] = cmd
|
||||
end
|
||||
end
|
||||
table.sort(cmds)
|
||||
return true, gettext("Available commands: ") .. table.concat(cmds, " ") .. "\n"
|
||||
.. gettext_replace("Use '$1help <cmd>' to get more information,"
|
||||
.. " or '$1help all' to list everything.", cmd_marker)
|
||||
elseif param == "all" then
|
||||
local cmds = {}
|
||||
for cmd, def in pairs(core.registered_chatcommands) do
|
||||
if INIT == "client" or core.check_player_privs(name, def.privs) then
|
||||
cmds[#cmds + 1] = format_help_line(cmd, def)
|
||||
end
|
||||
end
|
||||
table.sort(cmds)
|
||||
return true, gettext("Available commands:").."\n"..table.concat(cmds, "\n")
|
||||
elseif INIT == "game" and param == "privs" then
|
||||
local privs = {}
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
privs[#privs + 1] = priv .. ": " .. def.description
|
||||
end
|
||||
table.sort(privs)
|
||||
return true, "Available privileges:\n"..table.concat(privs, "\n")
|
||||
else
|
||||
local cmd = param
|
||||
local def = core.registered_chatcommands[cmd]
|
||||
if not def then
|
||||
return false, gettext("Command not available: ")..cmd
|
||||
else
|
||||
return true, format_help_line(cmd, def)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if INIT == "client" then
|
||||
core.register_chatcommand("help", {
|
||||
params = gettext("[all/<cmd>]"),
|
||||
description = gettext("Get help for commands"),
|
||||
func = function(param)
|
||||
return do_help_cmd(nil, param)
|
||||
end,
|
||||
})
|
||||
else
|
||||
core.register_chatcommand("help", {
|
||||
params = "[all/privs/<cmd>]",
|
||||
description = "Get help for commands or list privileges",
|
||||
func = do_help_cmd,
|
||||
})
|
||||
end
|
||||
@@ -289,6 +289,9 @@ function sort_mod_list(self)
|
||||
table.sort(self.m_processed_list, function(a, b)
|
||||
-- Show game mods at bottom
|
||||
if a.typ ~= b.typ then
|
||||
if b.typ == "game" then
|
||||
return a.typ ~= "game_mod"
|
||||
end
|
||||
return b.typ == "game_mod"
|
||||
end
|
||||
-- If in same or no modpack, sort by name
|
||||
|
||||
@@ -197,16 +197,17 @@ assert(table.indexof({"foo", "bar"}, "foo") == 1)
|
||||
assert(table.indexof({"foo", "bar"}, "baz") == -1)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function file_exists(filename)
|
||||
local f = io.open(filename, "r")
|
||||
if f == nil then
|
||||
return false
|
||||
else
|
||||
f:close()
|
||||
return true
|
||||
if INIT ~= "client" then
|
||||
function file_exists(filename)
|
||||
local f = io.open(filename, "r")
|
||||
if f == nil then
|
||||
return false
|
||||
else
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function string:trim()
|
||||
return (self:gsub("^%s*(.-)%s*$", "%1"))
|
||||
@@ -307,7 +308,7 @@ function core.formspec_escape(text)
|
||||
end
|
||||
|
||||
|
||||
function core.splittext(text,charlimit)
|
||||
function core.wrap_text(text, charlimit)
|
||||
local retval = {}
|
||||
|
||||
local current_idx = 1
|
||||
@@ -382,7 +383,6 @@ if INIT == "game" then
|
||||
itemstack, pointed_thing)
|
||||
return
|
||||
end
|
||||
local pitch = placer:get_look_pitch()
|
||||
local fdir = core.dir_to_facedir(placer:get_look_dir())
|
||||
local wield_name = itemstack:get_name()
|
||||
|
||||
@@ -463,7 +463,7 @@ if INIT == "game" then
|
||||
|
||||
core.rotate_node = function(itemstack, placer, pointed_thing)
|
||||
core.rotate_and_place(itemstack, placer, pointed_thing,
|
||||
core.setting_getbool("creative_mode"),
|
||||
core.settings:get_bool("creative_mode"),
|
||||
{invert_wall = placer:get_player_control().sneak})
|
||||
return itemstack
|
||||
end
|
||||
@@ -607,7 +607,9 @@ if INIT == "mainmenu" then
|
||||
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
if INIT == "client" or INIT == "mainmenu" then
|
||||
function fgettext_ne(text, ...)
|
||||
text = core.gettext(text)
|
||||
local arg = {n=select('#', ...), ...}
|
||||
@@ -638,3 +640,86 @@ if INIT == "mainmenu" then
|
||||
end
|
||||
end
|
||||
|
||||
local ESCAPE_CHAR = string.char(0x1b)
|
||||
|
||||
-- Client-side mods don't have access to settings
|
||||
if core.settings and core.settings:get_bool("disable_escape_sequences") then
|
||||
|
||||
function core.get_color_escape_sequence(color)
|
||||
return ""
|
||||
end
|
||||
|
||||
function core.get_background_escape_sequence(color)
|
||||
return ""
|
||||
end
|
||||
|
||||
function core.colorize(color, message)
|
||||
return message
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
function core.get_color_escape_sequence(color)
|
||||
return ESCAPE_CHAR .. "(c@" .. color .. ")"
|
||||
end
|
||||
|
||||
function core.get_background_escape_sequence(color)
|
||||
return ESCAPE_CHAR .. "(b@" .. color .. ")"
|
||||
end
|
||||
|
||||
function core.colorize(color, message)
|
||||
local lines = tostring(message):split("\n", true)
|
||||
local color_code = core.get_color_escape_sequence(color)
|
||||
|
||||
for i, line in ipairs(lines) do
|
||||
lines[i] = color_code .. line
|
||||
end
|
||||
|
||||
return table.concat(lines, "\n") .. core.get_color_escape_sequence("#ffffff")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function core.strip_foreground_colors(str)
|
||||
return (str:gsub(ESCAPE_CHAR .. "%(c@[^)]+%)", ""))
|
||||
end
|
||||
|
||||
function core.strip_background_colors(str)
|
||||
return (str:gsub(ESCAPE_CHAR .. "%(b@[^)]+%)", ""))
|
||||
end
|
||||
|
||||
function core.strip_colors(str)
|
||||
return (str:gsub(ESCAPE_CHAR .. "%([bc]@[^)]+%)", ""))
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Returns the exact coordinate of a pointed surface
|
||||
--------------------------------------------------------------------------------
|
||||
function core.pointed_thing_to_face_pos(placer, pointed_thing)
|
||||
local eye_offset_first = placer:get_eye_offset()
|
||||
local node_pos = pointed_thing.under
|
||||
local camera_pos = placer:get_pos()
|
||||
local pos_off = vector.multiply(
|
||||
vector.subtract(pointed_thing.above, node_pos), 0.5)
|
||||
local look_dir = placer:get_look_dir()
|
||||
local offset, nc
|
||||
local oc = {}
|
||||
|
||||
for c, v in pairs(pos_off) do
|
||||
if nc or v == 0 then
|
||||
oc[#oc + 1] = c
|
||||
else
|
||||
offset = v
|
||||
nc = c
|
||||
end
|
||||
end
|
||||
|
||||
local fine_pos = {[nc] = node_pos[nc] + offset}
|
||||
camera_pos.y = camera_pos.y + 1.625 + eye_offset_first.y / 10
|
||||
local f = (node_pos[nc] + offset - camera_pos[nc]) / look_dir[nc]
|
||||
|
||||
for i = 1, #oc do
|
||||
fine_pos[oc[i]] = camera_pos[oc[i]] + look_dir[oc[i]] * f
|
||||
end
|
||||
return fine_pos
|
||||
end
|
||||
|
||||
@@ -186,6 +186,10 @@ local safe_env = {
|
||||
}
|
||||
|
||||
function core.deserialize(str, safe)
|
||||
if type(str) ~= "string" then
|
||||
return nil, "Cannot deserialize type '"..type(str)
|
||||
.."'. Argument must be a string."
|
||||
end
|
||||
if str:byte(1) == 0x1B then
|
||||
return nil, "Bytecode prohibited"
|
||||
end
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
-- This ignores mod namespaces (variables with the same name as the current mod).
|
||||
local WARN_INIT = false
|
||||
|
||||
local getinfo = debug.getinfo
|
||||
|
||||
function core.global_exists(name)
|
||||
if type(name) ~= "string" then
|
||||
error("core.global_exists: " .. tostring(name) .. " is not a string")
|
||||
end
|
||||
return rawget(_G, name) ~= nil
|
||||
end
|
||||
|
||||
@@ -15,7 +19,7 @@ local declared = {}
|
||||
local warned = {}
|
||||
|
||||
function meta:__newindex(name, value)
|
||||
local info = debug.getinfo(2, "Sl")
|
||||
local info = getinfo(2, "Sl")
|
||||
local desc = ("%s:%d"):format(info.short_src, info.currentline)
|
||||
if not declared[name] then
|
||||
local warn_key = ("%s\0%d\0%s"):format(info.source,
|
||||
@@ -39,7 +43,7 @@ end
|
||||
|
||||
|
||||
function meta:__index(name)
|
||||
local info = debug.getinfo(2, "Sl")
|
||||
local info = getinfo(2, "Sl")
|
||||
local warn_key = ("%s\0%d\0%s"):format(info.source, info.currentline, name)
|
||||
if not declared[name] and not warned[warn_key] and info.what ~= "C" then
|
||||
core.log("warning", ("Undeclared global variable %q accessed at %s:%s")
|
||||
|
||||
@@ -31,6 +31,14 @@ function vector.normalize(v)
|
||||
end
|
||||
end
|
||||
|
||||
function vector.floor(v)
|
||||
return {
|
||||
x = math.floor(v.x),
|
||||
y = math.floor(v.y),
|
||||
z = math.floor(v.z)
|
||||
}
|
||||
end
|
||||
|
||||
function vector.round(v)
|
||||
return {
|
||||
x = math.floor(v.x + 0.5),
|
||||
@@ -131,3 +139,7 @@ function vector.divide(a, b)
|
||||
end
|
||||
end
|
||||
|
||||
function vector.sort(a, b)
|
||||
return {x = math.min(a.x, b.x), y = math.min(a.y, b.y), z = math.min(a.z, b.z)},
|
||||
{x = math.max(a.x, b.x), y = math.max(a.y, b.y), z = math.max(a.z, b.z)}
|
||||
end
|
||||
|
||||
@@ -167,7 +167,7 @@ local function switch_to_tab(self, index)
|
||||
self.current_tab = self.tablist[index].name
|
||||
|
||||
if (self.autosave_tab) then
|
||||
core.setting_set(self.name .. "_LAST",self.current_tab)
|
||||
core.settings:set(self.name .. "_LAST",self.current_tab)
|
||||
end
|
||||
|
||||
-- call for tab to enter
|
||||
|
||||
@@ -106,7 +106,7 @@ core.builtin_auth_handler = {
|
||||
end
|
||||
end
|
||||
-- For the admin, give everything
|
||||
elseif name == core.setting_get("name") then
|
||||
elseif name == core.settings:get("name") then
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
privileges[priv] = true
|
||||
end
|
||||
@@ -125,7 +125,7 @@ core.builtin_auth_handler = {
|
||||
core.log('info', "Built-in authentication handler adding player '"..name.."'")
|
||||
core.auth_table[name] = {
|
||||
password = password,
|
||||
privileges = core.string_to_privs(core.setting_get("default_privs")),
|
||||
privileges = core.string_to_privs(core.settings:get("default_privs")),
|
||||
last_login = os.time(),
|
||||
}
|
||||
save_auth_file()
|
||||
@@ -148,7 +148,7 @@ core.builtin_auth_handler = {
|
||||
if not core.auth_table[name] then
|
||||
core.builtin_auth_handler.create_auth(name,
|
||||
core.get_password_hash(name,
|
||||
core.setting_get("default_password")))
|
||||
core.settings:get("default_password")))
|
||||
end
|
||||
core.auth_table[name].privileges = privileges
|
||||
core.notify_authentication_modified(name)
|
||||
@@ -199,3 +199,19 @@ core.register_on_joinplayer(function(player)
|
||||
record_login(player:get_player_name())
|
||||
end)
|
||||
|
||||
core.register_on_prejoinplayer(function(name, ip)
|
||||
local auth = core.auth_table
|
||||
if auth[name] ~= nil then
|
||||
return
|
||||
end
|
||||
|
||||
local name_lower = name:lower()
|
||||
for k in pairs(auth) do
|
||||
if k:lower() == name_lower then
|
||||
return string.format("\nCannot create new player called '%s'. "..
|
||||
"Another account called '%s' is already registered. "..
|
||||
"Please check the spelling if it's your account "..
|
||||
"or use a different nickname.", name, k)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -1,40 +1,28 @@
|
||||
-- Minetest: builtin/chatcommands.lua
|
||||
-- Minetest: builtin/game/chatcommands.lua
|
||||
|
||||
--
|
||||
-- Chat command handler
|
||||
--
|
||||
|
||||
core.chatcommands = {}
|
||||
function core.register_chatcommand(cmd, def)
|
||||
def = def or {}
|
||||
def.params = def.params or ""
|
||||
def.description = def.description or ""
|
||||
def.privs = def.privs or {}
|
||||
def.mod_origin = core.get_current_modname() or "??"
|
||||
core.chatcommands[cmd] = def
|
||||
end
|
||||
|
||||
if core.setting_getbool("mod_profiling") then
|
||||
local tracefct = profiling_print_log
|
||||
profiling_print_log = nil
|
||||
core.register_chatcommand("save_mod_profile",
|
||||
{
|
||||
params = "",
|
||||
description = "save mod profiling data to logfile " ..
|
||||
"(depends on default loglevel)",
|
||||
func = tracefct,
|
||||
privs = { server=true }
|
||||
})
|
||||
end
|
||||
core.chatcommands = core.registered_chatcommands -- BACKWARDS COMPATIBILITY
|
||||
|
||||
core.register_on_chat_message(function(name, message)
|
||||
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
|
||||
if not param then
|
||||
param = ""
|
||||
if message:sub(1,1) ~= "/" then
|
||||
return
|
||||
end
|
||||
local cmd_def = core.chatcommands[cmd]
|
||||
|
||||
local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
|
||||
if not cmd then
|
||||
core.chat_send_player(name, "-!- Empty command")
|
||||
return true
|
||||
end
|
||||
|
||||
param = param or ""
|
||||
|
||||
local cmd_def = core.registered_chatcommands[cmd]
|
||||
if not cmd_def then
|
||||
return false
|
||||
core.chat_send_player(name, "-!- Invalid command: " .. cmd)
|
||||
return true
|
||||
end
|
||||
local has_privs, missing_privs = core.check_player_privs(name, cmd_def.privs)
|
||||
if has_privs then
|
||||
@@ -51,6 +39,12 @@ core.register_on_chat_message(function(name, message)
|
||||
return true -- Handled chat message
|
||||
end)
|
||||
|
||||
if core.settings:get_bool("profiler.load") then
|
||||
-- Run after register_chatcommand and its register_on_chat_message
|
||||
-- Before any chattcommands that should be profiled
|
||||
profiler.init_chatcommand()
|
||||
end
|
||||
|
||||
-- Parses a "range" string in the format of "here (number)" or
|
||||
-- "(x1, y1, z1) (x2, y2, z2)", returning two position vectors
|
||||
local function parse_range_str(player_name, str)
|
||||
@@ -77,7 +71,8 @@ end
|
||||
--
|
||||
core.register_chatcommand("me", {
|
||||
params = "<action>",
|
||||
description = "chat action (eg. /me orders a pizza)",
|
||||
description = "Display chat action (e.g., '/me orders a pizza' displays"
|
||||
.. " '<player name> orders a pizza')",
|
||||
privs = {shout=true},
|
||||
func = function(name, param)
|
||||
core.chat_send_all("* " .. name .. " " .. param)
|
||||
@@ -87,7 +82,7 @@ core.register_chatcommand("me", {
|
||||
core.register_chatcommand("admin", {
|
||||
description = "Show the name of the server owner",
|
||||
func = function(name)
|
||||
local admin = minetest.setting_get("name")
|
||||
local admin = minetest.settings:get("name")
|
||||
if admin then
|
||||
return true, "The administrator of this server is "..admin.."."
|
||||
else
|
||||
@@ -96,118 +91,82 @@ core.register_chatcommand("admin", {
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("help", {
|
||||
privs = {},
|
||||
params = "[all/privs/<cmd>]",
|
||||
description = "Get help for commands or list privileges",
|
||||
func = function(name, param)
|
||||
local function format_help_line(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 = ""
|
||||
local cmds = {}
|
||||
for cmd, def in pairs(core.chatcommands) do
|
||||
if core.check_player_privs(name, def.privs) then
|
||||
cmds[#cmds + 1] = cmd
|
||||
end
|
||||
end
|
||||
table.sort(cmds)
|
||||
return true, "Available commands: " .. table.concat(cmds, " ") .. "\n"
|
||||
.. "Use '/help <cmd>' to get more information,"
|
||||
.. " or '/help all' to list everything."
|
||||
elseif param == "all" then
|
||||
local cmds = {}
|
||||
for cmd, def in pairs(core.chatcommands) do
|
||||
if core.check_player_privs(name, def.privs) then
|
||||
cmds[#cmds + 1] = format_help_line(cmd, def)
|
||||
end
|
||||
end
|
||||
table.sort(cmds)
|
||||
return true, "Available commands:\n"..table.concat(cmds, "\n")
|
||||
elseif param == "privs" then
|
||||
local privs = {}
|
||||
for priv, def in pairs(core.registered_privileges) do
|
||||
privs[#privs + 1] = priv .. ": " .. def.description
|
||||
end
|
||||
table.sort(privs)
|
||||
return true, "Available privileges:\n"..table.concat(privs, "\n")
|
||||
else
|
||||
local cmd = param
|
||||
local def = core.chatcommands[cmd]
|
||||
if not def then
|
||||
return false, "Command not available: "..cmd
|
||||
else
|
||||
return true, format_help_line(cmd, def)
|
||||
end
|
||||
end
|
||||
core.register_chatcommand("privs", {
|
||||
params = "<name>",
|
||||
description = "Print privileges of player",
|
||||
func = function(caller, param)
|
||||
param = param:trim()
|
||||
local name = (param ~= "" and param or caller)
|
||||
return true, "Privileges of " .. name .. ": "
|
||||
.. core.privs_to_string(
|
||||
core.get_player_privs(name), ' ')
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("privs", {
|
||||
params = "<name>",
|
||||
description = "print out privileges of player",
|
||||
func = function(name, param)
|
||||
param = (param ~= "" and param or name)
|
||||
return true, "Privileges of " .. param .. ": "
|
||||
.. core.privs_to_string(
|
||||
core.get_player_privs(param), ' ')
|
||||
end,
|
||||
})
|
||||
local function handle_grant_command(caller, grantname, grantprivstr)
|
||||
local caller_privs = minetest.get_player_privs(caller)
|
||||
if not (caller_privs.privs or caller_privs.basic_privs) then
|
||||
return false, "Your privileges are insufficient."
|
||||
end
|
||||
|
||||
if not core.get_auth_handler().get_auth(grantname) then
|
||||
return false, "Player " .. grantname .. " does not exist."
|
||||
end
|
||||
local grantprivs = core.string_to_privs(grantprivstr)
|
||||
if grantprivstr == "all" then
|
||||
grantprivs = core.registered_privileges
|
||||
end
|
||||
local privs = core.get_player_privs(grantname)
|
||||
local privs_unknown = ""
|
||||
local basic_privs =
|
||||
core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
|
||||
for priv, _ in pairs(grantprivs) do
|
||||
if not basic_privs[priv] and not caller_privs.privs then
|
||||
return false, "Your privileges are insufficient."
|
||||
end
|
||||
if not core.registered_privileges[priv] then
|
||||
privs_unknown = privs_unknown .. "Unknown privilege: " .. priv .. "\n"
|
||||
end
|
||||
privs[priv] = true
|
||||
end
|
||||
if privs_unknown ~= "" then
|
||||
return false, privs_unknown
|
||||
end
|
||||
core.set_player_privs(grantname, privs)
|
||||
core.log("action", caller..' granted ('..core.privs_to_string(grantprivs, ', ')..') privileges to '..grantname)
|
||||
if grantname ~= caller then
|
||||
core.chat_send_player(grantname, caller
|
||||
.. " granted you privileges: "
|
||||
.. core.privs_to_string(grantprivs, ' '))
|
||||
end
|
||||
return true, "Privileges of " .. grantname .. ": "
|
||||
.. core.privs_to_string(
|
||||
core.get_player_privs(grantname), ' ')
|
||||
end
|
||||
|
||||
core.register_chatcommand("grant", {
|
||||
params = "<name> <privilege>|all",
|
||||
description = "Give privilege to player",
|
||||
func = function(name, param)
|
||||
if not core.check_player_privs(name, {privs=true}) and
|
||||
not core.check_player_privs(name, {basic_privs=true}) then
|
||||
return false, "Your privileges are insufficient."
|
||||
end
|
||||
local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)")
|
||||
if not grantname or not grantprivstr then
|
||||
return false, "Invalid parameters (see /help grant)"
|
||||
elseif not core.auth_table[grantname] then
|
||||
return false, "Player " .. grantname .. " does not exist."
|
||||
end
|
||||
local grantprivs = core.string_to_privs(grantprivstr)
|
||||
if grantprivstr == "all" then
|
||||
grantprivs = core.registered_privileges
|
||||
end
|
||||
local privs = core.get_player_privs(grantname)
|
||||
local privs_unknown = ""
|
||||
local basic_privs =
|
||||
core.string_to_privs(core.setting_get("basic_privs") or "interact,shout")
|
||||
for priv, _ in pairs(grantprivs) do
|
||||
if not basic_privs[priv] and
|
||||
not core.check_player_privs(name, {privs=true}) then
|
||||
return false, "Your privileges are insufficient."
|
||||
end
|
||||
if not core.registered_privileges[priv] then
|
||||
privs_unknown = privs_unknown .. "Unknown privilege: " .. priv .. "\n"
|
||||
end
|
||||
privs[priv] = true
|
||||
end
|
||||
if privs_unknown ~= "" then
|
||||
return false, privs_unknown
|
||||
end
|
||||
core.set_player_privs(grantname, privs)
|
||||
core.log("action", name..' granted ('..core.privs_to_string(grantprivs, ', ')..') privileges to '..grantname)
|
||||
if grantname ~= name then
|
||||
core.chat_send_player(grantname, name
|
||||
.. " granted you privileges: "
|
||||
.. core.privs_to_string(grantprivs, ' '))
|
||||
end
|
||||
return true, "Privileges of " .. grantname .. ": "
|
||||
.. core.privs_to_string(
|
||||
core.get_player_privs(grantname), ' ')
|
||||
return handle_grant_command(name, grantname, grantprivstr)
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("grantme", {
|
||||
params = "<privilege>|all",
|
||||
description = "Grant privileges to yourself",
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
return false, "Invalid parameters (see /help grantme)"
|
||||
end
|
||||
return handle_grant_command(name, name, param)
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("revoke", {
|
||||
params = "<name> <privilege>|all",
|
||||
description = "Remove privilege from player",
|
||||
@@ -220,13 +179,13 @@ core.register_chatcommand("revoke", {
|
||||
local revoke_name, revoke_priv_str = string.match(param, "([^ ]+) (.+)")
|
||||
if not revoke_name or not revoke_priv_str then
|
||||
return false, "Invalid parameters (see /help revoke)"
|
||||
elseif not core.auth_table[revoke_name] then
|
||||
elseif not core.get_auth_handler().get_auth(revoke_name) then
|
||||
return false, "Player " .. revoke_name .. " does not exist."
|
||||
end
|
||||
local revoke_privs = core.string_to_privs(revoke_priv_str)
|
||||
local privs = core.get_player_privs(revoke_name)
|
||||
local basic_privs =
|
||||
core.string_to_privs(core.setting_get("basic_privs") or "interact,shout")
|
||||
core.string_to_privs(core.settings:get("basic_privs") or "interact,shout")
|
||||
for priv, _ in pairs(revoke_privs) do
|
||||
if not basic_privs[priv] and
|
||||
not core.check_player_privs(name, {privs=true}) then
|
||||
@@ -257,7 +216,7 @@ core.register_chatcommand("revoke", {
|
||||
|
||||
core.register_chatcommand("setpassword", {
|
||||
params = "<name> <password>",
|
||||
description = "set given password",
|
||||
description = "Set player's password",
|
||||
privs = {password=true},
|
||||
func = function(name, param)
|
||||
local toname, raw_password = string.match(param, "^([^ ]+) +(.+)$")
|
||||
@@ -295,7 +254,7 @@ core.register_chatcommand("setpassword", {
|
||||
|
||||
core.register_chatcommand("clearpassword", {
|
||||
params = "<name>",
|
||||
description = "set empty password",
|
||||
description = "Set empty password",
|
||||
privs = {password=true},
|
||||
func = function(name, param)
|
||||
local toname = param
|
||||
@@ -312,7 +271,7 @@ core.register_chatcommand("clearpassword", {
|
||||
|
||||
core.register_chatcommand("auth_reload", {
|
||||
params = "",
|
||||
description = "reload authentication data",
|
||||
description = "Reload authentication data",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
local done = core.auth_reload()
|
||||
@@ -320,9 +279,34 @@ core.register_chatcommand("auth_reload", {
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("remove_player", {
|
||||
params = "<name>",
|
||||
description = "Remove player data",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
local toname = param
|
||||
if toname == "" then
|
||||
return false, "Name field required"
|
||||
end
|
||||
|
||||
local rc = core.remove_player(toname)
|
||||
|
||||
if rc == 0 then
|
||||
core.log("action", name .. " removed player data of " .. toname .. ".")
|
||||
return true, "Player \"" .. toname .. "\" removed."
|
||||
elseif rc == 1 then
|
||||
return true, "No such player \"" .. toname .. "\" to remove."
|
||||
elseif rc == 2 then
|
||||
return true, "Player \"" .. toname .. "\" is connected, cannot remove."
|
||||
end
|
||||
|
||||
return false, "Unhandled remove_player return code " .. rc .. ""
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("teleport", {
|
||||
params = "<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>",
|
||||
description = "teleport to given position",
|
||||
description = "Teleport to player or position",
|
||||
privs = {teleport=true},
|
||||
func = function(name, param)
|
||||
-- Returns (pos, true) if found, otherwise (pos, false)
|
||||
@@ -353,7 +337,7 @@ core.register_chatcommand("teleport", {
|
||||
p.y = tonumber(p.y)
|
||||
p.z = tonumber(p.z)
|
||||
if p.x and p.y and p.z then
|
||||
local lm = tonumber(minetest.setting_get("map_generation_limit") or 31000)
|
||||
local lm = 31000
|
||||
if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm or p.z < -lm or p.z > lm then
|
||||
return false, "Cannot teleport out of map bounds!"
|
||||
end
|
||||
@@ -430,25 +414,25 @@ core.register_chatcommand("teleport", {
|
||||
|
||||
core.register_chatcommand("set", {
|
||||
params = "[-n] <name> <value> | <name>",
|
||||
description = "set or read server configuration setting",
|
||||
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
|
||||
core.setting_set(setname, setvalue)
|
||||
core.settings:set(setname, setvalue)
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
local setname, setvalue = string.match(param, "([^ ]+) (.+)")
|
||||
if setname and setvalue then
|
||||
if not core.setting_get(setname) then
|
||||
if not core.settings:get(setname) then
|
||||
return false, "Failed. Use '/set -n <name> <value>' to create a new setting."
|
||||
end
|
||||
core.setting_set(setname, setvalue)
|
||||
core.settings:set(setname, setvalue)
|
||||
return true, setname .. " = " .. setvalue
|
||||
end
|
||||
local setname = string.match(param, "([^ ]+)")
|
||||
if setname then
|
||||
local setvalue = core.setting_get(setname)
|
||||
local setvalue = core.settings:get(setname)
|
||||
if not setvalue then
|
||||
setvalue = "<not set>"
|
||||
end
|
||||
@@ -485,7 +469,7 @@ end
|
||||
|
||||
core.register_chatcommand("emergeblocks", {
|
||||
params = "(here [radius]) | (<pos1> <pos2>)",
|
||||
description = "starts loading (or generating, if inexistent) map blocks "
|
||||
description = "Load (or, if nonexistent, generate) map blocks "
|
||||
.. "contained in area pos1 to pos2",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
@@ -511,7 +495,7 @@ core.register_chatcommand("emergeblocks", {
|
||||
|
||||
core.register_chatcommand("deleteblocks", {
|
||||
params = "(here [radius]) | (<pos1> <pos2>)",
|
||||
description = "delete map blocks contained in area pos1 to pos2",
|
||||
description = "Delete map blocks contained in area pos1 to pos2",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
local p1, p2 = parse_range_str(name, param)
|
||||
@@ -528,6 +512,25 @@ core.register_chatcommand("deleteblocks", {
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("fixlight", {
|
||||
params = "(here [radius]) | (<pos1> <pos2>)",
|
||||
description = "Resets lighting in the area between pos1 and pos2",
|
||||
privs = {server = true},
|
||||
func = function(name, param)
|
||||
local p1, p2 = parse_range_str(name, param)
|
||||
if p1 == false then
|
||||
return false, p2
|
||||
end
|
||||
|
||||
if core.fix_light(p1, p2) then
|
||||
return true, "Successfully reset light in the area ranging from " ..
|
||||
core.pos_to_string(p1, 1) .. " to " .. core.pos_to_string(p2, 1)
|
||||
else
|
||||
return false, "Failed to load one or more blocks in area"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("mods", {
|
||||
params = "",
|
||||
description = "List mods installed on the server",
|
||||
@@ -575,7 +578,7 @@ end
|
||||
|
||||
core.register_chatcommand("give", {
|
||||
params = "<name> <ItemString>",
|
||||
description = "give item to player",
|
||||
description = "Give item to player",
|
||||
privs = {give=true},
|
||||
func = function(name, param)
|
||||
local toname, itemstring = string.match(param, "^([^ ]+) +(.+)$")
|
||||
@@ -588,7 +591,7 @@ core.register_chatcommand("give", {
|
||||
|
||||
core.register_chatcommand("giveme", {
|
||||
params = "<ItemString>",
|
||||
description = "give item to yourself",
|
||||
description = "Give item to yourself",
|
||||
privs = {give=true},
|
||||
func = function(name, param)
|
||||
local itemstring = string.match(param, "(.+)$")
|
||||
@@ -659,12 +662,12 @@ end)
|
||||
|
||||
core.register_chatcommand("rollback_check", {
|
||||
params = "[<range>] [<seconds>] [limit]",
|
||||
description = "Check who has last touched a node or near it,"
|
||||
.. " max. <seconds> ago (default range=0,"
|
||||
.. " seconds=86400=24h, limit=5)",
|
||||
description = "Check who last touched a node or a node near it"
|
||||
.. " within the time specified by <seconds>. Default: range = 0,"
|
||||
.. " seconds = 86400 = 24h, limit = 5",
|
||||
privs = {rollback=true},
|
||||
func = function(name, param)
|
||||
if not core.setting_getbool("enable_rollback_recording") then
|
||||
if not core.settings:get_bool("enable_rollback_recording") then
|
||||
return false, "Rollback functions are disabled."
|
||||
end
|
||||
local range, seconds, limit =
|
||||
@@ -712,10 +715,10 @@ core.register_chatcommand("rollback_check", {
|
||||
|
||||
core.register_chatcommand("rollback", {
|
||||
params = "<player name> [<seconds>] | :<actor> [<seconds>]",
|
||||
description = "revert actions of a player; default for <seconds> is 60",
|
||||
description = "Revert actions of a player. Default for <seconds> is 60",
|
||||
privs = {rollback=true},
|
||||
func = function(name, param)
|
||||
if not core.setting_getbool("enable_rollback_recording") then
|
||||
if not core.settings:get_bool("enable_rollback_recording") then
|
||||
return false, "Rollback functions are disabled."
|
||||
end
|
||||
local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
|
||||
@@ -757,7 +760,7 @@ core.register_chatcommand("status", {
|
||||
|
||||
core.register_chatcommand("time", {
|
||||
params = "<0..23>:<0..59> | <0..24000>",
|
||||
description = "set time of day",
|
||||
description = "Set time of day",
|
||||
privs = {},
|
||||
func = function(name, param)
|
||||
if param == "" then
|
||||
@@ -803,12 +806,21 @@ core.register_chatcommand("days", {
|
||||
})
|
||||
|
||||
core.register_chatcommand("shutdown", {
|
||||
description = "shutdown server",
|
||||
description = "Shutdown server",
|
||||
params = "[delay_in_seconds (non-negative number, or -1 to cancel)] [reconnect] [message]",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
core.log("action", name .. " shuts down server")
|
||||
core.request_shutdown()
|
||||
core.chat_send_all("*** Server shutting down (operator request).")
|
||||
local delay, reconnect, message = param:match("([^ ][-]?[0-9]+)([^ ]+)(.*)")
|
||||
message = message or ""
|
||||
|
||||
if delay ~= "" then
|
||||
delay = tonumber(param) or 0
|
||||
else
|
||||
delay = 0
|
||||
core.log("action", name .. " shuts down server")
|
||||
core.chat_send_all("*** Server shutting down (operator request).")
|
||||
end
|
||||
core.request_shutdown(message:trim(), core.is_yes(reconnect), delay)
|
||||
end,
|
||||
})
|
||||
|
||||
@@ -834,7 +846,7 @@ core.register_chatcommand("ban", {
|
||||
|
||||
core.register_chatcommand("unban", {
|
||||
params = "<name/ip>",
|
||||
description = "remove IP ban",
|
||||
description = "Remove IP ban",
|
||||
privs = {ban=true},
|
||||
func = function(name, param)
|
||||
if not core.unban_player_or_ip(param) then
|
||||
@@ -847,7 +859,7 @@ core.register_chatcommand("unban", {
|
||||
|
||||
core.register_chatcommand("kick", {
|
||||
params = "<name> [reason]",
|
||||
description = "kick a player",
|
||||
description = "Kick a player",
|
||||
privs = {kick=true},
|
||||
func = function(name, param)
|
||||
local tokick, reason = param:match("([^ ]+) (.+)")
|
||||
@@ -866,7 +878,7 @@ core.register_chatcommand("kick", {
|
||||
|
||||
core.register_chatcommand("clearobjects", {
|
||||
params = "[full|quick]",
|
||||
description = "clear all objects in world",
|
||||
description = "Clear all objects in world",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
local options = {}
|
||||
@@ -926,3 +938,31 @@ core.register_chatcommand("last-login", {
|
||||
return false, "Last login time is unknown"
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("clearinv", {
|
||||
params = "[name]",
|
||||
description = "Clear the inventory of yourself or another player",
|
||||
func = function(name, param)
|
||||
local player
|
||||
if param and param ~= "" and param ~= name then
|
||||
if not core.check_player_privs(name, {server=true}) then
|
||||
return false, "You don't have permission"
|
||||
.. " to run this command (missing privilege: server)"
|
||||
end
|
||||
player = core.get_player_by_name(param)
|
||||
core.chat_send_player(param, name.." cleared your inventory.")
|
||||
else
|
||||
player = core.get_player_by_name(name)
|
||||
end
|
||||
|
||||
if player then
|
||||
player:get_inventory():set_list("main", {})
|
||||
player:get_inventory():set_list("craft", {})
|
||||
player:get_inventory():set_list("craftpreview", {})
|
||||
core.log("action", name.." clears "..player:get_player_name().."'s inventory")
|
||||
return true, "Cleared "..player:get_player_name().."'s inventory."
|
||||
else
|
||||
return false, "Player must be online to clear inventory!"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
@@ -4,14 +4,24 @@
|
||||
-- Constants values for use with the Lua API
|
||||
--
|
||||
|
||||
-- mapnode.h
|
||||
-- Built-in Content IDs (for use with VoxelManip API)
|
||||
core.CONTENT_UNKNOWN = 125
|
||||
core.CONTENT_AIR = 126
|
||||
core.CONTENT_IGNORE = 127
|
||||
|
||||
-- emerge.h
|
||||
-- Block emerge status constants (for use with core.emerge_area)
|
||||
core.EMERGE_CANCELLED = 0
|
||||
core.EMERGE_ERRORED = 1
|
||||
core.EMERGE_FROM_MEMORY = 2
|
||||
core.EMERGE_FROM_DISK = 3
|
||||
core.EMERGE_GENERATED = 4
|
||||
|
||||
-- constants.h
|
||||
-- Size of mapblocks in nodes
|
||||
core.MAP_BLOCKSIZE = 16
|
||||
|
||||
-- light.h
|
||||
-- Maximum value for node 'light_source' parameter
|
||||
core.LIGHT_MAX = 14
|
||||
|
||||
@@ -49,3 +49,24 @@ setmetatable(core.env, {
|
||||
function core.rollback_get_last_node_actor(pos, range, seconds)
|
||||
return core.rollback_get_node_actions(pos, range, seconds, 1)[1]
|
||||
end
|
||||
|
||||
--
|
||||
-- core.setting_*
|
||||
--
|
||||
|
||||
local settings = core.settings
|
||||
|
||||
local function setting_proxy(name)
|
||||
return function(...)
|
||||
core.log("deprecated", "WARNING: minetest.setting_* "..
|
||||
"functions are deprecated. "..
|
||||
"Use methods on the minetest.settings object.")
|
||||
return settings[name](settings, ...)
|
||||
end
|
||||
end
|
||||
|
||||
core.setting_set = setting_proxy("set")
|
||||
core.setting_get = setting_proxy("get")
|
||||
core.setting_setbool = setting_proxy("set_bool")
|
||||
core.setting_getbool = setting_proxy("get_bool")
|
||||
core.setting_save = setting_proxy("write")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
core.detached_inventories = {}
|
||||
|
||||
function core.create_detached_inventory(name, callbacks)
|
||||
function core.create_detached_inventory(name, callbacks, player_name)
|
||||
local stuff = {}
|
||||
stuff.name = name
|
||||
if callbacks then
|
||||
@@ -15,6 +15,6 @@ function core.create_detached_inventory(name, callbacks)
|
||||
end
|
||||
stuff.mod_origin = core.get_current_modname() or "??"
|
||||
core.detached_inventories[name] = stuff
|
||||
return core.create_detached_inventory_raw(name)
|
||||
return core.create_detached_inventory_raw(name, player_name)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
-- Minetest: builtin/item.lua
|
||||
|
||||
local builtin_shared = ...
|
||||
|
||||
--
|
||||
-- Falling stuff
|
||||
--
|
||||
@@ -16,9 +18,11 @@ core.register_entity(":__builtin:falling_node", {
|
||||
},
|
||||
|
||||
node = {},
|
||||
meta = {},
|
||||
|
||||
set_node = function(self, node)
|
||||
set_node = function(self, node, meta)
|
||||
self.node = node
|
||||
self.meta = meta or {}
|
||||
self.object:set_properties({
|
||||
is_visible = true,
|
||||
textures = {node.name},
|
||||
@@ -26,34 +30,41 @@ core.register_entity(":__builtin:falling_node", {
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
return core.serialize(self.node)
|
||||
local ds = {
|
||||
node = self.node,
|
||||
meta = self.meta,
|
||||
}
|
||||
return core.serialize(ds)
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_armor_groups({immortal = 1})
|
||||
|
||||
local node = core.deserialize(staticdata)
|
||||
if node then
|
||||
self:set_node(node)
|
||||
local ds = core.deserialize(staticdata)
|
||||
if ds and ds.node then
|
||||
self:set_node(ds.node, ds.meta)
|
||||
elseif ds then
|
||||
self:set_node(ds)
|
||||
elseif staticdata ~= "" then
|
||||
self:set_node({name = staticdata})
|
||||
end
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
-- Set gravity
|
||||
-- Set gravity
|
||||
local acceleration = self.object:getacceleration()
|
||||
if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
|
||||
self.object:setacceleration({x = 0, y = -10, z = 0})
|
||||
end
|
||||
-- Turn to actual sand when collides to ground or just move
|
||||
-- Turn to actual node when colliding with ground, or continue to move
|
||||
local pos = self.object:getpos()
|
||||
local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z} -- Position of bottom center point
|
||||
local bcn = core.get_node(bcp)
|
||||
local bcd = core.registered_nodes[bcn.name]
|
||||
-- Note: walkable is in the node definition, not in item groups
|
||||
if not bcd or
|
||||
(bcd.walkable or
|
||||
-- Position of bottom center point
|
||||
local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
|
||||
-- Avoid bugs caused by an unloaded node below
|
||||
local bcn = core.get_node_or_nil(bcp)
|
||||
local bcd = bcn and core.registered_nodes[bcn.name]
|
||||
if bcn and
|
||||
(not bcd or bcd.walkable or
|
||||
(core.get_item_group(self.node.name, "float") ~= 0 and
|
||||
bcd.liquidtype ~= "none")) then
|
||||
if bcd and bcd.leveled and
|
||||
@@ -75,29 +86,33 @@ core.register_entity(":__builtin:falling_node", {
|
||||
local np = {x = bcp.x, y = bcp.y + 1, z = bcp.z}
|
||||
-- Check what's here
|
||||
local n2 = core.get_node(np)
|
||||
local nd = core.registered_nodes[n2.name]
|
||||
-- If it's not air or liquid, remove node and replace it with
|
||||
-- it's drops
|
||||
if n2.name ~= "air" and (not core.registered_nodes[n2.name] or
|
||||
core.registered_nodes[n2.name].liquidtype == "none") then
|
||||
if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
|
||||
core.remove_node(np)
|
||||
if core.registered_nodes[n2.name].buildable_to == false then
|
||||
if nd and nd.buildable_to == false then
|
||||
-- Add dropped items
|
||||
local drops = core.get_node_drops(n2.name, "")
|
||||
for _, dropped_item in ipairs(drops) do
|
||||
for _, dropped_item in pairs(drops) do
|
||||
core.add_item(np, dropped_item)
|
||||
end
|
||||
end
|
||||
-- Run script hook
|
||||
for _, callback in ipairs(core.registered_on_dignodes) do
|
||||
for _, callback in pairs(core.registered_on_dignodes) do
|
||||
callback(np, n2)
|
||||
end
|
||||
end
|
||||
-- Create node and remove entity
|
||||
if core.registered_nodes[self.node.name] then
|
||||
core.add_node(np, self.node)
|
||||
if self.meta then
|
||||
local meta = core.get_meta(np)
|
||||
meta:from_table(self.meta)
|
||||
end
|
||||
end
|
||||
self.object:remove()
|
||||
nodeupdate(np)
|
||||
core.check_for_falling(np)
|
||||
return
|
||||
end
|
||||
local vel = self.object:getvelocity()
|
||||
@@ -108,15 +123,31 @@ core.register_entity(":__builtin:falling_node", {
|
||||
end
|
||||
})
|
||||
|
||||
function spawn_falling_node(p, node)
|
||||
local function spawn_falling_node(p, node, meta)
|
||||
local obj = core.add_entity(p, "__builtin:falling_node")
|
||||
obj:get_luaentity():set_node(node)
|
||||
if obj then
|
||||
obj:get_luaentity():set_node(node, meta)
|
||||
end
|
||||
end
|
||||
|
||||
function drop_attached_node(p)
|
||||
function core.spawn_falling_node(pos)
|
||||
local node = core.get_node(pos)
|
||||
if node.name == "air" or node.name == "ignore" then
|
||||
return false
|
||||
end
|
||||
local obj = core.add_entity(pos, "__builtin:falling_node")
|
||||
if obj then
|
||||
obj:get_luaentity():set_node(node)
|
||||
core.remove_node(pos)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function drop_attached_node(p)
|
||||
local nn = core.get_node(p).name
|
||||
core.remove_node(p)
|
||||
for _, item in ipairs(core.get_node_drops(nn, "")) do
|
||||
for _, item in pairs(core.get_node_drops(nn, "")) do
|
||||
local pos = {
|
||||
x = p.x + math.random()/2 - 0.25,
|
||||
y = p.y + math.random()/2 - 0.25,
|
||||
@@ -126,11 +157,16 @@ function drop_attached_node(p)
|
||||
end
|
||||
end
|
||||
|
||||
function check_attached_node(p, n)
|
||||
function builtin_shared.check_attached_node(p, n)
|
||||
local def = core.registered_nodes[n.name]
|
||||
local d = {x = 0, y = 0, z = 0}
|
||||
if def.paramtype2 == "wallmounted" then
|
||||
d = core.wallmounted_to_dir(n.param2)
|
||||
if def.paramtype2 == "wallmounted" or
|
||||
def.paramtype2 == "colorwallmounted" then
|
||||
-- The fallback vector here is in case 'wallmounted to dir' is nil due
|
||||
-- to voxelmanip placing a wallmounted node without resetting a
|
||||
-- pre-existing param2 value that is out-of-range for wallmounted.
|
||||
-- The fallback vector corresponds to param2 = 0.
|
||||
d = core.wallmounted_to_dir(n.param2) or {x = 0, y = 1, z = 0}
|
||||
else
|
||||
d.y = -1
|
||||
end
|
||||
@@ -147,28 +183,37 @@ end
|
||||
-- Some common functions
|
||||
--
|
||||
|
||||
function nodeupdate_single(p)
|
||||
function core.check_single_for_falling(p)
|
||||
local n = core.get_node(p)
|
||||
if core.get_item_group(n.name, "falling_node") ~= 0 then
|
||||
local p_bottom = {x = p.x, y = p.y - 1, z = p.z}
|
||||
local n_bottom = core.get_node(p_bottom)
|
||||
-- Note: walkable is in the node definition, not in item groups
|
||||
if core.registered_nodes[n_bottom.name] and
|
||||
-- Only spawn falling node if node below is loaded
|
||||
local n_bottom = core.get_node_or_nil(p_bottom)
|
||||
local d_bottom = n_bottom and core.registered_nodes[n_bottom.name]
|
||||
if d_bottom and
|
||||
|
||||
(core.get_item_group(n.name, "float") == 0 or
|
||||
core.registered_nodes[n_bottom.name].liquidtype == "none") and
|
||||
(n.name ~= n_bottom.name or (core.registered_nodes[n_bottom.name].leveled and
|
||||
core.get_node_level(p_bottom) < core.get_node_max_level(p_bottom))) and
|
||||
(not core.registered_nodes[n_bottom.name].walkable or
|
||||
core.registered_nodes[n_bottom.name].buildable_to) then
|
||||
d_bottom.liquidtype == "none") and
|
||||
|
||||
(n.name ~= n_bottom.name or (d_bottom.leveled and
|
||||
core.get_node_level(p_bottom) <
|
||||
core.get_node_max_level(p_bottom))) and
|
||||
|
||||
(not d_bottom.walkable or d_bottom.buildable_to) then
|
||||
n.level = core.get_node_level(p)
|
||||
local meta = core.get_meta(p)
|
||||
local metatable = {}
|
||||
if meta ~= nil then
|
||||
metatable = meta:to_table()
|
||||
end
|
||||
core.remove_node(p)
|
||||
spawn_falling_node(p, n)
|
||||
spawn_falling_node(p, n, metatable)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if core.get_item_group(n.name, "attached_node") ~= 0 then
|
||||
if not check_attached_node(p, n) then
|
||||
if not builtin_shared.check_attached_node(p, n) then
|
||||
drop_attached_node(p)
|
||||
return true
|
||||
end
|
||||
@@ -181,7 +226,7 @@ end
|
||||
-- We don't walk diagonals, only our direct neighbors, and self.
|
||||
-- Down first as likely case, but always before self. The same with sides.
|
||||
-- Up must come last, so that things above self will also fall all at once.
|
||||
local nodeupdate_neighbors = {
|
||||
local check_for_falling_neighbors = {
|
||||
{x = -1, y = -1, z = 0},
|
||||
{x = 1, y = -1, z = 0},
|
||||
{x = 0, y = -1, z = -1},
|
||||
@@ -195,7 +240,7 @@ local nodeupdate_neighbors = {
|
||||
{x = 0, y = 1, z = 0},
|
||||
}
|
||||
|
||||
function nodeupdate(p)
|
||||
function core.check_for_falling(p)
|
||||
-- Round p to prevent falling entities to get stuck.
|
||||
p = vector.round(p)
|
||||
|
||||
@@ -214,10 +259,10 @@ function nodeupdate(p)
|
||||
n = n + 1
|
||||
s[n] = {p = p, v = v}
|
||||
-- Select next node from neighbor list.
|
||||
p = vector.add(p, nodeupdate_neighbors[v])
|
||||
p = vector.add(p, check_for_falling_neighbors[v])
|
||||
-- Now we check out the node. If it is in need of an update,
|
||||
-- it will let us know in the return value (true = updated).
|
||||
if not nodeupdate_single(p) then
|
||||
if not core.check_single_for_falling(p) then
|
||||
-- If we don't need to "recurse" (walk) to it then pop
|
||||
-- our previous pos off the stack and continue from there,
|
||||
-- with the v value we were at when we last were at that
|
||||
@@ -249,12 +294,33 @@ end
|
||||
-- Global callbacks
|
||||
--
|
||||
|
||||
function on_placenode(p, node)
|
||||
nodeupdate(p)
|
||||
local function on_placenode(p, node)
|
||||
core.check_for_falling(p)
|
||||
end
|
||||
core.register_on_placenode(on_placenode)
|
||||
|
||||
function on_dignode(p, node)
|
||||
nodeupdate(p)
|
||||
local function on_dignode(p, node)
|
||||
core.check_for_falling(p)
|
||||
end
|
||||
core.register_on_dignode(on_dignode)
|
||||
|
||||
local function on_punchnode(p, node)
|
||||
core.check_for_falling(p)
|
||||
end
|
||||
core.register_on_punchnode(on_punchnode)
|
||||
|
||||
--
|
||||
-- Globally exported functions
|
||||
--
|
||||
|
||||
-- TODO remove this function after the 0.4.15 release
|
||||
function nodeupdate(p)
|
||||
core.log("deprecated", "nodeupdate: deprecated, please use core.check_for_falling instead")
|
||||
core.check_for_falling(p)
|
||||
end
|
||||
|
||||
-- TODO remove this function after the 0.4.15 release
|
||||
function nodeupdate_single(p)
|
||||
core.log("deprecated", "nodeupdate_single: deprecated, please use core.check_single_for_falling instead")
|
||||
core.check_single_for_falling(p)
|
||||
end
|
||||
|
||||
@@ -9,6 +9,8 @@ core.features = {
|
||||
no_legacy_abms = true,
|
||||
texture_names_parens = true,
|
||||
area_store_custom_ids = true,
|
||||
add_entity_with_staticdata = true,
|
||||
no_chat_message_prediction = true,
|
||||
}
|
||||
|
||||
function core.has_feature(arg)
|
||||
|
||||
@@ -5,9 +5,10 @@ core.forceload_block = nil
|
||||
core.forceload_free_block = nil
|
||||
|
||||
local blocks_forceloaded
|
||||
local blocks_temploaded = {}
|
||||
local total_forceloaded = 0
|
||||
|
||||
local BLOCKSIZE = 16
|
||||
local BLOCKSIZE = core.MAP_BLOCKSIZE
|
||||
local function get_blockpos(pos)
|
||||
return {
|
||||
x = math.floor(pos.x/BLOCKSIZE),
|
||||
@@ -15,32 +16,52 @@ local function get_blockpos(pos)
|
||||
z = math.floor(pos.z/BLOCKSIZE)}
|
||||
end
|
||||
|
||||
function core.forceload_block(pos)
|
||||
-- When we create/free a forceload, it's either transient or persistent. We want
|
||||
-- to add to/remove from the table that corresponds to the type of forceload, but
|
||||
-- we also need the other table because whether we forceload a block depends on
|
||||
-- both tables.
|
||||
-- This function returns the "primary" table we are adding to/removing from, and
|
||||
-- the other table.
|
||||
local function get_relevant_tables(transient)
|
||||
if transient then
|
||||
return blocks_temploaded, blocks_forceloaded
|
||||
else
|
||||
return blocks_forceloaded, blocks_temploaded
|
||||
end
|
||||
end
|
||||
|
||||
function core.forceload_block(pos, transient)
|
||||
local blockpos = get_blockpos(pos)
|
||||
local hash = core.hash_node_position(blockpos)
|
||||
if blocks_forceloaded[hash] ~= nil then
|
||||
blocks_forceloaded[hash] = blocks_forceloaded[hash] + 1
|
||||
local relevant_table, other_table = get_relevant_tables(transient)
|
||||
if relevant_table[hash] ~= nil then
|
||||
relevant_table[hash] = relevant_table[hash] + 1
|
||||
return true
|
||||
elseif other_table[hash] ~= nil then
|
||||
relevant_table[hash] = 1
|
||||
else
|
||||
if total_forceloaded >= (tonumber(core.setting_get("max_forceloaded_blocks")) or 16) then
|
||||
if total_forceloaded >= (tonumber(core.settings:get("max_forceloaded_blocks")) or 16) then
|
||||
return false
|
||||
end
|
||||
total_forceloaded = total_forceloaded+1
|
||||
blocks_forceloaded[hash] = 1
|
||||
relevant_table[hash] = 1
|
||||
forceload_block(blockpos)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function core.forceload_free_block(pos)
|
||||
function core.forceload_free_block(pos, transient)
|
||||
local blockpos = get_blockpos(pos)
|
||||
local hash = core.hash_node_position(blockpos)
|
||||
if blocks_forceloaded[hash] == nil then return end
|
||||
if blocks_forceloaded[hash] > 1 then
|
||||
blocks_forceloaded[hash] = blocks_forceloaded[hash] - 1
|
||||
local relevant_table, other_table = get_relevant_tables(transient)
|
||||
if relevant_table[hash] == nil then return end
|
||||
if relevant_table[hash] > 1 then
|
||||
relevant_table[hash] = relevant_table[hash] - 1
|
||||
elseif other_table[hash] ~= nil then
|
||||
relevant_table[hash] = nil
|
||||
else
|
||||
total_forceloaded = total_forceloaded-1
|
||||
blocks_forceloaded[hash] = nil
|
||||
relevant_table[hash] = nil
|
||||
forceload_free_block(blockpos)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,26 +3,34 @@ local scriptpath = core.get_builtin_path()..DIR_DELIM
|
||||
local commonpath = scriptpath.."common"..DIR_DELIM
|
||||
local gamepath = scriptpath.."game"..DIR_DELIM
|
||||
|
||||
-- Shared between builtin files, but
|
||||
-- not exposed to outer context
|
||||
local builtin_shared = {}
|
||||
|
||||
dofile(commonpath.."vector.lua")
|
||||
|
||||
dofile(gamepath.."constants.lua")
|
||||
dofile(gamepath.."item.lua")
|
||||
assert(loadfile(gamepath.."item.lua"))(builtin_shared)
|
||||
dofile(gamepath.."register.lua")
|
||||
|
||||
if core.setting_getbool("mod_profiling") then
|
||||
dofile(gamepath.."mod_profiling.lua")
|
||||
if core.settings:get_bool("profiler.load") then
|
||||
profiler = dofile(scriptpath.."profiler"..DIR_DELIM.."init.lua")
|
||||
end
|
||||
|
||||
dofile(commonpath .. "after.lua")
|
||||
dofile(gamepath.."item_entity.lua")
|
||||
dofile(gamepath.."deprecated.lua")
|
||||
dofile(gamepath.."misc.lua")
|
||||
dofile(gamepath.."privileges.lua")
|
||||
dofile(gamepath.."auth.lua")
|
||||
dofile(commonpath .. "chatcommands.lua")
|
||||
dofile(gamepath.."chatcommands.lua")
|
||||
dofile(gamepath.."static_spawn.lua")
|
||||
dofile(gamepath.."detached_inventory.lua")
|
||||
dofile(gamepath.."falling.lua")
|
||||
assert(loadfile(gamepath.."falling.lua"))(builtin_shared)
|
||||
dofile(gamepath.."features.lua")
|
||||
dofile(gamepath.."voxelarea.lua")
|
||||
dofile(gamepath.."forceloading.lua")
|
||||
dofile(gamepath.."statbars.lua")
|
||||
|
||||
profiler = nil
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
-- Minetest: builtin/item.lua
|
||||
|
||||
local builtin_shared = ...
|
||||
|
||||
local function copy_pointed_thing(pointed_thing)
|
||||
return {
|
||||
type = pointed_thing.type,
|
||||
@@ -107,7 +109,7 @@ local facedir_to_dir_map = {
|
||||
1, 4, 3, 2,
|
||||
}
|
||||
function core.facedir_to_dir(facedir)
|
||||
return facedir_to_dir[facedir_to_dir_map[facedir]]
|
||||
return facedir_to_dir[facedir_to_dir_map[facedir % 32]]
|
||||
end
|
||||
|
||||
function core.dir_to_wallmounted(dir)
|
||||
@@ -142,11 +144,20 @@ local wallmounted_to_dir = {
|
||||
{x = 0, y = 0, z = -1},
|
||||
}
|
||||
function core.wallmounted_to_dir(wallmounted)
|
||||
return wallmounted_to_dir[wallmounted]
|
||||
return wallmounted_to_dir[wallmounted % 8]
|
||||
end
|
||||
|
||||
function core.dir_to_yaw(dir)
|
||||
return -math.atan2(dir.x, dir.z)
|
||||
end
|
||||
|
||||
function core.yaw_to_dir(yaw)
|
||||
return {x = -math.sin(yaw), y = 0, z = math.cos(yaw)}
|
||||
end
|
||||
|
||||
function core.get_node_drops(nodename, toolname)
|
||||
local drop = ItemStack({name=nodename}):get_definition().drop
|
||||
local def = core.registered_nodes[nodename]
|
||||
local drop = def and def.drop
|
||||
if drop == nil then
|
||||
-- default drop
|
||||
return {nodename}
|
||||
@@ -195,7 +206,6 @@ function core.get_node_drops(nodename, toolname)
|
||||
end
|
||||
|
||||
function core.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||
local item = itemstack:peek_item()
|
||||
local def = itemstack:get_definition()
|
||||
if def.type ~= "node" or pointed_thing.type ~= "node" then
|
||||
return itemstack, false
|
||||
@@ -205,20 +215,21 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||
local oldnode_under = core.get_node_or_nil(under)
|
||||
local above = pointed_thing.above
|
||||
local oldnode_above = core.get_node_or_nil(above)
|
||||
local playername = placer:get_player_name()
|
||||
|
||||
if not oldnode_under or not oldnode_above then
|
||||
core.log("info", placer:get_player_name() .. " tried to place"
|
||||
core.log("info", playername .. " tried to place"
|
||||
.. " node in unloaded position " .. core.pos_to_string(above))
|
||||
return itemstack, false
|
||||
end
|
||||
|
||||
local olddef_under = ItemStack({name=oldnode_under.name}):get_definition()
|
||||
local olddef_under = core.registered_nodes[oldnode_under.name]
|
||||
olddef_under = olddef_under or core.nodedef_default
|
||||
local olddef_above = ItemStack({name=oldnode_above.name}):get_definition()
|
||||
local olddef_above = core.registered_nodes[oldnode_above.name]
|
||||
olddef_above = olddef_above or core.nodedef_default
|
||||
|
||||
if not olddef_above.buildable_to and not olddef_under.buildable_to then
|
||||
core.log("info", placer:get_player_name() .. " tried to place"
|
||||
core.log("info", playername .. " tried to place"
|
||||
.. " node in invalid position " .. core.pos_to_string(above)
|
||||
.. ", replacing " .. oldnode_above.name)
|
||||
return itemstack, false
|
||||
@@ -233,24 +244,27 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||
place_to = {x = under.x, y = under.y, z = under.z}
|
||||
end
|
||||
|
||||
if core.is_protected(place_to, placer:get_player_name()) and
|
||||
if core.is_protected(place_to, playername) and
|
||||
not minetest.check_player_privs(placer, "protection_bypass") then
|
||||
core.log("action", placer:get_player_name()
|
||||
core.log("action", playername
|
||||
.. " tried to place " .. def.name
|
||||
.. " at protected position "
|
||||
.. core.pos_to_string(place_to))
|
||||
core.record_protection_violation(place_to, placer:get_player_name())
|
||||
core.record_protection_violation(place_to, playername)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
core.log("action", placer:get_player_name() .. " places node "
|
||||
core.log("action", playername .. " places node "
|
||||
.. def.name .. " at " .. core.pos_to_string(place_to))
|
||||
|
||||
local oldnode = core.get_node(place_to)
|
||||
local newnode = {name = def.name, param1 = 0, param2 = param2}
|
||||
|
||||
-- Calculate direction for wall mounted stuff like torches and signs
|
||||
if def.paramtype2 == 'wallmounted' and not param2 then
|
||||
if def.place_param2 ~= nil then
|
||||
newnode.param2 = def.place_param2
|
||||
elseif (def.paramtype2 == "wallmounted" or
|
||||
def.paramtype2 == "colorwallmounted") and not param2 then
|
||||
local dir = {
|
||||
x = under.x - above.x,
|
||||
y = under.y - above.y,
|
||||
@@ -258,7 +272,8 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||
}
|
||||
newnode.param2 = core.dir_to_wallmounted(dir)
|
||||
-- Calculate the direction for furnaces and chests and stuff
|
||||
elseif def.paramtype2 == 'facedir' and not param2 then
|
||||
elseif (def.paramtype2 == "facedir" or
|
||||
def.paramtype2 == "colorfacedir") and not param2 then
|
||||
local placer_pos = placer:getpos()
|
||||
if placer_pos then
|
||||
local dir = {
|
||||
@@ -273,7 +288,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||
|
||||
-- Check if the node is attached and if it can be placed there
|
||||
if core.get_item_group(def.name, "attached_node") ~= 0 and
|
||||
not check_attached_node(place_to, newnode) then
|
||||
not builtin_shared.check_attached_node(place_to, newnode) then
|
||||
core.log("action", "attached node " .. def.name ..
|
||||
" can not be placed at " .. core.pos_to_string(place_to))
|
||||
return itemstack, false
|
||||
@@ -296,7 +311,6 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||
end
|
||||
|
||||
-- Run script hook
|
||||
local _, callback
|
||||
for _, callback in ipairs(core.registered_on_placenodes) do
|
||||
-- Deepcopy pos, node and pointed_thing because callback can modify them
|
||||
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
|
||||
@@ -437,8 +451,9 @@ function core.handle_node_drops(pos, drops, digger)
|
||||
end
|
||||
|
||||
function core.node_dig(pos, node, digger)
|
||||
local def = ItemStack({name=node.name}):get_definition()
|
||||
if not def.diggable or (def.can_dig and not def.can_dig(pos,digger)) then
|
||||
local def = core.registered_nodes[node.name]
|
||||
if def and (not def.diggable or
|
||||
(def.can_dig and not def.can_dig(pos, digger))) then
|
||||
core.log("info", digger:get_player_name() .. " tried to dig "
|
||||
.. node.name .. " which is not diggable "
|
||||
.. core.pos_to_string(pos))
|
||||
@@ -463,13 +478,16 @@ function core.node_dig(pos, node, digger)
|
||||
|
||||
local wdef = wielded:get_definition()
|
||||
local tp = wielded:get_tool_capabilities()
|
||||
local dp = core.get_dig_params(def.groups, tp)
|
||||
local dp = core.get_dig_params(def and def.groups, tp)
|
||||
if wdef and wdef.after_use then
|
||||
wielded = wdef.after_use(wielded, digger, node, dp) or wielded
|
||||
else
|
||||
-- Wear out tool
|
||||
if not core.setting_getbool("creative_mode") then
|
||||
if not core.settings:get_bool("creative_mode") then
|
||||
wielded:add_wear(dp.wear)
|
||||
if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then
|
||||
core.sound_play(wdef.sound.breaks, {pos = pos, gain = 0.5})
|
||||
end
|
||||
end
|
||||
end
|
||||
digger:set_wielded_item(wielded)
|
||||
@@ -478,7 +496,7 @@ function core.node_dig(pos, node, digger)
|
||||
core.handle_node_drops(pos, drops, digger)
|
||||
|
||||
local oldmetadata = nil
|
||||
if def.after_dig_node then
|
||||
if def and def.after_dig_node then
|
||||
oldmetadata = core.get_meta(pos):to_table()
|
||||
end
|
||||
|
||||
@@ -486,7 +504,7 @@ function core.node_dig(pos, node, digger)
|
||||
core.remove_node(pos)
|
||||
|
||||
-- Run callback
|
||||
if def.after_dig_node then
|
||||
if def and def.after_dig_node then
|
||||
-- Copy pos and node because callback can modify them
|
||||
local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
|
||||
local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
|
||||
|
||||
@@ -14,7 +14,7 @@ end
|
||||
-- If item_entity_ttl is not set, enity will have default life time
|
||||
-- Setting it to -1 disables the feature
|
||||
|
||||
local time_to_live = tonumber(core.setting_get("item_entity_ttl"))
|
||||
local time_to_live = tonumber(core.settings:get("item_entity_ttl"))
|
||||
if not time_to_live then
|
||||
time_to_live = 900
|
||||
end
|
||||
@@ -31,7 +31,6 @@ core.register_entity(":__builtin:item", {
|
||||
spritediv = {x = 1, y = 1},
|
||||
initial_sprite_basepos = {x = 0, y = 0},
|
||||
is_visible = false,
|
||||
infotext = "",
|
||||
},
|
||||
|
||||
itemstring = '',
|
||||
@@ -51,16 +50,16 @@ core.register_entity(":__builtin:item", {
|
||||
local c = s
|
||||
local itemtable = stack:to_table()
|
||||
local itemname = nil
|
||||
local description = ""
|
||||
if itemtable then
|
||||
itemname = stack:to_table().name
|
||||
end
|
||||
-- Backwards compatibility: old clients use the texture
|
||||
-- to get the type of the item
|
||||
local item_texture = nil
|
||||
local item_type = ""
|
||||
if core.registered_items[itemname] then
|
||||
item_texture = core.registered_items[itemname].inventory_image
|
||||
item_type = core.registered_items[itemname].type
|
||||
description = core.registered_items[itemname].description
|
||||
end
|
||||
local prop = {
|
||||
is_visible = true,
|
||||
@@ -69,7 +68,7 @@ core.register_entity(":__builtin:item", {
|
||||
visual_size = {x = s, y = s},
|
||||
collisionbox = {-c, -c, -c, c, c, c},
|
||||
automatic_rotate = math.pi * 0.5,
|
||||
infotext = description,
|
||||
wield_item = itemstring,
|
||||
}
|
||||
self.object:set_properties(prop)
|
||||
end,
|
||||
@@ -105,31 +104,39 @@ core.register_entity(":__builtin:item", {
|
||||
self:set_item(self.itemstring)
|
||||
end,
|
||||
|
||||
-- moves items from this stack to an other stack
|
||||
try_merge_with = function(self, own_stack, object, obj)
|
||||
-- other item's stack
|
||||
local stack = ItemStack(obj.itemstring)
|
||||
if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then
|
||||
-- only merge if items are the same
|
||||
if own_stack:get_name() == stack:get_name() and
|
||||
own_stack:get_meta() == stack:get_meta() and
|
||||
own_stack:get_wear() == stack:get_wear() and
|
||||
stack:get_free_space() > 0 then
|
||||
local overflow = false
|
||||
local count = stack:get_count() + own_stack:get_count()
|
||||
local max_count = stack:get_stack_max()
|
||||
if count > max_count then
|
||||
overflow = true
|
||||
stack:set_count(max_count)
|
||||
count = count - max_count
|
||||
own_stack:set_count(count)
|
||||
else
|
||||
self.itemstring = ''
|
||||
stack:set_count(count)
|
||||
end
|
||||
local pos = object:getpos()
|
||||
pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
|
||||
object:moveto(pos, false)
|
||||
local s, c
|
||||
local max_count = stack:get_stack_max()
|
||||
local name = stack:get_name()
|
||||
if not overflow then
|
||||
obj.itemstring = name .. " " .. count
|
||||
obj.itemstring = stack:to_string()
|
||||
s = 0.2 + 0.1 * (count / max_count)
|
||||
c = s
|
||||
object:set_properties({
|
||||
visual_size = {x = s, y = s},
|
||||
collisionbox = {-c, -c, -c, c, c, c}
|
||||
collisionbox = {-c, -c, -c, c, c, c},
|
||||
wield_item = obj.itemstring
|
||||
})
|
||||
self.object:remove()
|
||||
-- merging succeeded
|
||||
@@ -137,18 +144,20 @@ core.register_entity(":__builtin:item", {
|
||||
else
|
||||
s = 0.4
|
||||
c = 0.3
|
||||
obj.itemstring = stack:to_string()
|
||||
object:set_properties({
|
||||
visual_size = {x = s, y = s},
|
||||
collisionbox = {-c, -c, -c, c, c, c}
|
||||
collisionbox = {-c, -c, -c, c, c, c},
|
||||
wield_item = obj.itemstring
|
||||
})
|
||||
obj.itemstring = name .. " " .. max_count
|
||||
s = 0.2 + 0.1 * (count / max_count)
|
||||
c = s
|
||||
self.itemstring = own_stack:to_string()
|
||||
self.object:set_properties({
|
||||
visual_size = {x = s, y = s},
|
||||
collisionbox = {-c, -c, -c, c, c, c}
|
||||
collisionbox = {-c, -c, -c, c, c, c},
|
||||
wield_item = self.itemstring
|
||||
})
|
||||
self.itemstring = name .. " " .. count
|
||||
end
|
||||
end
|
||||
-- merging didn't succeed
|
||||
|
||||
@@ -4,61 +4,19 @@
|
||||
-- Misc. API functions
|
||||
--
|
||||
|
||||
local jobs = {}
|
||||
local time = 0.0
|
||||
local last = core.get_us_time() / 1000000
|
||||
|
||||
core.register_globalstep(function(dtime)
|
||||
local new = core.get_us_time() / 1000000
|
||||
if new > last then
|
||||
time = time + (new - last)
|
||||
else
|
||||
-- Overflow, we may lose a little bit of time here but
|
||||
-- only 1 tick max, potentially running timers slightly
|
||||
-- too early.
|
||||
time = time + new
|
||||
end
|
||||
last = new
|
||||
|
||||
if #jobs < 1 then
|
||||
return
|
||||
end
|
||||
|
||||
-- Iterate backwards so that we miss any new timers added by
|
||||
-- a timer callback, and so that we don't skip the next timer
|
||||
-- in the list if we remove one.
|
||||
for i = #jobs, 1, -1 do
|
||||
local job = jobs[i]
|
||||
if time >= job.expire then
|
||||
core.set_last_run_mod(job.mod_origin)
|
||||
job.func(unpack(job.arg))
|
||||
table.remove(jobs, i)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function core.after(after, func, ...)
|
||||
assert(tonumber(time) and type(func) == "function",
|
||||
"Invalid core.after invocation")
|
||||
jobs[#jobs + 1] = {
|
||||
func = func,
|
||||
expire = time + after,
|
||||
arg = {...},
|
||||
mod_origin = core.get_last_run_mod()
|
||||
}
|
||||
end
|
||||
|
||||
function core.check_player_privs(player_or_name, ...)
|
||||
local name = player_or_name
|
||||
-- Check if we have been provided with a Player object.
|
||||
if type(name) ~= "string" then
|
||||
function core.check_player_privs(name, ...)
|
||||
local arg_type = type(name)
|
||||
if (arg_type == "userdata" or arg_type == "table") and
|
||||
name.get_player_name then -- If it quacks like a Player...
|
||||
name = name:get_player_name()
|
||||
elseif arg_type ~= "string" then
|
||||
error("Invalid core.check_player_privs argument type: " .. arg_type, 2)
|
||||
end
|
||||
|
||||
|
||||
local requested_privs = {...}
|
||||
local player_privs = core.get_player_privs(name)
|
||||
local missing_privileges = {}
|
||||
|
||||
|
||||
if type(requested_privs[1]) == "table" then
|
||||
-- We were provided with a table like { privA = true, privB = true }.
|
||||
for priv, value in pairs(requested_privs[1]) do
|
||||
@@ -74,22 +32,32 @@ function core.check_player_privs(player_or_name, ...)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if #missing_privileges > 0 then
|
||||
return false, missing_privileges
|
||||
end
|
||||
|
||||
|
||||
return true, ""
|
||||
end
|
||||
|
||||
local player_list = {}
|
||||
|
||||
core.register_on_joinplayer(function(player)
|
||||
player_list[player:get_player_name()] = player
|
||||
local player_name = player:get_player_name()
|
||||
player_list[player_name] = player
|
||||
if not minetest.is_singleplayer() then
|
||||
core.chat_send_all("*** " .. player_name .. " joined the game.")
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_on_leaveplayer(function(player)
|
||||
player_list[player:get_player_name()] = nil
|
||||
core.register_on_leaveplayer(function(player, timed_out)
|
||||
local player_name = player:get_player_name()
|
||||
player_list[player_name] = nil
|
||||
local announcement = "*** " .. player_name .. " left the game."
|
||||
if timed_out then
|
||||
announcement = announcement .. " (timed out)"
|
||||
end
|
||||
core.chat_send_all(announcement)
|
||||
end)
|
||||
|
||||
function core.get_connected_players()
|
||||
@@ -102,6 +70,10 @@ function core.get_connected_players()
|
||||
return temp_table
|
||||
end
|
||||
|
||||
function minetest.player_exists(name)
|
||||
return minetest.get_auth_handler().get_auth(name) ~= nil
|
||||
end
|
||||
|
||||
-- Returns two position vectors representing a box of `radius` in each
|
||||
-- direction centered around the player corresponding to `player_name`
|
||||
function core.get_player_radius_area(player_name, radius)
|
||||
@@ -149,7 +121,7 @@ function core.get_node_group(name, group)
|
||||
end
|
||||
|
||||
function core.setting_get_pos(name)
|
||||
local value = core.setting_get(name)
|
||||
local value = core.settings:get(name)
|
||||
if not value then
|
||||
return nil
|
||||
end
|
||||
@@ -197,3 +169,12 @@ function core.http_add_fetch(httpenv)
|
||||
|
||||
return httpenv
|
||||
end
|
||||
|
||||
function core.close_formspec(player_name, formname)
|
||||
return minetest.show_formspec(player_name, formname, "")
|
||||
end
|
||||
|
||||
function core.cancel_shutdown_requests()
|
||||
core.request_shutdown("", false, -1)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,356 +0,0 @@
|
||||
-- Minetest: builtin/game/mod_profiling.lua
|
||||
|
||||
local mod_statistics = {}
|
||||
mod_statistics.step_total = 0
|
||||
mod_statistics.data = {}
|
||||
mod_statistics.stats = {}
|
||||
mod_statistics.stats["total"] = {
|
||||
min_us = math.huge,
|
||||
max_us = 0,
|
||||
avg_us = 0,
|
||||
min_per = 100,
|
||||
max_per = 100,
|
||||
avg_per = 100
|
||||
}
|
||||
|
||||
local replacement_table = {
|
||||
"register_globalstep",
|
||||
"register_on_placenode",
|
||||
"register_on_dignode",
|
||||
"register_on_punchnode",
|
||||
"register_on_generated",
|
||||
"register_on_newplayer",
|
||||
"register_on_dieplayer",
|
||||
"register_on_respawnplayer",
|
||||
"register_on_prejoinplayer",
|
||||
"register_on_joinplayer",
|
||||
"register_on_leaveplayer",
|
||||
"register_on_cheat",
|
||||
"register_on_chat_message",
|
||||
"register_on_player_receive_fields",
|
||||
"register_on_mapgen_init",
|
||||
"register_on_craft",
|
||||
"register_craft_predict",
|
||||
"register_on_item_eat"
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function mod_statistics.log_time(type, modname, time_in_us)
|
||||
|
||||
if modname == nil then
|
||||
modname = "builtin"
|
||||
end
|
||||
|
||||
if mod_statistics.data[modname] == nil then
|
||||
mod_statistics.data[modname] = {}
|
||||
end
|
||||
|
||||
if mod_statistics.data[modname][type] == nil then
|
||||
mod_statistics.data[modname][type] = 0
|
||||
end
|
||||
|
||||
mod_statistics.data[modname][type] =
|
||||
mod_statistics.data[modname][type] + time_in_us
|
||||
mod_statistics.step_total = mod_statistics.step_total + time_in_us
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function mod_statistics.update_statistics(dtime)
|
||||
for modname,types in pairs(mod_statistics.data) do
|
||||
|
||||
if mod_statistics.stats[modname] == nil then
|
||||
mod_statistics.stats[modname] = {
|
||||
min_us = math.huge,
|
||||
max_us = 0,
|
||||
avg_us = 0,
|
||||
min_per = 100,
|
||||
max_per = 0,
|
||||
avg_per = 0
|
||||
}
|
||||
end
|
||||
|
||||
local modtime = 0
|
||||
for type,time in pairs(types) do
|
||||
modtime = modtime + time
|
||||
if mod_statistics.stats[modname].types == nil then
|
||||
mod_statistics.stats[modname].types = {}
|
||||
end
|
||||
if mod_statistics.stats[modname].types[type] == nil then
|
||||
mod_statistics.stats[modname].types[type] = {
|
||||
min_us = math.huge,
|
||||
max_us = 0,
|
||||
avg_us = 0,
|
||||
min_per = 100,
|
||||
max_per = 0,
|
||||
avg_per = 0
|
||||
}
|
||||
end
|
||||
|
||||
local toupdate = mod_statistics.stats[modname].types[type]
|
||||
|
||||
--update us values
|
||||
toupdate.min_us = math.min(time, toupdate.min_us)
|
||||
toupdate.max_us = math.max(time, toupdate.max_us)
|
||||
--TODO find better algorithm
|
||||
toupdate.avg_us = toupdate.avg_us * 0.99 + modtime * 0.01
|
||||
|
||||
--update percentage values
|
||||
local cur_per = (time/mod_statistics.step_total) * 100
|
||||
toupdate.min_per = math.min(toupdate.min_per, cur_per)
|
||||
|
||||
toupdate.max_per = math.max(toupdate.max_per, cur_per)
|
||||
|
||||
--TODO find better algorithm
|
||||
toupdate.avg_per = toupdate.avg_per * 0.99 + cur_per * 0.01
|
||||
|
||||
mod_statistics.data[modname][type] = 0
|
||||
end
|
||||
|
||||
--per mod statistics
|
||||
--update us values
|
||||
mod_statistics.stats[modname].min_us =
|
||||
math.min(modtime, mod_statistics.stats[modname].min_us)
|
||||
mod_statistics.stats[modname].max_us =
|
||||
math.max(modtime, mod_statistics.stats[modname].max_us)
|
||||
--TODO find better algorithm
|
||||
mod_statistics.stats[modname].avg_us =
|
||||
mod_statistics.stats[modname].avg_us * 0.99 + modtime * 0.01
|
||||
|
||||
--update percentage values
|
||||
local cur_per = (modtime/mod_statistics.step_total) * 100
|
||||
mod_statistics.stats[modname].min_per =
|
||||
math.min(mod_statistics.stats[modname].min_per, cur_per)
|
||||
|
||||
mod_statistics.stats[modname].max_per =
|
||||
math.max(mod_statistics.stats[modname].max_per, cur_per)
|
||||
|
||||
--TODO find better algorithm
|
||||
mod_statistics.stats[modname].avg_per =
|
||||
mod_statistics.stats[modname].avg_per * 0.99 + cur_per * 0.01
|
||||
end
|
||||
|
||||
--update "total"
|
||||
mod_statistics.stats["total"].min_us =
|
||||
math.min(mod_statistics.step_total, mod_statistics.stats["total"].min_us)
|
||||
mod_statistics.stats["total"].max_us =
|
||||
math.max(mod_statistics.step_total, mod_statistics.stats["total"].max_us)
|
||||
--TODO find better algorithm
|
||||
mod_statistics.stats["total"].avg_us =
|
||||
mod_statistics.stats["total"].avg_us * 0.99 +
|
||||
mod_statistics.step_total * 0.01
|
||||
|
||||
mod_statistics.step_total = 0
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function build_callback(log_id, fct)
|
||||
return function( toregister )
|
||||
local modname = core.get_current_modname()
|
||||
|
||||
fct(function(...)
|
||||
local starttime = core.get_us_time()
|
||||
-- note maximum 10 return values are supported unless someone finds
|
||||
-- a way to store a variable lenght return value list
|
||||
local r0, r1, r2, r3, r4, r5, r6, r7, r8, r9 = toregister(...)
|
||||
local delta = core.get_us_time() - starttime
|
||||
mod_statistics.log_time(log_id, modname, delta)
|
||||
return r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function profiling_print_log(cmd, filter)
|
||||
|
||||
print("Filter:" .. dump(filter))
|
||||
|
||||
core.log("action", "Values below show times/percentages per server step.")
|
||||
core.log("action", "Following suffixes are used for entities:")
|
||||
core.log("action", "\t#oa := on_activate, #os := on_step, #op := on_punch, #or := on_rightclick, #gs := get_staticdata")
|
||||
core.log("action",
|
||||
string.format("%16s | %25s | %10s | %10s | %10s | %9s | %9s | %9s",
|
||||
"modname", "type" , "min µs", "max µs", "avg µs", "min %", "max %", "avg %")
|
||||
)
|
||||
core.log("action",
|
||||
"-----------------+---------------------------+-----------+" ..
|
||||
"-----------+-----------+-----------+-----------+-----------")
|
||||
for modname,statistics in pairs(mod_statistics.stats) do
|
||||
if modname ~= "total" then
|
||||
|
||||
if (filter == "") or (modname == filter) then
|
||||
if modname:len() > 16 then
|
||||
modname = "..." .. modname:sub(-13)
|
||||
end
|
||||
|
||||
core.log("action",
|
||||
string.format("%16s | %25s | %9d | %9d | %9d | %9d | %9d | %9d",
|
||||
modname,
|
||||
" ",
|
||||
statistics.min_us,
|
||||
statistics.max_us,
|
||||
statistics.avg_us,
|
||||
statistics.min_per,
|
||||
statistics.max_per,
|
||||
statistics.avg_per)
|
||||
)
|
||||
if core.setting_getbool("detailed_profiling") then
|
||||
if statistics.types ~= nil then
|
||||
for type,typestats in pairs(statistics.types) do
|
||||
|
||||
if type:len() > 25 then
|
||||
type = "..." .. type:sub(-22)
|
||||
end
|
||||
|
||||
core.log("action",
|
||||
string.format(
|
||||
"%16s | %25s | %9d | %9d | %9d | %9d | %9d | %9d",
|
||||
" ",
|
||||
type,
|
||||
typestats.min_us,
|
||||
typestats.max_us,
|
||||
typestats.avg_us,
|
||||
typestats.min_per,
|
||||
typestats.max_per,
|
||||
typestats.avg_per)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
core.log("action",
|
||||
"-----------------+---------------------------+-----------+" ..
|
||||
"-----------+-----------+-----------+-----------+-----------")
|
||||
|
||||
if filter == "" then
|
||||
core.log("action",
|
||||
string.format("%16s | %25s | %9d | %9d | %9d | %9d | %9d | %9d",
|
||||
"total",
|
||||
" ",
|
||||
mod_statistics.stats["total"].min_us,
|
||||
mod_statistics.stats["total"].max_us,
|
||||
mod_statistics.stats["total"].avg_us,
|
||||
mod_statistics.stats["total"].min_per,
|
||||
mod_statistics.stats["total"].max_per,
|
||||
mod_statistics.stats["total"].avg_per)
|
||||
)
|
||||
end
|
||||
core.log("action", " ")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function initialize_profiling()
|
||||
core.log("action", "Initialize tracing")
|
||||
|
||||
mod_statistics.entity_callbacks = {}
|
||||
|
||||
-- first register our own globalstep handler
|
||||
core.register_globalstep(mod_statistics.update_statistics)
|
||||
|
||||
local rp_register_entity = core.register_entity
|
||||
core.register_entity = function(name, prototype)
|
||||
local modname = core.get_current_modname()
|
||||
local new_on_activate = nil
|
||||
local new_on_step = nil
|
||||
local new_on_punch = nil
|
||||
local new_rightclick = nil
|
||||
local new_get_staticdata = nil
|
||||
|
||||
if prototype.on_activate ~= nil then
|
||||
local cbid = name .. "#oa"
|
||||
mod_statistics.entity_callbacks[cbid] = prototype.on_activate
|
||||
new_on_activate = function(self, staticdata, dtime_s)
|
||||
local starttime = core.get_us_time()
|
||||
mod_statistics.entity_callbacks[cbid](self, staticdata, dtime_s)
|
||||
local delta = core.get_us_time() -starttime
|
||||
mod_statistics.log_time(cbid, modname, delta)
|
||||
end
|
||||
end
|
||||
|
||||
if prototype.on_step ~= nil then
|
||||
local cbid = name .. "#os"
|
||||
mod_statistics.entity_callbacks[cbid] = prototype.on_step
|
||||
new_on_step = function(self, dtime)
|
||||
local starttime = core.get_us_time()
|
||||
mod_statistics.entity_callbacks[cbid](self, dtime)
|
||||
local delta = core.get_us_time() -starttime
|
||||
mod_statistics.log_time(cbid, modname, delta)
|
||||
end
|
||||
end
|
||||
|
||||
if prototype.on_punch ~= nil then
|
||||
local cbid = name .. "#op"
|
||||
mod_statistics.entity_callbacks[cbid] = prototype.on_punch
|
||||
new_on_punch = function(self, hitter)
|
||||
local starttime = core.get_us_time()
|
||||
mod_statistics.entity_callbacks[cbid](self, hitter)
|
||||
local delta = core.get_us_time() -starttime
|
||||
mod_statistics.log_time(cbid, modname, delta)
|
||||
end
|
||||
end
|
||||
|
||||
if prototype.rightclick ~= nil then
|
||||
local cbid = name .. "#rc"
|
||||
mod_statistics.entity_callbacks[cbid] = prototype.rightclick
|
||||
new_rightclick = function(self, clicker)
|
||||
local starttime = core.get_us_time()
|
||||
mod_statistics.entity_callbacks[cbid](self, clicker)
|
||||
local delta = core.get_us_time() -starttime
|
||||
mod_statistics.log_time(cbid, modname, delta)
|
||||
end
|
||||
end
|
||||
|
||||
if prototype.get_staticdata ~= nil then
|
||||
local cbid = name .. "#gs"
|
||||
mod_statistics.entity_callbacks[cbid] = prototype.get_staticdata
|
||||
new_get_staticdata = function(self)
|
||||
local starttime = core.get_us_time()
|
||||
local retval = mod_statistics.entity_callbacks[cbid](self)
|
||||
local delta = core.get_us_time() -starttime
|
||||
mod_statistics.log_time(cbid, modname, delta)
|
||||
return retval
|
||||
end
|
||||
end
|
||||
|
||||
prototype.on_activate = new_on_activate
|
||||
prototype.on_step = new_on_step
|
||||
prototype.on_punch = new_on_punch
|
||||
prototype.rightclick = new_rightclick
|
||||
prototype.get_staticdata = new_get_staticdata
|
||||
|
||||
rp_register_entity(name,prototype)
|
||||
end
|
||||
|
||||
for i,v in ipairs(replacement_table) do
|
||||
local to_replace = core[v]
|
||||
core[v] = build_callback(v, to_replace)
|
||||
end
|
||||
|
||||
local rp_register_abm = core.register_abm
|
||||
core.register_abm = function(spec)
|
||||
|
||||
local modname = core.get_current_modname()
|
||||
|
||||
local replacement_spec = {
|
||||
nodenames = spec.nodenames,
|
||||
neighbors = spec.neighbors,
|
||||
interval = spec.interval,
|
||||
chance = spec.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local starttime = core.get_us_time()
|
||||
spec.action(pos, node, active_object_count, active_object_count_wider)
|
||||
local delta = core.get_us_time() - starttime
|
||||
mod_statistics.log_time("abm", modname, delta)
|
||||
end
|
||||
}
|
||||
rp_register_abm(replacement_spec)
|
||||
end
|
||||
|
||||
core.log("action", "Mod profiling initialized")
|
||||
end
|
||||
|
||||
initialize_profiling()
|
||||
@@ -26,18 +26,46 @@ function core.register_privilege(name, param)
|
||||
end
|
||||
|
||||
core.register_privilege("interact", "Can interact with things and modify the world")
|
||||
core.register_privilege("teleport", "Can use /teleport command")
|
||||
core.register_privilege("bring", "Can teleport other players")
|
||||
core.register_privilege("settime", "Can use /time")
|
||||
core.register_privilege("privs", "Can modify privileges")
|
||||
core.register_privilege("basic_privs", "Can modify 'shout' and 'interact' privileges")
|
||||
core.register_privilege("server", "Can do server maintenance stuff")
|
||||
core.register_privilege("protection_bypass", "Can bypass node protection in the world")
|
||||
core.register_privilege("shout", "Can speak in chat")
|
||||
core.register_privilege("ban", "Can ban and unban players")
|
||||
core.register_privilege("kick", "Can kick players")
|
||||
core.register_privilege("give", "Can use /give and /giveme")
|
||||
core.register_privilege("password", "Can use /setpassword and /clearpassword")
|
||||
core.register_privilege("basic_privs", "Can modify 'shout' and 'interact' privileges")
|
||||
core.register_privilege("privs", "Can modify privileges")
|
||||
|
||||
core.register_privilege("teleport", {
|
||||
description = "Can use /teleport command",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("bring", {
|
||||
description = "Can teleport other players",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("settime", {
|
||||
description = "Can use /time",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("server", {
|
||||
description = "Can do server maintenance stuff",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("protection_bypass", {
|
||||
description = "Can bypass node protection in the world",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("ban", {
|
||||
description = "Can ban and unban players",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("kick", {
|
||||
description = "Can kick players",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("give", {
|
||||
description = "Can use /give and /giveme",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("password", {
|
||||
description = "Can use /setpassword and /clearpassword",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("fly", {
|
||||
description = "Can fly using the free_move mode",
|
||||
give_to_singleplayer = false,
|
||||
@@ -50,5 +78,15 @@ core.register_privilege("noclip", {
|
||||
description = "Can fly through walls",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("rollback", "Can use the rollback functionality")
|
||||
|
||||
core.register_privilege("rollback", {
|
||||
description = "Can use the rollback functionality",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("zoom", {
|
||||
description = "Can zoom the camera",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
core.register_privilege("debug", {
|
||||
description = "Allows enabling various debug options that may affect gameplay",
|
||||
give_to_singleplayer = false,
|
||||
})
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
local register_item_raw = core.register_item_raw
|
||||
core.register_item_raw = nil
|
||||
|
||||
local unregister_item_raw = core.unregister_item_raw
|
||||
core.unregister_item_raw = nil
|
||||
|
||||
local register_alias_raw = core.register_alias_raw
|
||||
core.register_alias_raw = nil
|
||||
|
||||
@@ -124,6 +127,11 @@ function core.register_item(name, itemdef)
|
||||
fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8},
|
||||
}
|
||||
end
|
||||
if itemdef.light_source and itemdef.light_source > core.LIGHT_MAX then
|
||||
itemdef.light_source = core.LIGHT_MAX
|
||||
core.log("warning", "Node 'light_source' value exceeds maximum," ..
|
||||
" limiting to maximum: " ..name)
|
||||
end
|
||||
setmetatable(itemdef, {__index = core.nodedef_default})
|
||||
core.registered_nodes[itemdef.name] = itemdef
|
||||
elseif itemdef.type == "craft" then
|
||||
@@ -172,6 +180,27 @@ function core.register_item(name, itemdef)
|
||||
register_item_raw(itemdef)
|
||||
end
|
||||
|
||||
function core.unregister_item(name)
|
||||
if not core.registered_items[name] then
|
||||
core.log("warning", "Not unregistering item " ..name..
|
||||
" because it doesn't exist.")
|
||||
return
|
||||
end
|
||||
-- Erase from registered_* table
|
||||
local type = core.registered_items[name].type
|
||||
if type == "node" then
|
||||
core.registered_nodes[name] = nil
|
||||
elseif type == "craft" then
|
||||
core.registered_craftitems[name] = nil
|
||||
elseif type == "tool" then
|
||||
core.registered_tools[name] = nil
|
||||
end
|
||||
core.registered_items[name] = nil
|
||||
|
||||
|
||||
unregister_item_raw(name)
|
||||
end
|
||||
|
||||
function core.register_node(name, nodedef)
|
||||
nodedef.type = "node"
|
||||
core.register_item(name, nodedef)
|
||||
@@ -242,6 +271,20 @@ function core.register_alias(name, convert_to)
|
||||
end
|
||||
end
|
||||
|
||||
function core.register_alias_force(name, convert_to)
|
||||
if forbidden_item_names[name] then
|
||||
error("Unable to register alias: Name is forbidden: " .. name)
|
||||
end
|
||||
if core.registered_items[name] ~= nil then
|
||||
core.unregister_item(name)
|
||||
core.log("info", "Removed item " ..name..
|
||||
" while attempting to force add an alias")
|
||||
end
|
||||
--core.log("Registering alias: " .. name .. " -> " .. convert_to)
|
||||
core.registered_aliases[name] = convert_to
|
||||
register_alias_raw(name, convert_to)
|
||||
end
|
||||
|
||||
function core.on_craft(itemstack, player, old_craft_list, craft_inv)
|
||||
for _, func in ipairs(core.registered_on_crafts) do
|
||||
itemstack = func(itemstack, player, old_craft_list, craft_inv) or itemstack
|
||||
@@ -288,8 +331,8 @@ core.register_item(":unknown", {
|
||||
|
||||
core.register_node(":air", {
|
||||
description = "Air (you hacker you!)",
|
||||
inventory_image = "unknown_node.png",
|
||||
wield_image = "unknown_node.png",
|
||||
inventory_image = "air.png",
|
||||
wield_image = "air.png",
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
@@ -305,8 +348,8 @@ core.register_node(":air", {
|
||||
|
||||
core.register_node(":ignore", {
|
||||
description = "Ignore (you hacker you!)",
|
||||
inventory_image = "unknown_node.png",
|
||||
wield_image = "unknown_node.png",
|
||||
inventory_image = "ignore.png",
|
||||
wield_image = "ignore.png",
|
||||
drawtype = "airlike",
|
||||
paramtype = "none",
|
||||
sunlight_propagates = false,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
-- cache setting
|
||||
local enable_damage = core.settings:get_bool("enable_damage")
|
||||
|
||||
local health_bar_definition =
|
||||
{
|
||||
@@ -42,9 +44,8 @@ local function initialize_builtin_statbars(player)
|
||||
player:hud_set_flags(player:hud_get_flags())
|
||||
end
|
||||
|
||||
if player:hud_get_flags().healthbar and
|
||||
core.is_yes(core.setting_get("enable_damage")) then
|
||||
if hud_ids[name].id_healthbar == nil then
|
||||
if player:hud_get_flags().healthbar and enable_damage then
|
||||
if hud_ids[name].id_healthbar == nil then
|
||||
health_bar_definition.number = player:get_hp()
|
||||
hud_ids[name].id_healthbar = player:hud_add(health_bar_definition)
|
||||
end
|
||||
@@ -56,8 +57,7 @@ local function initialize_builtin_statbars(player)
|
||||
end
|
||||
|
||||
if (player:get_breath() < 11) then
|
||||
if player:hud_get_flags().breathbar and
|
||||
core.is_yes(core.setting_get("enable_damage")) then
|
||||
if player:hud_get_flags().breathbar and enable_damage then
|
||||
if hud_ids[name].id_breathbar == nil then
|
||||
hud_ids[name].id_breathbar = player:hud_add(breath_bar_definition)
|
||||
end
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
-- Minetest: builtin/static_spawn.lua
|
||||
|
||||
local function warn_invalid_static_spawnpoint()
|
||||
if core.setting_get("static_spawnpoint") and
|
||||
if core.settings:get("static_spawnpoint") and
|
||||
not core.setting_get_pos("static_spawnpoint") then
|
||||
core.log("error", "The static_spawnpoint setting is invalid: \""..
|
||||
core.setting_get("static_spawnpoint").."\"")
|
||||
core.settings:get("static_spawnpoint").."\"")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ end
|
||||
function VoxelArea:position(i)
|
||||
local p = {}
|
||||
local MinEdge = self.MinEdge
|
||||
|
||||
|
||||
i = i - 1
|
||||
|
||||
p.z = math.floor(i / self.zstride) + MinEdge.z
|
||||
@@ -84,23 +84,46 @@ end
|
||||
|
||||
function VoxelArea:iter(minx, miny, minz, maxx, maxy, maxz)
|
||||
local i = self:index(minx, miny, minz) - 1
|
||||
local last = self:index(maxx, maxy, maxz)
|
||||
local ystride = self.ystride
|
||||
local zstride = self.zstride
|
||||
local yoff = (last+1) % ystride
|
||||
local zoff = (last+1) % zstride
|
||||
local ystridediff = (i - last) % ystride
|
||||
local zstridediff = (i - last) % zstride
|
||||
local xrange = maxx - minx + 1
|
||||
local nextaction = i + 1 + xrange
|
||||
|
||||
local y = 0
|
||||
local yrange = maxy - miny + 1
|
||||
local yreqstride = self.ystride - xrange
|
||||
|
||||
local z = 0
|
||||
local zrange = maxz - minz + 1
|
||||
local multistride = self.zstride - ((yrange - 1) * self.ystride + xrange)
|
||||
|
||||
return function()
|
||||
-- continue i until it needs to jump
|
||||
i = i + 1
|
||||
if i % zstride == zoff then
|
||||
i = i + zstridediff
|
||||
elseif i % ystride == yoff then
|
||||
i = i + ystridediff
|
||||
end
|
||||
if i <= last then
|
||||
if i ~= nextaction then
|
||||
return i
|
||||
end
|
||||
|
||||
-- continue y until maxy is exceeded
|
||||
y = y + 1
|
||||
if y ~= yrange then
|
||||
-- set i to index(minx, miny + y, minz + z) - 1
|
||||
i = i + yreqstride
|
||||
nextaction = i + xrange
|
||||
return i
|
||||
end
|
||||
|
||||
-- continue z until maxz is exceeded
|
||||
z = z + 1
|
||||
if z == zrange then
|
||||
-- cuboid finished, return nil
|
||||
return
|
||||
end
|
||||
|
||||
-- set i to index(minx, miny, minz + z) - 1
|
||||
i = i + multistride
|
||||
|
||||
y = 0
|
||||
nextaction = i + xrange
|
||||
return i
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ minetest = core
|
||||
-- Load other files
|
||||
local scriptdir = core.get_builtin_path() .. DIR_DELIM
|
||||
local gamepath = scriptdir .. "game" .. DIR_DELIM
|
||||
local clientpath = scriptdir .. "client" .. DIR_DELIM
|
||||
local commonpath = scriptdir .. "common" .. DIR_DELIM
|
||||
local asyncpath = scriptdir .. "async" .. DIR_DELIM
|
||||
|
||||
@@ -37,15 +38,17 @@ dofile(commonpath .. "misc_helpers.lua")
|
||||
if INIT == "game" then
|
||||
dofile(gamepath .. "init.lua")
|
||||
elseif INIT == "mainmenu" then
|
||||
local mainmenuscript = core.setting_get("main_menu_script")
|
||||
if mainmenuscript ~= nil and mainmenuscript ~= "" then
|
||||
dofile(mainmenuscript)
|
||||
local mm_script = core.settings:get("main_menu_script")
|
||||
if mm_script and mm_script ~= "" then
|
||||
dofile(mm_script)
|
||||
else
|
||||
dofile(core.get_mainmenu_path() .. DIR_DELIM .. "init.lua")
|
||||
end
|
||||
elseif INIT == "async" then
|
||||
dofile(asyncpath .. "init.lua")
|
||||
elseif INIT == "client" then
|
||||
os.setlocale = nil
|
||||
dofile(clientpath .. "init.lua")
|
||||
else
|
||||
error(("Unrecognized builtin initialization type %s!"):format(tostring(INIT)))
|
||||
end
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ end
|
||||
local function configure_selected_world_params(idx)
|
||||
local worldconfig = modmgr.get_worldconfig(menudata.worldlist:get_list()[idx].path)
|
||||
if worldconfig.creative_mode then
|
||||
core.setting_set("creative_mode", worldconfig.creative_mode)
|
||||
core.settings:set("creative_mode", worldconfig.creative_mode)
|
||||
end
|
||||
if worldconfig.enable_damage then
|
||||
core.setting_set("enable_damage", worldconfig.enable_damage)
|
||||
core.settings:set("enable_damage", worldconfig.enable_damage)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -54,7 +54,12 @@ end
|
||||
function image_column(tooltip, flagname)
|
||||
return "image,tooltip=" .. core.formspec_escape(tooltip) .. "," ..
|
||||
"0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," ..
|
||||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
|
||||
"1=" .. core.formspec_escape(defaulttexturedir ..
|
||||
(flagname and "server_flags_" .. flagname .. ".png" or "blank.png")) .. "," ..
|
||||
"2=" .. core.formspec_escape(defaulttexturedir .. "server_ping_4.png") .. "," ..
|
||||
"3=" .. core.formspec_escape(defaulttexturedir .. "server_ping_3.png") .. "," ..
|
||||
"4=" .. core.formspec_escape(defaulttexturedir .. "server_ping_2.png") .. "," ..
|
||||
"5=" .. core.formspec_escape(defaulttexturedir .. "server_ping_1.png")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -77,7 +82,7 @@ function order_favorite_list(list)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function render_favorite(spec, is_favorite)
|
||||
function render_serverlist_row(spec, is_favorite)
|
||||
local text = ""
|
||||
if spec.name then
|
||||
text = text .. core.formspec_escape(spec.name:trim())
|
||||
@@ -97,6 +102,21 @@ function render_favorite(spec, is_favorite)
|
||||
details = "0,"
|
||||
end
|
||||
|
||||
if spec.ping then
|
||||
local ping = spec.ping * 1000
|
||||
if ping <= 50 then
|
||||
details = details .. "2,"
|
||||
elseif ping <= 100 then
|
||||
details = details .. "3,"
|
||||
elseif ping <= 250 then
|
||||
details = details .. "4,"
|
||||
else
|
||||
details = details .. "5,"
|
||||
end
|
||||
else
|
||||
details = details .. "0,"
|
||||
end
|
||||
|
||||
if spec.clients and spec.clients_max then
|
||||
local clients_color = ''
|
||||
local clients_percent = 100 * spec.clients / spec.clients_max
|
||||
@@ -144,8 +164,8 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
os.tempfolder = function()
|
||||
if core.setting_get("TMPFolder") then
|
||||
return core.setting_get("TMPFolder") .. DIR_DELIM .. "MT_" .. math.random(0,10000)
|
||||
if core.settings:get("TMPFolder") then
|
||||
return core.settings:get("TMPFolder") .. DIR_DELIM .. "MT_" .. math.random(0,10000)
|
||||
end
|
||||
|
||||
local filetocheck = os.tmpname()
|
||||
@@ -186,7 +206,7 @@ function menu_handle_key_up_down(fields, textlist, settingname)
|
||||
oldidx < menudata.worldlist:size() then
|
||||
newidx = oldidx + 1
|
||||
end
|
||||
core.setting_set(settingname, menudata.worldlist:get_raw_index(newidx))
|
||||
core.settings:set(settingname, menudata.worldlist:get_raw_index(newidx))
|
||||
configure_selected_world_params(newidx)
|
||||
return true
|
||||
end
|
||||
@@ -230,7 +250,7 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency)
|
||||
local textlines = core.splittext(text, textlen)
|
||||
local textlines = core.wrap_text(text, textlen)
|
||||
local retval = "textlist[" .. xpos .. "," .. ypos .. ";" .. width ..
|
||||
"," .. height .. ";" .. tl_name .. ";"
|
||||
|
||||
@@ -248,14 +268,18 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function is_server_protocol_compat(server_proto_min, server_proto_max)
|
||||
return min_supp_proto <= (server_proto_max or 24) and max_supp_proto >= (server_proto_min or 13)
|
||||
if (not server_proto_min) or (not server_proto_max) then
|
||||
-- There is no info. Assume the best and act as if we would be compatible.
|
||||
return true
|
||||
end
|
||||
return min_supp_proto <= server_proto_max and max_supp_proto >= server_proto_min
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
function is_server_protocol_compat_or_error(server_proto_min, server_proto_max)
|
||||
if not is_server_protocol_compat(server_proto_min, server_proto_max) then
|
||||
local server_prot_ver_info, client_prot_ver_info
|
||||
local s_p_min = server_proto_min or 13
|
||||
local s_p_max = server_proto_max or 24
|
||||
local s_p_min = server_proto_min
|
||||
local s_p_max = server_proto_max
|
||||
|
||||
if s_p_min ~= s_p_max then
|
||||
server_prot_ver_info = fgettext_ne("Server supports protocol versions between $1 and $2. ",
|
||||
@@ -304,9 +328,9 @@ function menu_worldmt_legacy(selected)
|
||||
for _, mode_name in pairs(modes_names) do
|
||||
local mode_val = menu_worldmt(selected, mode_name)
|
||||
if mode_val then
|
||||
core.setting_set(mode_name, mode_val)
|
||||
core.settings:set(mode_name, mode_val)
|
||||
else
|
||||
menu_worldmt(selected, mode_name, core.setting_get(mode_name))
|
||||
menu_worldmt(selected, mode_name, core.settings:get(mode_name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local enabled_all = false
|
||||
|
||||
local function modname_valid(name)
|
||||
return not name:find("[^a-z0-9_]")
|
||||
end
|
||||
|
||||
local function get_formspec(data)
|
||||
|
||||
local mod = data.list:get_list()[data.selected_mod]
|
||||
|
||||
local retval =
|
||||
@@ -29,62 +31,63 @@ local function get_formspec(data)
|
||||
"label[0.5,0;" .. fgettext("World:") .. "]" ..
|
||||
"label[1.75,0;" .. data.worldspec.name .. "]"
|
||||
|
||||
if data.hide_gamemods then
|
||||
retval = retval .. "checkbox[1,6;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";true]"
|
||||
else
|
||||
retval = retval .. "checkbox[1,6;cb_hide_gamemods;" .. fgettext("Hide Game") .. ";false]"
|
||||
end
|
||||
|
||||
if data.hide_modpackcontents then
|
||||
retval = retval .. "checkbox[6,6;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";true]"
|
||||
else
|
||||
retval = retval .. "checkbox[6,6;cb_hide_mpcontent;" .. fgettext("Hide mp content") .. ";false]"
|
||||
end
|
||||
|
||||
if mod == nil then
|
||||
mod = {name=""}
|
||||
end
|
||||
|
||||
|
||||
local hard_deps, soft_deps = modmgr.get_dependencies(mod.path)
|
||||
|
||||
retval = retval ..
|
||||
"label[0,0.7;" .. fgettext("Mod:") .. "]" ..
|
||||
"label[0.75,0.7;" .. mod.name .. "]" ..
|
||||
"label[0,1.25;" .. fgettext("Depends:") .. "]" ..
|
||||
"textlist[0,1.75;5,4.25;world_config_depends;" ..
|
||||
modmgr.get_dependencies(mod.path) .. ";0]" ..
|
||||
"label[0,1.25;" .. fgettext("Dependencies:") .. "]" ..
|
||||
"textlist[0,1.75;5,2.125;world_config_depends;" ..
|
||||
hard_deps .. ";0]" ..
|
||||
"label[0,3.875;" .. fgettext("Optional dependencies:") .. "]" ..
|
||||
"textlist[0,4.375;5,1.8;world_config_optdepends;" ..
|
||||
soft_deps .. ";0]" ..
|
||||
"button[3.25,7;2.5,0.5;btn_config_world_save;" .. fgettext("Save") .. "]" ..
|
||||
"button[5.75,7;2.5,0.5;btn_config_world_cancel;" .. fgettext("Cancel") .. "]"
|
||||
|
||||
if mod ~= nil and mod.name ~= "" and mod.typ ~= "game_mod" then
|
||||
if mod and mod.name ~= "" and not mod.is_game_content then
|
||||
if mod.is_modpack then
|
||||
local rawlist = data.list:get_raw_list()
|
||||
|
||||
local all_enabled = true
|
||||
for j=1,#rawlist,1 do
|
||||
if rawlist[j].modpack == mod.name and
|
||||
rawlist[j].enabled ~= true then
|
||||
all_enabled = false
|
||||
break
|
||||
for j = 1, #rawlist, 1 do
|
||||
if rawlist[j].modpack == mod.name and not rawlist[j].enabled then
|
||||
all_enabled = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if all_enabled == false then
|
||||
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_enable;" .. fgettext("Enable MP") .. "]"
|
||||
if all_enabled then
|
||||
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_disable;" ..
|
||||
fgettext("Disable MP") .. "]"
|
||||
else
|
||||
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_disable;" .. fgettext("Disable MP") .. "]"
|
||||
retval = retval .. "button[5.5,0.125;2.5,0.5;btn_mp_enable;" ..
|
||||
fgettext("Enable MP") .. "]"
|
||||
end
|
||||
else
|
||||
if mod.enabled then
|
||||
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") .. ";true]"
|
||||
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" ..
|
||||
fgettext("enabled") .. ";true]"
|
||||
else
|
||||
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" .. fgettext("enabled") .. ";false]"
|
||||
retval = retval .. "checkbox[5.5,-0.125;cb_mod_enable;" ..
|
||||
fgettext("enabled") .. ";false]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if enabled_all then
|
||||
retval = retval ..
|
||||
"button[8.75,0.125;2.5,0.5;btn_disable_all_mods;" .. fgettext("Disable all") .. "]"
|
||||
else
|
||||
retval = retval ..
|
||||
"button[8.75,0.125;2.5,0.5;btn_enable_all_mods;" .. fgettext("Enable all") .. "]"
|
||||
end
|
||||
retval = retval ..
|
||||
"button[8.75,0.125;2.5,0.5;btn_all_mods;" .. fgettext("Enable all") .. "]" ..
|
||||
"textlist[5.5,0.75;5.75,5.25;world_config_modlist;"
|
||||
|
||||
"tablecolumns[color;tree;text]" ..
|
||||
"table[5.5,0.75;5.75,6;world_config_modlist;"
|
||||
retval = retval .. modmgr.render_modlist(data.list)
|
||||
retval = retval .. ";" .. data.selected_mod .."]"
|
||||
|
||||
@@ -94,7 +97,7 @@ end
|
||||
local function enable_mod(this, toset)
|
||||
local mod = this.data.list:get_list()[this.data.selected_mod]
|
||||
|
||||
if mod.typ == "game_mod" then
|
||||
if mod.is_game_content then
|
||||
-- game mods can't be enabled or disabled
|
||||
elseif not mod.is_modpack then
|
||||
if toset == nil then
|
||||
@@ -117,16 +120,15 @@ end
|
||||
|
||||
|
||||
local function handle_buttons(this, fields)
|
||||
|
||||
if fields["world_config_modlist"] ~= nil then
|
||||
local event = core.explode_textlist_event(fields["world_config_modlist"])
|
||||
this.data.selected_mod = event.index
|
||||
core.setting_set("world_config_selected_mod", event.index)
|
||||
local event = core.explode_table_event(fields["world_config_modlist"])
|
||||
this.data.selected_mod = event.row
|
||||
core.settings:set("world_config_selected_mod", event.row)
|
||||
|
||||
if event.type == "DCL" then
|
||||
enable_mod(this)
|
||||
end
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -148,44 +150,7 @@ local function handle_buttons(this, fields)
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_hide_gamemods"] ~= nil or
|
||||
fields["cb_hide_mpcontent"] ~= nil then
|
||||
local current = this.data.list:get_filtercriteria()
|
||||
|
||||
if current == nil then
|
||||
current = {}
|
||||
end
|
||||
|
||||
if fields["cb_hide_gamemods"] ~= nil then
|
||||
if core.is_yes(fields["cb_hide_gamemods"]) then
|
||||
current.hide_game = true
|
||||
this.data.hide_gamemods = true
|
||||
core.setting_set("world_config_hide_gamemods", "true")
|
||||
else
|
||||
current.hide_game = false
|
||||
this.data.hide_gamemods = false
|
||||
core.setting_set("world_config_hide_gamemods", "false")
|
||||
end
|
||||
end
|
||||
|
||||
if fields["cb_hide_mpcontent"] ~= nil then
|
||||
if core.is_yes(fields["cb_hide_mpcontent"]) then
|
||||
current.hide_modpackcontents = true
|
||||
this.data.hide_modpackcontents = true
|
||||
core.setting_set("world_config_hide_modpackcontents", "true")
|
||||
else
|
||||
current.hide_modpackcontents = false
|
||||
this.data.hide_modpackcontents = false
|
||||
core.setting_set("world_config_hide_modpackcontents", "false")
|
||||
end
|
||||
end
|
||||
|
||||
this.data.list:set_filtercriteria(current)
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_config_world_save"] then
|
||||
|
||||
local filename = this.data.worldspec.path ..
|
||||
DIR_DELIM .. "world.mt"
|
||||
|
||||
@@ -197,7 +162,7 @@ local function handle_buttons(this, fields)
|
||||
local i,mod
|
||||
for i,mod in ipairs(rawlist) do
|
||||
if not mod.is_modpack and
|
||||
mod.typ ~= "game_mod" then
|
||||
not mod.is_game_content then
|
||||
if modname_valid(mod.name) then
|
||||
worldfile:set("load_mod_"..mod.name, tostring(mod.enabled))
|
||||
else
|
||||
@@ -219,7 +184,7 @@ local function handle_buttons(this, fields)
|
||||
if not worldfile:write() then
|
||||
core.log("error", "Failed to write world config file")
|
||||
end
|
||||
|
||||
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
@@ -229,15 +194,29 @@ local function handle_buttons(this, fields)
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_all_mods"] then
|
||||
if fields.btn_enable_all_mods then
|
||||
local list = this.data.list:get_raw_list()
|
||||
|
||||
for i=1,#list,1 do
|
||||
if list[i].typ ~= "game_mod" and
|
||||
not list[i].is_modpack then
|
||||
for i = 1, #list do
|
||||
if not list[i].is_game_content
|
||||
and not list[i].is_modpack then
|
||||
list[i].enabled = true
|
||||
end
|
||||
end
|
||||
enabled_all = true
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.btn_disable_all_mods then
|
||||
local list = this.data.list:get_raw_list()
|
||||
|
||||
for i = 1, #list do
|
||||
if not list[i].is_game_content
|
||||
and not list[i].is_modpack then
|
||||
list[i].enabled = false
|
||||
end
|
||||
end
|
||||
enabled_all = false
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -245,15 +224,12 @@ local function handle_buttons(this, fields)
|
||||
end
|
||||
|
||||
function create_configure_world_dlg(worldidx)
|
||||
|
||||
local dlg = dialog_create("sp_config_world",
|
||||
get_formspec,
|
||||
handle_buttons,
|
||||
nil)
|
||||
|
||||
dlg.data.hide_gamemods = core.setting_getbool("world_config_hide_gamemods")
|
||||
dlg.data.hide_modpackcontents = core.setting_getbool("world_config_hide_modpackcontents")
|
||||
dlg.data.selected_mod = tonumber(core.setting_get("world_config_selected_mod"))
|
||||
dlg.data.selected_mod = tonumber(core.settings:get("world_config_selected_mod"))
|
||||
if dlg.data.selected_mod == nil then
|
||||
dlg.data.selected_mod = 0
|
||||
end
|
||||
@@ -262,14 +238,14 @@ function create_configure_world_dlg(worldidx)
|
||||
if dlg.data.worldspec == nil then dlg:delete() return nil end
|
||||
|
||||
dlg.data.worldconfig = modmgr.get_worldconfig(dlg.data.worldspec.path)
|
||||
|
||||
|
||||
if dlg.data.worldconfig == nil or dlg.data.worldconfig.id == nil or
|
||||
dlg.data.worldconfig.id == "" then
|
||||
|
||||
dlg:delete()
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
dlg.data.list = filterlist.create(
|
||||
modmgr.preparemodlist, --refresh
|
||||
modmgr.comparemod, --compare
|
||||
@@ -278,16 +254,16 @@ function create_configure_world_dlg(worldidx)
|
||||
return true
|
||||
end
|
||||
end,
|
||||
function(element,criteria)
|
||||
function(element, criteria)
|
||||
if criteria.hide_game and
|
||||
element.typ == "game_mod" then
|
||||
return false
|
||||
element.is_game_content then
|
||||
return false
|
||||
end
|
||||
|
||||
if criteria.hide_modpackcontents and
|
||||
element.modpack ~= nil then
|
||||
return false
|
||||
end
|
||||
element.modpack ~= nil then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end, --filter
|
||||
{ worldpath= dlg.data.worldspec.path,
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
local function create_world_formspec(dialogdata)
|
||||
local mapgens = core.get_mapgen_names()
|
||||
|
||||
local current_seed = core.setting_get("fixed_map_seed") or ""
|
||||
local current_mg = core.setting_get("mg_name")
|
||||
local current_seed = core.settings:get("fixed_map_seed") or ""
|
||||
local current_mg = core.settings:get("mg_name")
|
||||
|
||||
local mglist = ""
|
||||
local selindex = 1
|
||||
@@ -33,7 +33,7 @@ local function create_world_formspec(dialogdata)
|
||||
end
|
||||
mglist = mglist:sub(1, -2)
|
||||
|
||||
local gameid = core.setting_get("menu_last_game")
|
||||
local gameid = core.settings:get("menu_last_game")
|
||||
|
||||
local game, gameidx = nil , 0
|
||||
if gameid ~= nil then
|
||||
@@ -90,10 +90,10 @@ local function create_world_buttonhandler(this, fields)
|
||||
|
||||
local message = nil
|
||||
|
||||
core.setting_set("fixed_map_seed", fields["te_seed"])
|
||||
core.settings:set("fixed_map_seed", fields["te_seed"])
|
||||
|
||||
if not menudata.worldlist:uid_exists_raw(worldname) then
|
||||
core.setting_set("mg_name",fields["dd_mapgen"])
|
||||
core.settings:set("mg_name",fields["dd_mapgen"])
|
||||
message = core.create_world(worldname,gameindex)
|
||||
else
|
||||
message = fgettext("A world named \"$1\" already exists", worldname)
|
||||
@@ -102,13 +102,13 @@ local function create_world_buttonhandler(this, fields)
|
||||
if message ~= nil then
|
||||
gamedata.errormessage = message
|
||||
else
|
||||
core.setting_set("menu_last_game",gamemgr.games[gameindex].id)
|
||||
core.settings:set("menu_last_game",gamemgr.games[gameindex].id)
|
||||
if this.data.update_worldlist_filter then
|
||||
menudata.worldlist:set_filtercriteria(gamemgr.games[gameindex].id)
|
||||
mm_texture.update("singleplayer", gamemgr.games[gameindex].id)
|
||||
end
|
||||
menudata.worldlist:refresh()
|
||||
core.setting_set("mainmenu_last_selected_world",
|
||||
core.settings:set("mainmenu_last_selected_world",
|
||||
menudata.worldlist:raw_index_by_uid(worldname))
|
||||
end
|
||||
else
|
||||
|
||||
@@ -344,11 +344,86 @@ local function parse_config_file(read_all, parse_mods)
|
||||
return settings
|
||||
end
|
||||
|
||||
local settings = parse_config_file(false, true)
|
||||
local function filter_settings(settings, searchstring)
|
||||
if not searchstring or searchstring == "" then
|
||||
return settings, -1
|
||||
end
|
||||
|
||||
-- Setup the keyword list
|
||||
local keywords = {}
|
||||
for word in searchstring:lower():gmatch("%S+") do
|
||||
table.insert(keywords, word)
|
||||
end
|
||||
|
||||
local result = {}
|
||||
local category_stack = {}
|
||||
local current_level = 0
|
||||
local best_setting = nil
|
||||
for _, entry in pairs(settings) do
|
||||
if entry.type == "category" then
|
||||
-- Remove all settingless categories
|
||||
while #category_stack > 0 and entry.level <= current_level do
|
||||
table.remove(category_stack, #category_stack)
|
||||
if #category_stack > 0 then
|
||||
current_level = category_stack[#category_stack].level
|
||||
else
|
||||
current_level = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- Push category onto stack
|
||||
category_stack[#category_stack + 1] = entry
|
||||
current_level = entry.level
|
||||
else
|
||||
-- See if setting matches keywords
|
||||
local setting_score = 0
|
||||
for k = 1, #keywords do
|
||||
local keyword = keywords[k]
|
||||
|
||||
if string.find(entry.name:lower(), keyword, 1, true) then
|
||||
setting_score = setting_score + 1
|
||||
end
|
||||
|
||||
if entry.readable_name and
|
||||
string.find(fgettext(entry.readable_name):lower(), keyword, 1, true) then
|
||||
setting_score = setting_score + 1
|
||||
end
|
||||
|
||||
if entry.comment and
|
||||
string.find(fgettext_ne(entry.comment):lower(), keyword, 1, true) then
|
||||
setting_score = setting_score + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Add setting to results if match
|
||||
if setting_score > 0 then
|
||||
-- Add parent categories
|
||||
for _, category in pairs(category_stack) do
|
||||
result[#result + 1] = category
|
||||
end
|
||||
category_stack = {}
|
||||
|
||||
-- Add setting
|
||||
result[#result + 1] = entry
|
||||
entry.score = setting_score
|
||||
|
||||
if not best_setting or
|
||||
setting_score > result[best_setting].score then
|
||||
best_setting = #result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return result, best_setting or -1
|
||||
end
|
||||
|
||||
local full_settings = parse_config_file(false, true)
|
||||
local search_string = ""
|
||||
local settings = full_settings
|
||||
local selected_setting = 1
|
||||
|
||||
local function get_current_value(setting)
|
||||
local value = core.setting_get(setting.name)
|
||||
local value = core.settings:get(setting.name)
|
||||
if value == nil then
|
||||
value = setting.default
|
||||
end
|
||||
@@ -464,11 +539,11 @@ local function handle_change_setting_buttons(this, fields)
|
||||
if setting.type == "bool" then
|
||||
local new_value = fields["dd_setting_value"]
|
||||
-- Note: new_value is the actual (translated) value shown in the dropdown
|
||||
core.setting_setbool(setting.name, new_value == fgettext("Enabled"))
|
||||
core.settings:set_bool(setting.name, new_value == fgettext("Enabled"))
|
||||
|
||||
elseif setting.type == "enum" then
|
||||
local new_value = fields["dd_setting_value"]
|
||||
core.setting_set(setting.name, new_value)
|
||||
core.settings:set(setting.name, new_value)
|
||||
|
||||
elseif setting.type == "int" then
|
||||
local new_value = tonumber(fields["te_setting_value"])
|
||||
@@ -479,18 +554,18 @@ local function handle_change_setting_buttons(this, fields)
|
||||
return true
|
||||
end
|
||||
if setting.min and new_value < setting.min then
|
||||
this.data.error_message = fgettext_ne("The value must be greater than $1.", setting.min)
|
||||
this.data.error_message = fgettext_ne("The value must be at least $1.", setting.min)
|
||||
this.data.entered_text = fields["te_setting_value"]
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
if setting.max and new_value > setting.max then
|
||||
this.data.error_message = fgettext_ne("The value must be lower than $1.", setting.max)
|
||||
this.data.error_message = fgettext_ne("The value must not be larger than $1.", setting.max)
|
||||
this.data.entered_text = fields["te_setting_value"]
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
core.setting_set(setting.name, new_value)
|
||||
core.settings:set(setting.name, new_value)
|
||||
|
||||
elseif setting.type == "float" then
|
||||
local new_value = tonumber(fields["te_setting_value"])
|
||||
@@ -500,7 +575,7 @@ local function handle_change_setting_buttons(this, fields)
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
core.setting_set(setting.name, new_value)
|
||||
core.settings:set(setting.name, new_value)
|
||||
|
||||
elseif setting.type == "flags" then
|
||||
local new_value = fields["te_setting_value"]
|
||||
@@ -514,13 +589,13 @@ local function handle_change_setting_buttons(this, fields)
|
||||
return true
|
||||
end
|
||||
end
|
||||
core.setting_set(setting.name, new_value)
|
||||
core.settings:set(setting.name, new_value)
|
||||
|
||||
else
|
||||
local new_value = fields["te_setting_value"]
|
||||
core.setting_set(setting.name, new_value)
|
||||
core.settings:set(setting.name, new_value)
|
||||
end
|
||||
core.setting_save()
|
||||
core.settings:write()
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
@@ -544,14 +619,17 @@ end
|
||||
|
||||
local function create_settings_formspec(tabview, name, tabdata)
|
||||
local formspec = "size[12,6.5;true]" ..
|
||||
"tablecolumns[color;tree;text;text]" ..
|
||||
"tablecolumns[color;tree;text,width=32;text]" ..
|
||||
"tableoptions[background=#00000000;border=false]" ..
|
||||
"table[0,0;12,5.5;list_settings;"
|
||||
"field[0.3,0.1;10.2,1;search_string;;" .. core.formspec_escape(search_string) .. "]" ..
|
||||
"field_close_on_enter[search_string;false]" ..
|
||||
"button[10.2,-0.2;2,1;search;" .. fgettext("Search") .. "]" ..
|
||||
"table[0,0.8;12,4.5;list_settings;"
|
||||
|
||||
local current_level = 0
|
||||
for _, entry in ipairs(settings) do
|
||||
local name
|
||||
if not core.setting_getbool("main_menu_technical_settings") and entry.readable_name then
|
||||
if not core.settings:get_bool("main_menu_technical_settings") and entry.readable_name then
|
||||
name = fgettext_ne(entry.readable_name)
|
||||
else
|
||||
name = entry.name
|
||||
@@ -588,7 +666,7 @@ local function create_settings_formspec(tabview, name, tabdata)
|
||||
"button[10,6;2,1;btn_edit;" .. fgettext("Edit") .. "]" ..
|
||||
"button[7,6;3,1;btn_restore;" .. fgettext("Restore Default") .. "]" ..
|
||||
"checkbox[0,5.3;cb_tech_settings;" .. fgettext("Show technical names") .. ";"
|
||||
.. dump(core.setting_getbool("main_menu_technical_settings")) .. "]"
|
||||
.. dump(core.settings:get_bool("main_menu_technical_settings")) .. "]"
|
||||
|
||||
return formspec
|
||||
end
|
||||
@@ -597,13 +675,13 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||
local list_enter = false
|
||||
if fields["list_settings"] then
|
||||
selected_setting = core.get_table_index("list_settings")
|
||||
if core.explode_table_event(fields["list_settings"]).type == "DCL" then
|
||||
if core.explode_table_event(fields["list_settings"]).type == "DCL" then
|
||||
-- Directly toggle booleans
|
||||
local setting = settings[selected_setting]
|
||||
if setting.type == "bool" then
|
||||
if setting and setting.type == "bool" then
|
||||
local current_value = get_current_value(setting)
|
||||
core.setting_setbool(setting.name, not core.is_yes(current_value))
|
||||
core.setting_save()
|
||||
core.settings:set_bool(setting.name, not core.is_yes(current_value))
|
||||
core.settings:write()
|
||||
return true
|
||||
else
|
||||
list_enter = true
|
||||
@@ -613,9 +691,39 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||
end
|
||||
end
|
||||
|
||||
if fields.search or fields.key_enter_field == "search_string" then
|
||||
if search_string == fields.search_string then
|
||||
if selected_setting > 0 then
|
||||
-- Go to next result on enter press
|
||||
local i = selected_setting + 1
|
||||
local looped = false
|
||||
while i > #settings or settings[i].type == "category" do
|
||||
i = i + 1
|
||||
if i > #settings then
|
||||
-- Stop infinte looping
|
||||
if looped then
|
||||
return false
|
||||
end
|
||||
i = 1
|
||||
looped = true
|
||||
end
|
||||
end
|
||||
selected_setting = i
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
else
|
||||
-- Search for setting
|
||||
search_string = fields.search_string
|
||||
settings, selected_setting = filter_settings(full_settings, search_string)
|
||||
core.update_formspec(this:get_formspec())
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["btn_edit"] or list_enter then
|
||||
local setting = settings[selected_setting]
|
||||
if setting.type ~= "category" then
|
||||
if setting and setting.type ~= "category" then
|
||||
local edit_dialog = dialog_create("change_setting", create_change_setting_formspec,
|
||||
handle_change_setting_buttons)
|
||||
edit_dialog:set_parent(this)
|
||||
@@ -627,9 +735,9 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||
|
||||
if fields["btn_restore"] then
|
||||
local setting = settings[selected_setting]
|
||||
if setting.type ~= "category" then
|
||||
core.setting_set(setting.name, setting.default)
|
||||
core.setting_save()
|
||||
if setting and setting.type ~= "category" then
|
||||
core.settings:set(setting.name, setting.default)
|
||||
core.settings:write()
|
||||
core.update_formspec(this:get_formspec())
|
||||
end
|
||||
return true
|
||||
@@ -641,8 +749,8 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||
end
|
||||
|
||||
if fields["cb_tech_settings"] then
|
||||
core.setting_set("main_menu_technical_settings", fields["cb_tech_settings"])
|
||||
core.setting_save()
|
||||
core.settings:set("main_menu_technical_settings", fields["cb_tech_settings"])
|
||||
core.settings:write()
|
||||
core.update_formspec(this:get_formspec())
|
||||
return true
|
||||
end
|
||||
@@ -659,102 +767,6 @@ function create_adv_settings_dlg()
|
||||
return dlg
|
||||
end
|
||||
|
||||
local function create_minetest_conf_example()
|
||||
local result = "# This file contains a list of all available settings and their default value for minetest.conf\n" ..
|
||||
"\n" ..
|
||||
"# By default, all the settings are commented and not functional.\n" ..
|
||||
"# Uncomment settings by removing the preceding #.\n" ..
|
||||
"\n" ..
|
||||
"# minetest.conf is read by default from:\n" ..
|
||||
"# ../minetest.conf\n" ..
|
||||
"# ../../minetest.conf\n" ..
|
||||
"# Any other path can be chosen by passing the path as a parameter\n" ..
|
||||
"# to the program, eg. \"minetest.exe --config ../minetest.conf.example\".\n" ..
|
||||
"\n" ..
|
||||
"# Further documentation:\n" ..
|
||||
"# http://wiki.minetest.net/\n" ..
|
||||
"\n"
|
||||
-- Generate minetest.conf.example and settings_translation_file.cpp
|
||||
|
||||
local settings = parse_config_file(true, false)
|
||||
for _, entry in ipairs(settings) do
|
||||
if entry.type == "category" then
|
||||
if entry.level == 0 then
|
||||
result = result .. "#\n# " .. entry.name .. "\n#\n\n"
|
||||
else
|
||||
for i = 1, entry.level do
|
||||
result = result .. "#"
|
||||
end
|
||||
result = result .. "# " .. entry.name .. "\n\n"
|
||||
end
|
||||
else
|
||||
if entry.comment ~= "" then
|
||||
for _, comment_line in ipairs(entry.comment:split("\n", true)) do
|
||||
result = result .."# " .. comment_line .. "\n"
|
||||
end
|
||||
end
|
||||
result = result .. "# type: " .. entry.type
|
||||
if entry.min then
|
||||
result = result .. " min: " .. entry.min
|
||||
end
|
||||
if entry.max then
|
||||
result = result .. " max: " .. entry.max
|
||||
end
|
||||
if entry.values then
|
||||
result = result .. " values: " .. table.concat(entry.values, ", ")
|
||||
end
|
||||
if entry.possible then
|
||||
result = result .. " possible values: " .. entry.possible:gsub(",", ", ")
|
||||
end
|
||||
result = result .. "\n"
|
||||
local append = ""
|
||||
if entry.default ~= "" then
|
||||
append = " " .. entry.default
|
||||
end
|
||||
result = result .. "# " .. entry.name .. " =" .. append .. "\n\n"
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local function create_translation_file()
|
||||
local result = "// This file is automatically generated\n" ..
|
||||
"// It conatins a bunch of fake gettext calls, to tell xgettext about the strings in config files\n" ..
|
||||
"// To update it, refer to the bottom of builtin/mainmenu/tab_settings.lua\n\n" ..
|
||||
"fake_function() {\n"
|
||||
|
||||
local settings = parse_config_file(true, false)
|
||||
for _, entry in ipairs(settings) do
|
||||
if entry.type == "category" then
|
||||
local name_escaped = entry.name:gsub("\"", "\\\"")
|
||||
result = result .. "\tgettext(\"" .. name_escaped .. "\");\n"
|
||||
else
|
||||
if entry.readable_name then
|
||||
local readable_name_escaped = entry.readable_name:gsub("\"", "\\\"")
|
||||
result = result .. "\tgettext(\"" .. readable_name_escaped .. "\");\n"
|
||||
end
|
||||
if entry.comment ~= "" then
|
||||
local comment_escaped = entry.comment:gsub("\n", "\\n")
|
||||
comment_escaped = comment_escaped:gsub("\"", "\\\"")
|
||||
result = result .. "\tgettext(\"" .. comment_escaped .. "\");\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
result = result .. "}\n"
|
||||
return result
|
||||
end
|
||||
|
||||
if false then
|
||||
local file = io.open("minetest.conf.example", "w")
|
||||
if file then
|
||||
file:write(create_minetest_conf_example())
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
if false then
|
||||
local file = io.open("src/settings_translation_file.cpp", "w")
|
||||
if file then
|
||||
file:write(create_translation_file())
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
--assert(loadfile(core.get_builtin_path()..DIR_DELIM.."mainmenu"..DIR_DELIM.."generate_from_settingtypes.lua"))(parse_config_file(true, false))
|
||||
|
||||
@@ -68,10 +68,10 @@ end
|
||||
function gamemgr.gamelist()
|
||||
local retval = ""
|
||||
if #gamemgr.games > 0 then
|
||||
retval = retval .. gamemgr.games[1].name
|
||||
retval = retval .. core.formspec_escape(gamemgr.games[1].name)
|
||||
|
||||
for i=2,#gamemgr.games,1 do
|
||||
retval = retval .. "," .. gamemgr.games[i].name
|
||||
retval = retval .. "," .. core.formspec_escape(gamemgr.games[i].name)
|
||||
end
|
||||
end
|
||||
return retval
|
||||
|
||||
99
builtin/mainmenu/generate_from_settingtypes.lua
Normal file
99
builtin/mainmenu/generate_from_settingtypes.lua
Normal file
@@ -0,0 +1,99 @@
|
||||
local settings = ...
|
||||
|
||||
local concat = table.concat
|
||||
local insert = table.insert
|
||||
local sprintf = string.format
|
||||
local rep = string.rep
|
||||
|
||||
local minetest_example_header = [[
|
||||
# This file contains a list of all available settings and their default value for minetest.conf
|
||||
|
||||
# By default, all the settings are commented and not functional.
|
||||
# Uncomment settings by removing the preceding #.
|
||||
|
||||
# minetest.conf is read by default from:
|
||||
# ../minetest.conf
|
||||
# ../../minetest.conf
|
||||
# Any other path can be chosen by passing the path as a parameter
|
||||
# to the program, eg. "minetest.exe --config ../minetest.conf.example".
|
||||
|
||||
# Further documentation:
|
||||
# http://wiki.minetest.net/
|
||||
|
||||
]]
|
||||
|
||||
local function create_minetest_conf_example()
|
||||
local result = { minetest_example_header }
|
||||
for _, entry in ipairs(settings) do
|
||||
if entry.type == "category" then
|
||||
if entry.level == 0 then
|
||||
insert(result, "#\n# " .. entry.name .. "\n#\n\n")
|
||||
else
|
||||
insert(result, rep("#", entry.level))
|
||||
insert(result, "# " .. entry.name .. "\n\n")
|
||||
end
|
||||
else
|
||||
if entry.comment ~= "" then
|
||||
for _, comment_line in ipairs(entry.comment:split("\n", true)) do
|
||||
insert(result, "# " .. comment_line .. "\n")
|
||||
end
|
||||
end
|
||||
insert(result, "# type: " .. entry.type)
|
||||
if entry.min then
|
||||
insert(result, " min: " .. entry.min)
|
||||
end
|
||||
if entry.max then
|
||||
insert(result, " max: " .. entry.max)
|
||||
end
|
||||
if entry.values then
|
||||
insert(result, " values: " .. concat(entry.values, ", "))
|
||||
end
|
||||
if entry.possible then
|
||||
insert(result, " possible values: " .. entry.possible:gsub(",", ", "))
|
||||
end
|
||||
insert(result, "\n")
|
||||
local append
|
||||
if entry.default ~= "" then
|
||||
append = " " .. entry.default
|
||||
end
|
||||
insert(result, sprintf("# %s =%s\n\n", entry.name, append or ""))
|
||||
end
|
||||
end
|
||||
return concat(result)
|
||||
end
|
||||
|
||||
local translation_file_header = [[
|
||||
// This file is automatically generated
|
||||
// It conatins a bunch of fake gettext calls, to tell xgettext about the strings in config files
|
||||
// To update it, refer to the bottom of builtin/mainmenu/dlg_settings_advanced.lua
|
||||
|
||||
fake_function() {]]
|
||||
|
||||
local function create_translation_file()
|
||||
local result = { translation_file_header }
|
||||
for _, entry in ipairs(settings) do
|
||||
if entry.type == "category" then
|
||||
insert(result, sprintf("\tgettext(%q);", entry.name))
|
||||
else
|
||||
if entry.readable_name then
|
||||
insert(result, sprintf("\tgettext(%q);", entry.readable_name))
|
||||
end
|
||||
if entry.comment ~= "" then
|
||||
local comment_escaped = entry.comment:gsub("\n", "\\n")
|
||||
comment_escaped = comment_escaped:gsub("\"", "\\\"")
|
||||
insert(result, "\tgettext(\"" .. comment_escaped .. "\");")
|
||||
end
|
||||
end
|
||||
end
|
||||
insert(result, "}\n")
|
||||
return concat(result, "\n")
|
||||
end
|
||||
|
||||
local file = assert(io.open("minetest.conf.example", "w"))
|
||||
file:write(create_minetest_conf_example())
|
||||
file:close()
|
||||
|
||||
file = assert(io.open("src/settings_translation_file.cpp", "w"))
|
||||
file:write(create_translation_file())
|
||||
file:close()
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
mt_color_grey = "#AAAAAA"
|
||||
mt_color_blue = "#0000DD"
|
||||
mt_color_green = "#00DD00"
|
||||
mt_color_dark_green = "#003300"
|
||||
mt_color_blue = "#6389FF"
|
||||
mt_color_green = "#72FF63"
|
||||
mt_color_dark_green = "#25C191"
|
||||
|
||||
--for all other colors ask sfan5 to complete his work!
|
||||
|
||||
@@ -56,9 +56,8 @@ tabs.credits = dofile(menupath .. DIR_DELIM .. "tab_credits.lua")
|
||||
if PLATFORM == "Android" then
|
||||
tabs.simple_main = dofile(menupath .. DIR_DELIM .. "tab_simple_main.lua")
|
||||
else
|
||||
tabs.singleplayer = dofile(menupath .. DIR_DELIM .. "tab_singleplayer.lua")
|
||||
tabs.multiplayer = dofile(menupath .. DIR_DELIM .. "tab_multiplayer.lua")
|
||||
tabs.server = dofile(menupath .. DIR_DELIM .. "tab_server.lua")
|
||||
tabs.local_game = dofile(menupath .. DIR_DELIM .. "tab_local.lua")
|
||||
tabs.play_online = dofile(menupath .. DIR_DELIM .. "tab_online.lua")
|
||||
tabs.texturepacks = dofile(menupath .. DIR_DELIM .. "tab_texturepacks.lua")
|
||||
end
|
||||
|
||||
@@ -119,25 +118,24 @@ local function init_globals()
|
||||
menudata.worldlist:add_sort_mechanism("alphabetic", sort_worlds_alphabetic)
|
||||
menudata.worldlist:set_sortmode("alphabetic")
|
||||
|
||||
if not core.setting_get("menu_last_game") then
|
||||
local default_game = core.setting_get("default_game") or "minetest"
|
||||
core.setting_set("menu_last_game", default_game)
|
||||
if not core.settings:get("menu_last_game") then
|
||||
local default_game = core.settings:get("default_game") or "minetest"
|
||||
core.settings:set("menu_last_game", default_game)
|
||||
end
|
||||
|
||||
mm_texture.init()
|
||||
end
|
||||
|
||||
-- Create main tabview
|
||||
local tv_main = tabview_create("maintab", {x = 12, y = 5.2}, {x = 0, y = 0})
|
||||
local tv_main = tabview_create("maintab", {x = 12, y = 5.4}, {x = 0, y = 0})
|
||||
|
||||
if PLATFORM == "Android" then
|
||||
tv_main:add(tabs.simple_main)
|
||||
tv_main:add(tabs.settings)
|
||||
else
|
||||
tv_main:set_autosave_tab(true)
|
||||
tv_main:add(tabs.singleplayer)
|
||||
tv_main:add(tabs.multiplayer)
|
||||
tv_main:add(tabs.server)
|
||||
tv_main:add(tabs.local_game)
|
||||
tv_main:add(tabs.play_online)
|
||||
tv_main:add(tabs.settings)
|
||||
tv_main:add(tabs.texturepacks)
|
||||
end
|
||||
@@ -149,7 +147,7 @@ local function init_globals()
|
||||
tv_main:set_fixed_size(false)
|
||||
|
||||
if PLATFORM ~= "Android" then
|
||||
tv_main:set_tab(core.setting_get("maintab_LAST"))
|
||||
tv_main:set_tab(core.settings:get("maintab_LAST"))
|
||||
end
|
||||
ui.set_default("maintab")
|
||||
tv_main:show()
|
||||
@@ -167,4 +165,3 @@ local function init_globals()
|
||||
end
|
||||
|
||||
init_globals()
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
--------------------------------------------------------------------------------
|
||||
function get_mods(path,retval,modpack)
|
||||
local mods = core.get_dir_list(path, true)
|
||||
|
||||
|
||||
for _, name in ipairs(mods) do
|
||||
if name:sub(1, 1) ~= "." then
|
||||
local prefix = path .. DIR_DELIM .. name .. DIR_DELIM
|
||||
@@ -237,74 +237,68 @@ function modmgr.render_modlist(render_list)
|
||||
|
||||
local list = render_list:get_list()
|
||||
local last_modpack = nil
|
||||
|
||||
for i,v in ipairs(list) do
|
||||
if retval ~= "" then
|
||||
retval = retval ..","
|
||||
end
|
||||
|
||||
local retval = {}
|
||||
for i, v in ipairs(list) do
|
||||
local color = ""
|
||||
|
||||
if v.is_modpack then
|
||||
local rawlist = render_list:get_raw_list()
|
||||
color = mt_color_dark_green
|
||||
|
||||
local all_enabled = true
|
||||
for j=1,#rawlist,1 do
|
||||
for j = 1, #rawlist, 1 do
|
||||
if rawlist[j].modpack == list[i].name and
|
||||
rawlist[j].enabled ~= true then
|
||||
all_enabled = false
|
||||
break
|
||||
rawlist[j].enabled ~= true then
|
||||
-- Modpack not entirely enabled so showing as grey
|
||||
color = mt_color_grey
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if all_enabled == false then
|
||||
color = mt_color_grey
|
||||
else
|
||||
color = mt_color_dark_green
|
||||
end
|
||||
end
|
||||
|
||||
if v.typ == "game_mod" then
|
||||
elseif v.is_game_content then
|
||||
color = mt_color_blue
|
||||
else
|
||||
if v.enabled then
|
||||
color = mt_color_green
|
||||
end
|
||||
elseif v.enabled then
|
||||
color = mt_color_green
|
||||
end
|
||||
|
||||
retval = retval .. color
|
||||
if v.modpack ~= nil then
|
||||
retval = retval .. " "
|
||||
retval[#retval + 1] = color
|
||||
if v.modpack ~= nil or v.typ == "game_mod" then
|
||||
retval[#retval + 1] = "1"
|
||||
else
|
||||
retval[#retval + 1] = "0"
|
||||
end
|
||||
retval = retval .. v.name
|
||||
retval[#retval + 1] = core.formspec_escape(v.name)
|
||||
end
|
||||
|
||||
return retval
|
||||
return table.concat(retval, ",")
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function modmgr.get_dependencies(modfolder)
|
||||
local toadd = ""
|
||||
local toadd_hard = ""
|
||||
local toadd_soft = ""
|
||||
if modfolder ~= nil then
|
||||
local filename = modfolder ..
|
||||
DIR_DELIM .. "depends.txt"
|
||||
|
||||
local hard_dependencies = {}
|
||||
local soft_dependencies = {}
|
||||
local dependencyfile = io.open(filename,"r")
|
||||
|
||||
if dependencyfile then
|
||||
local dependency = dependencyfile:read("*l")
|
||||
while dependency do
|
||||
if toadd ~= "" then
|
||||
toadd = toadd .. ","
|
||||
dependency = dependency:gsub("\r", "")
|
||||
if string.sub(dependency, -1, -1) == "?" then
|
||||
table.insert(soft_dependencies, string.sub(dependency, 1, -2))
|
||||
else
|
||||
table.insert(hard_dependencies, dependency)
|
||||
end
|
||||
toadd = toadd .. dependency
|
||||
dependency = dependencyfile:read()
|
||||
end
|
||||
dependencyfile:close()
|
||||
end
|
||||
toadd_hard = table.concat(hard_dependencies, ",")
|
||||
toadd_soft = table.concat(soft_dependencies, ",")
|
||||
end
|
||||
|
||||
return toadd
|
||||
return toadd_hard, toadd_soft
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -419,8 +413,18 @@ function modmgr.preparemodlist(data)
|
||||
local gamespec = gamemgr.find_by_gameid(data.gameid)
|
||||
gamemgr.get_game_mods(gamespec, game_mods)
|
||||
|
||||
if #game_mods > 0 then
|
||||
-- Add title
|
||||
retval[#retval + 1] = {
|
||||
typ = "game",
|
||||
is_game_content = true,
|
||||
name = fgettext("Subgame Mods")
|
||||
}
|
||||
end
|
||||
|
||||
for i=1,#game_mods,1 do
|
||||
game_mods[i].typ = "game_mod"
|
||||
game_mods[i].is_game_content = true
|
||||
retval[#retval + 1] = game_mods[i]
|
||||
end
|
||||
|
||||
|
||||
@@ -233,14 +233,14 @@ function modstore.handle_buttons(parent, fields, name, data)
|
||||
|
||||
if not core.handle_async(
|
||||
function(param)
|
||||
local fullurl = core.setting_get("modstore_download_url") ..
|
||||
local fullurl = core.settings:get("modstore_download_url") ..
|
||||
param.moddetails.download_url
|
||||
|
||||
if param.version ~= nil then
|
||||
local found = false
|
||||
for i=1,#param.moddetails.versions, 1 do
|
||||
if param.moddetails.versions[i].date:sub(1,10) == param.version then
|
||||
fullurl = core.setting_get("modstore_download_url") ..
|
||||
fullurl = core.settings:get("modstore_download_url") ..
|
||||
param.moddetails.versions[i].download_url
|
||||
found = true
|
||||
end
|
||||
@@ -400,7 +400,7 @@ function modstore.getscreenshot(ypos,listentry)
|
||||
listentry.texturename = "in progress"
|
||||
|
||||
--prepare url and filename
|
||||
local fullurl = core.setting_get("modstore_download_url") ..
|
||||
local fullurl = core.settings:get("modstore_download_url") ..
|
||||
listentry.details.screenshot_url
|
||||
local filename = os.tempfolder() .. "_MID_" .. listentry.id
|
||||
|
||||
|
||||
@@ -19,82 +19,88 @@
|
||||
|
||||
local core_developers = {
|
||||
"Perttu Ahola (celeron55) <celeron55@gmail.com>",
|
||||
"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
|
||||
"PilzAdam <pilzadam@minetest.net>",
|
||||
"sfan5 <sfan5@live.de>",
|
||||
"kahrl <kahrl@gmx.net>",
|
||||
"sapier",
|
||||
"ShadowNinja <shadowninja@minetest.net>",
|
||||
"Nathanaël Courant (Nore/Ekdohibs) <nore@mesecons.net>",
|
||||
"Loic Blot (nerzhul/nrz) <loic.blot@unix-experience.fr>",
|
||||
"Matt Gregory (paramat)",
|
||||
"est31 <MTest31@outlook.com>",
|
||||
"Craig Robbins (Zeno)",
|
||||
"paramat",
|
||||
"Craig Robbins (Zeno) <craig.d.robbins@gmail.com>",
|
||||
"Auke Kok (sofar) <sofar@foo-projects.org>",
|
||||
"rubenwardy <rw@rubenwardy.com>",
|
||||
"Krock/SmallJoker <mk939@ymail.com>",
|
||||
}
|
||||
|
||||
local active_contributors = {
|
||||
"Auke Kok (sofar) <sofar@foo-projects.org>",
|
||||
"Duane Robertson <duane@duanerobertson.com>",
|
||||
"SmallJoker <mk939@ymail.com>",
|
||||
"Andrew Ward (rubenwardy) <rubenwardy@gmail.com>",
|
||||
"Jeija <jeija@mesecons.net>",
|
||||
"Gregory Currie (gregorycu)",
|
||||
"Sokomine <wegwerf@anarres.dyndns.org>",
|
||||
"TeTpaAka",
|
||||
"Jean-Patrick G (kilbith) <jeanpatrick.guerrero@gmail.com>",
|
||||
"Diego Martínez (kaeza) <kaeza@users.sf.net>",
|
||||
"red-001 <red-001@outlook.ie> [CSM & Menu fixes]",
|
||||
"Dániel Juhász (juhdanad) <juhdanad@gmail.com> [Audiovisuals: lighting]",
|
||||
"numberZero [Audiovisuals: meshgen]",
|
||||
"Lars Hofhansl <larsh@apache.org> [Occulusion culling, fixes]",
|
||||
"Jean-Patrick G (kilbith) <jeanpatrick.guerrero@gmail.com> [Audiovisuals]",
|
||||
"Vincent Glize (Dumbeldor) <vincent.glize@live.fr> [CSM]",
|
||||
"bigfoot547 [CSM]",
|
||||
"Rogier <rogier777@gmail.com> [Fixes]",
|
||||
"Wuzzy [Audiovisuals]",
|
||||
"Shara/Ezhh [Settings]",
|
||||
}
|
||||
|
||||
local previous_core_developers = {
|
||||
"BlockMen",
|
||||
"Maciej Kasatkin (RealBadAngel) <maciej.kasatkin@o2.pl>",
|
||||
"Maciej Kasatkin (RealBadAngel) [RIP]",
|
||||
"Lisa Milne (darkrose) <lisa@ltmnet.com>",
|
||||
"proller",
|
||||
"Ilya Zhuravlev (xyz) <xyz@minetest.net>",
|
||||
"PilzAdam <pilzadam@minetest.net>",
|
||||
"est31 <MTest31@outlook.com>",
|
||||
"kahrl <kahrl@gmx.net>",
|
||||
"Ryan Kwolek (kwolekr) <kwolekr@minetest.net>",
|
||||
"sapier",
|
||||
}
|
||||
|
||||
local previous_contributors = {
|
||||
"Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>",
|
||||
"Jurgen Doser (doserj) <jurgen.doser@gmail.com>",
|
||||
"MirceaKitsune <mirceakitsune@gmail.com>",
|
||||
"dannydark <the_skeleton_of_a_child@yahoo.co.uk>",
|
||||
"0gb.us <0gb.us@0gb.us>",
|
||||
"Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>",
|
||||
"Jonathan Neuschafer <j.neuschaefer@gmx.net>",
|
||||
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>",
|
||||
"Břetislav Štec (t0suj4/TBC_x)",
|
||||
"Aaron Suen <warr1024@gmail.com>",
|
||||
"Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>",
|
||||
"matttpt <matttpt@gmail.com>",
|
||||
"JacobF <queatz@gmail.com>",
|
||||
"TriBlade9 <triblade9@mail.com>",
|
||||
"Zefram <zefram@fysh.org>",
|
||||
"Gregory Currie (gregorycu) [optimisation]",
|
||||
"Diego Martínez (kaeza) <kaeza@users.sf.net>",
|
||||
"T4im [Profiler]",
|
||||
"TeTpaAka [Hand overriding, nametag colors]",
|
||||
"HybridDog [Fixes]",
|
||||
"Duane Robertson <duane@duanerobertson.com> [MGValleys]",
|
||||
"neoascetic [OS X Fixes]",
|
||||
"TriBlade9 <triblade9@mail.com> [Audiovisuals]",
|
||||
"Jurgen Doser (doserj) <jurgen.doser@gmail.com> [Fixes]",
|
||||
"MirceaKitsune <mirceakitsune@gmail.com> [Audiovisuals]",
|
||||
"Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com> [Fixes]",
|
||||
"matttpt <matttpt@gmail.com> [Fixes]",
|
||||
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest Logo]",
|
||||
"Jeija <jeija@mesecons.net> [HTTP, particles]",
|
||||
}
|
||||
|
||||
local function buildCreditList(source)
|
||||
ret = {}
|
||||
for i = 1, #source do
|
||||
ret[i] = core.formspec_escape(source[i])
|
||||
end
|
||||
return table.concat(ret, ",,")
|
||||
end
|
||||
|
||||
return {
|
||||
name = "credits",
|
||||
caption = fgettext("Credits"),
|
||||
cbf_formspec = function(tabview, name, tabdata)
|
||||
local logofile = defaulttexturedir .. "logo.png"
|
||||
local version = core.get_version()
|
||||
return "image[0.5,1;" .. core.formspec_escape(logofile) .. "]" ..
|
||||
"label[0.5,3.2;Minetest " .. core.get_version() .. "]" ..
|
||||
"label[0.5,3.2;" .. version.project .. " " .. version.string .. "]" ..
|
||||
"label[0.5,3.5;http://minetest.net]" ..
|
||||
"tablecolumns[color;text]" ..
|
||||
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
|
||||
"table[3.5,-0.25;8.5,5.8;list_credits;" ..
|
||||
"#FFFF00," .. "Dedication of the current release" .. ",," ..
|
||||
"The 0.4.14 release is dedicated to the memory of" .. ",," ..
|
||||
"Minetest developer Maciej Kasatkin (RealBadAngel)" .. ",," ..
|
||||
"who died on March 24 2016." .. ",," ..
|
||||
"Our thoughts are with his family and friends." .. ",,," ..
|
||||
"table[3.5,-0.25;8.5,6.05;list_credits;" ..
|
||||
"#FFFF00," .. fgettext("Core Developers") .. ",," ..
|
||||
table.concat(core_developers, ",,") .. ",,," ..
|
||||
buildCreditList(core_developers) .. ",,," ..
|
||||
"#FFFF00," .. fgettext("Active Contributors") .. ",," ..
|
||||
table.concat(active_contributors, ",,") .. ",,," ..
|
||||
buildCreditList(active_contributors) .. ",,," ..
|
||||
"#FFFF00," .. fgettext("Previous Core Developers") ..",," ..
|
||||
table.concat(previous_core_developers, ",,") .. ",,," ..
|
||||
buildCreditList(previous_core_developers) .. ",,," ..
|
||||
"#FFFF00," .. fgettext("Previous Contributors") .. ",," ..
|
||||
table.concat(previous_contributors, ",,") .. "," ..
|
||||
buildCreditList(previous_contributors) .. "," ..
|
||||
";1]"
|
||||
end
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
local function current_game()
|
||||
local last_game_id = core.setting_get("menu_last_game")
|
||||
local last_game_id = core.settings:get("menu_last_game")
|
||||
local game, index = gamemgr.find_by_gameid(last_game_id)
|
||||
|
||||
|
||||
return game
|
||||
end
|
||||
|
||||
@@ -36,10 +36,10 @@ local function singleplayer_refresh_gamebar()
|
||||
if ("game_btnbar_" .. gamemgr.games[j].id == key) then
|
||||
mm_texture.update("singleplayer", gamemgr.games[j])
|
||||
core.set_topleft_text(gamemgr.games[j].name)
|
||||
core.setting_set("menu_last_game",gamemgr.games[j].id)
|
||||
core.settings:set("menu_last_game",gamemgr.games[j].id)
|
||||
menudata.worldlist:set_filtercriteria(gamemgr.games[j].id)
|
||||
local index = filterlist.get_current_index(menudata.worldlist,
|
||||
tonumber(core.setting_get("mainmenu_last_selected_world")))
|
||||
tonumber(core.settings:get("mainmenu_last_selected_world")))
|
||||
if not index or index < 1 then
|
||||
local selected = core.get_textlist_index("sp_worlds")
|
||||
if selected ~= nil and selected < #menudata.worldlist:get_list() then
|
||||
@@ -57,24 +57,24 @@ local function singleplayer_refresh_gamebar()
|
||||
|
||||
local btnbar = buttonbar_create("game_button_bar",
|
||||
game_buttonbar_button_handler,
|
||||
{x=-0.3,y=5.65}, "horizontal", {x=12.4,y=1.15})
|
||||
{x=-0.3,y=5.9}, "horizontal", {x=12.4,y=1.15})
|
||||
|
||||
for i=1,#gamemgr.games,1 do
|
||||
local btn_name = "game_btnbar_" .. gamemgr.games[i].id
|
||||
|
||||
|
||||
local image = nil
|
||||
local text = nil
|
||||
local tooltip = core.formspec_escape(gamemgr.games[i].name)
|
||||
|
||||
|
||||
if gamemgr.games[i].menuicon_path ~= nil and
|
||||
gamemgr.games[i].menuicon_path ~= "" then
|
||||
image = core.formspec_escape(gamemgr.games[i].menuicon_path)
|
||||
else
|
||||
|
||||
|
||||
local part1 = gamemgr.games[i].id:sub(1,5)
|
||||
local part2 = gamemgr.games[i].id:sub(6,10)
|
||||
local part3 = gamemgr.games[i].id:sub(11)
|
||||
|
||||
|
||||
text = part1 .. "\n" .. part2
|
||||
if part3 ~= nil and
|
||||
part3 ~= "" then
|
||||
@@ -89,28 +89,57 @@ local function get_formspec(tabview, name, tabdata)
|
||||
local retval = ""
|
||||
|
||||
local index = filterlist.get_current_index(menudata.worldlist,
|
||||
tonumber(core.setting_get("mainmenu_last_selected_world"))
|
||||
tonumber(core.settings:get("mainmenu_last_selected_world"))
|
||||
)
|
||||
|
||||
retval = retval ..
|
||||
"button[4,4.15;2.6,0.5;world_delete;".. fgettext("Delete") .. "]" ..
|
||||
"button[6.5,4.15;2.8,0.5;world_create;".. fgettext("New") .. "]" ..
|
||||
"button[9.2,4.15;2.55,0.5;world_configure;".. fgettext("Configure") .. "]" ..
|
||||
"button[8.5,4.95;3.25,0.5;play;".. fgettext("Play") .. "]" ..
|
||||
"label[4,-0.25;".. fgettext("Select World:") .. "]"..
|
||||
"checkbox[0.25,0.25;cb_creative_mode;".. fgettext("Creative Mode") .. ";" ..
|
||||
dump(core.setting_getbool("creative_mode")) .. "]"..
|
||||
dump(core.settings:get_bool("creative_mode")) .. "]"..
|
||||
"checkbox[0.25,0.7;cb_enable_damage;".. fgettext("Enable Damage") .. ";" ..
|
||||
dump(core.setting_getbool("enable_damage")) .. "]"..
|
||||
dump(core.settings:get_bool("enable_damage")) .. "]"..
|
||||
"checkbox[0.25,1.15;cb_server;".. fgettext("Host Server") ..";" ..
|
||||
dump(core.settings:get_bool("enable_server")) .. "]" ..
|
||||
"textlist[4,0.25;7.5,3.7;sp_worlds;" ..
|
||||
menu_render_worldlist() ..
|
||||
";" .. index .. "]"
|
||||
|
||||
if core.settings:get_bool("enable_server") then
|
||||
retval = retval ..
|
||||
"button[8.5,5;3.25,0.5;play;".. fgettext("Host Game") .. "]" ..
|
||||
"checkbox[0.25,1.6;cb_server_announce;" .. fgettext("Announce Server") .. ";" ..
|
||||
dump(core.settings:get_bool("server_announce")) .. "]" ..
|
||||
"label[0.25,2.2;" .. fgettext("Name/Password") .. "]" ..
|
||||
"field[0.55,3.2;3.5,0.5;te_playername;;" ..
|
||||
core.formspec_escape(core.settings:get("name")) .. "]" ..
|
||||
"pwdfield[0.55,4;3.5,0.5;te_passwd;]"
|
||||
|
||||
local bind_addr = core.settings:get("bind_address")
|
||||
if bind_addr ~= nil and bind_addr ~= "" then
|
||||
retval = retval ..
|
||||
"field[0.55,5.2;2.25,0.5;te_serveraddr;" .. fgettext("Bind Address") .. ";" ..
|
||||
core.formspec_escape(core.settings:get("bind_address")) .. "]" ..
|
||||
"field[2.8,5.2;1.25,0.5;te_serverport;" .. fgettext("Port") .. ";" ..
|
||||
core.formspec_escape(core.settings:get("port")) .. "]"
|
||||
else
|
||||
retval = retval ..
|
||||
"field[0.55,5.2;3.5,0.5;te_serverport;" .. fgettext("Server Port") .. ";" ..
|
||||
core.formspec_escape(core.settings:get("port")) .. "]"
|
||||
end
|
||||
else
|
||||
retval = retval ..
|
||||
"button[8.5,5;3.25,0.5;play;".. fgettext("Play Game") .. "]"
|
||||
end
|
||||
|
||||
return retval
|
||||
end
|
||||
|
||||
local function main_button_handler(this, fields, name, tabdata)
|
||||
|
||||
assert(name == "singleplayer")
|
||||
assert(name == "local")
|
||||
|
||||
local world_doubleclick = false
|
||||
|
||||
@@ -125,7 +154,7 @@ local function main_button_handler(this, fields, name, tabdata)
|
||||
end
|
||||
|
||||
if event.type == "CHG" and selected ~= nil then
|
||||
core.setting_set("mainmenu_last_selected_world",
|
||||
core.settings:set("mainmenu_last_selected_world",
|
||||
menudata.worldlist:get_raw_index(selected))
|
||||
return true
|
||||
end
|
||||
@@ -136,7 +165,7 @@ local function main_button_handler(this, fields, name, tabdata)
|
||||
end
|
||||
|
||||
if fields["cb_creative_mode"] then
|
||||
core.setting_set("creative_mode", fields["cb_creative_mode"])
|
||||
core.settings:set("creative_mode", fields["cb_creative_mode"])
|
||||
local selected = core.get_textlist_index("sp_worlds")
|
||||
menu_worldmt(selected, "creative_mode", fields["cb_creative_mode"])
|
||||
|
||||
@@ -144,27 +173,65 @@ local function main_button_handler(this, fields, name, tabdata)
|
||||
end
|
||||
|
||||
if fields["cb_enable_damage"] then
|
||||
core.setting_set("enable_damage", fields["cb_enable_damage"])
|
||||
core.settings:set("enable_damage", fields["cb_enable_damage"])
|
||||
local selected = core.get_textlist_index("sp_worlds")
|
||||
menu_worldmt(selected, "enable_damage", fields["cb_enable_damage"])
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["play"] ~= nil or
|
||||
world_doubleclick or
|
||||
fields["key_enter"] then
|
||||
if fields["cb_server"] then
|
||||
core.settings:set("enable_server", fields["cb_server"])
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_server_announce"] then
|
||||
core.settings:set("server_announce", fields["cb_server_announce"])
|
||||
local selected = core.get_textlist_index("srv_worlds")
|
||||
menu_worldmt(selected, "server_announce", fields["cb_server_announce"])
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["play"] ~= nil or world_doubleclick or fields["key_enter"] then
|
||||
local selected = core.get_textlist_index("sp_worlds")
|
||||
gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
|
||||
|
||||
if selected ~= nil and gamedata.selected_world ~= 0 then
|
||||
gamedata.singleplayer = true
|
||||
core.start()
|
||||
|
||||
if core.settings:get_bool("enable_server") then
|
||||
if selected ~= nil and gamedata.selected_world ~= 0 then
|
||||
gamedata.playername = fields["te_playername"]
|
||||
gamedata.password = fields["te_passwd"]
|
||||
gamedata.port = fields["te_serverport"]
|
||||
gamedata.address = ""
|
||||
|
||||
core.settings:set("port",gamedata.port)
|
||||
if fields["te_serveraddr"] ~= nil then
|
||||
core.settings:set("bind_address",fields["te_serveraddr"])
|
||||
end
|
||||
|
||||
--update last game
|
||||
local world = menudata.worldlist:get_raw_element(gamedata.selected_world)
|
||||
if world then
|
||||
local game, index = gamemgr.find_by_gameid(world.gameid)
|
||||
core.settings:set("menu_last_game", game.id)
|
||||
end
|
||||
|
||||
core.start()
|
||||
else
|
||||
gamedata.errormessage =
|
||||
fgettext("No world created or selected!")
|
||||
end
|
||||
else
|
||||
gamedata.errormessage =
|
||||
fgettext("No world created or selected!")
|
||||
if selected ~= nil and gamedata.selected_world ~= 0 then
|
||||
gamedata.singleplayer = true
|
||||
core.start()
|
||||
else
|
||||
gamedata.errormessage =
|
||||
fgettext("No world created or selected!")
|
||||
end
|
||||
return true
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["world_create"] ~= nil then
|
||||
@@ -192,7 +259,7 @@ local function main_button_handler(this, fields, name, tabdata)
|
||||
mm_texture.update("singleplayer",current_game())
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -202,7 +269,7 @@ local function main_button_handler(this, fields, name, tabdata)
|
||||
local configdialog =
|
||||
create_configure_world_dlg(
|
||||
menudata.worldlist:get_raw_index(selected))
|
||||
|
||||
|
||||
if (configdialog ~= nil) then
|
||||
configdialog:set_parent(this)
|
||||
this:hide()
|
||||
@@ -210,22 +277,22 @@ local function main_button_handler(this, fields, name, tabdata)
|
||||
mm_texture.update("singleplayer",current_game())
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function on_change(type, old_tab, new_tab)
|
||||
local buttonbar = ui.find_by_name("game_button_bar")
|
||||
|
||||
|
||||
if ( buttonbar == nil ) then
|
||||
singleplayer_refresh_gamebar()
|
||||
buttonbar = ui.find_by_name("game_button_bar")
|
||||
end
|
||||
|
||||
|
||||
if (type == "ENTER") then
|
||||
local game = current_game()
|
||||
|
||||
|
||||
if game then
|
||||
menudata.worldlist:set_filtercriteria(game.id)
|
||||
core.set_topleft_text(game.name)
|
||||
@@ -242,8 +309,8 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
return {
|
||||
name = "singleplayer",
|
||||
caption = fgettext("Singleplayer"),
|
||||
name = "local",
|
||||
caption = fgettext("Local Game"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = on_change
|
||||
@@ -28,7 +28,8 @@ local function get_formspec(tabview, name, tabdata)
|
||||
|
||||
local retval =
|
||||
"label[0.05,-0.25;".. fgettext("Installed Mods:") .. "]" ..
|
||||
"textlist[0,0.25;5.1,5;modlist;" ..
|
||||
"tablecolumns[color;tree;text]" ..
|
||||
"table[0,0.25;5.1,5;modlist;" ..
|
||||
modmgr.render_modlist(modmgr.global_mods) ..
|
||||
";" .. tabdata.selected_mod .. "]"
|
||||
|
||||
@@ -74,7 +75,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||
if error == nil then
|
||||
local descriptiontext = descriptionfile:read("*all")
|
||||
|
||||
descriptionlines = core.splittext(descriptiontext,42)
|
||||
descriptionlines = core.wrap_text(descriptiontext, 42)
|
||||
descriptionfile:close()
|
||||
else
|
||||
descriptionlines = {}
|
||||
@@ -98,12 +99,24 @@ local function get_formspec(tabview, name, tabdata)
|
||||
.. fgettext("Uninstall selected modpack") .. "]"
|
||||
else
|
||||
--show dependencies
|
||||
local toadd_hard, toadd_soft = modmgr.get_dependencies(selected_mod.path)
|
||||
if toadd_hard == "" and toadd_soft == "" then
|
||||
retval = retval .. "," .. fgettext("No dependencies.")
|
||||
else
|
||||
if toadd_hard ~= "" then
|
||||
retval = retval .. "," .. fgettext("Dependencies:") .. ","
|
||||
retval = retval .. toadd_hard
|
||||
end
|
||||
if toadd_soft ~= "" then
|
||||
if toadd_hard ~= "" then
|
||||
retval = retval .. ","
|
||||
end
|
||||
retval = retval .. "," .. fgettext("Optional dependencies:") .. ","
|
||||
retval = retval .. toadd_soft
|
||||
end
|
||||
end
|
||||
|
||||
retval = retval .. "," .. fgettext("Depends:") .. ","
|
||||
|
||||
local toadd = modmgr.get_dependencies(selected_mod.path)
|
||||
|
||||
retval = retval .. toadd .. ";0]"
|
||||
retval = retval .. ";0]"
|
||||
|
||||
retval = retval .. "button[5.5,4.85;4.5,0.5;btn_mod_mgr_delete_mod;"
|
||||
.. fgettext("Uninstall selected mod") .. "]"
|
||||
@@ -115,8 +128,8 @@ end
|
||||
--------------------------------------------------------------------------------
|
||||
local function handle_buttons(tabview, fields, tabname, tabdata)
|
||||
if fields["modlist"] ~= nil then
|
||||
local event = core.explode_textlist_event(fields["modlist"])
|
||||
tabdata.selected_mod = event.index
|
||||
local event = core.explode_table_event(fields["modlist"])
|
||||
tabdata.selected_mod = event.row
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
@@ -20,28 +20,48 @@ local function get_formspec(tabview, name, tabdata)
|
||||
-- Update the cached supported proto info,
|
||||
-- it may have changed after a change by the settings menu.
|
||||
common_update_cached_supp_proto()
|
||||
local fav_selected = menudata.favorites[tabdata.fav_selected]
|
||||
local fav_selected = nil
|
||||
if menudata.search_result then
|
||||
fav_selected = menudata.search_result[tabdata.fav_selected]
|
||||
else
|
||||
fav_selected = menudata.favorites[tabdata.fav_selected]
|
||||
end
|
||||
|
||||
if not tabdata.search_for then
|
||||
tabdata.search_for = ""
|
||||
end
|
||||
|
||||
local retval =
|
||||
"label[7.75,-0.15;" .. fgettext("Address / Port") .. "]" ..
|
||||
"label[7.75,1.05;" .. fgettext("Name / Password") .. "]" ..
|
||||
"field[8,0.75;3.3,0.5;te_address;;" ..
|
||||
core.formspec_escape(core.setting_get("address")) .. "]" ..
|
||||
"field[11.15,0.75;1.4,0.5;te_port;;" ..
|
||||
core.formspec_escape(core.setting_get("remote_port")) .. "]" ..
|
||||
"button[10.1,4.9;2,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]" ..
|
||||
"field[8,1.95;2.95,0.5;te_name;;" ..
|
||||
core.formspec_escape(core.setting_get("name")) .. "]" ..
|
||||
"pwdfield[10.78,1.95;1.77,0.5;te_pwd;]" ..
|
||||
"box[7.73,2.35;4.3,2.28;#999999]"
|
||||
-- Search
|
||||
"field[0.15,0.35;6.05,0.27;te_search;;"..core.formspec_escape(tabdata.search_for).."]"..
|
||||
"button[5.8,0.1;2,0.1;btn_mp_search;" .. fgettext("Search") .. "]" ..
|
||||
|
||||
-- Address / Port
|
||||
"label[7.75,-0.25;" .. fgettext("Address / Port") .. "]" ..
|
||||
"field[8,0.65;3.25,0.5;te_address;;" ..
|
||||
core.formspec_escape(core.settings:get("address")) .. "]" ..
|
||||
"field[11.1,0.65;1.4,0.5;te_port;;" ..
|
||||
core.formspec_escape(core.settings:get("remote_port")) .. "]" ..
|
||||
|
||||
-- Name / Password
|
||||
"label[7.75,0.95;" .. fgettext("Name / Password") .. "]" ..
|
||||
"field[8,1.85;2.9,0.5;te_name;;" ..
|
||||
core.formspec_escape(core.settings:get("name")) .. "]" ..
|
||||
"pwdfield[10.73,1.85;1.77,0.5;te_pwd;]" ..
|
||||
|
||||
-- Description Background
|
||||
"box[7.73,2.25;4.25,2.6;#999999]"..
|
||||
|
||||
-- Connect
|
||||
"button[10.1,5.15;2,0.5;btn_mp_connect;" .. fgettext("Connect") .. "]"
|
||||
|
||||
if tabdata.fav_selected and fav_selected then
|
||||
if gamedata.fav then
|
||||
retval = retval .. "button[7.85,4.9;2.3,0.5;btn_delete_favorite;" ..
|
||||
retval = retval .. "button[7.75,5.15;2.3,0.5;btn_delete_favorite;" ..
|
||||
fgettext("Del. Favorite") .. "]"
|
||||
end
|
||||
if fav_selected.description then
|
||||
retval = retval .. "textarea[8.1,2.4;4.26,2.6;;" ..
|
||||
retval = retval .. "textarea[8.1,2.3;4.23,2.9;;" ..
|
||||
core.formspec_escape((gamedata.serverdescription or ""), true) .. ";]"
|
||||
end
|
||||
end
|
||||
@@ -49,6 +69,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||
--favourites
|
||||
retval = retval .. "tablecolumns[" ..
|
||||
image_column(fgettext("Favorite"), "favorite") .. ";" ..
|
||||
image_column(fgettext("Ping")) .. ",padding=0.25;" ..
|
||||
"color,span=3;" ..
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
@@ -58,9 +79,27 @@ local function get_formspec(tabview, name, tabdata)
|
||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||
"color,span=1;" ..
|
||||
"text,padding=1]" ..
|
||||
"table[-0.15,-0.1;7.75,5.5;favourites;"
|
||||
"table[-0.15,0.6;7.75,5.15;favourites;"
|
||||
|
||||
if #menudata.favorites > 0 then
|
||||
if menudata.search_result then
|
||||
for i = 1, #menudata.search_result do
|
||||
local favs = core.get_favorites("local")
|
||||
local server = menudata.search_result[i]
|
||||
|
||||
for fav_id = 1, #favs do
|
||||
if server.address == favs[fav_id].address and
|
||||
server.port == favs[fav_id].port then
|
||||
server.is_favorite = true
|
||||
end
|
||||
end
|
||||
|
||||
if i ~= 1 then
|
||||
retval = retval .. ","
|
||||
end
|
||||
|
||||
retval = retval .. render_serverlist_row(server, server.is_favorite)
|
||||
end
|
||||
elseif #menudata.favorites > 0 then
|
||||
local favs = core.get_favorites("local")
|
||||
if #favs > 0 then
|
||||
for i = 1, #favs do
|
||||
@@ -75,9 +114,9 @@ local function get_formspec(tabview, name, tabdata)
|
||||
end
|
||||
end
|
||||
end
|
||||
retval = retval .. render_favorite(menudata.favorites[1], (#favs > 0))
|
||||
retval = retval .. render_serverlist_row(menudata.favorites[1], (#favs > 0))
|
||||
for i = 2, #menudata.favorites do
|
||||
retval = retval .. "," .. render_favorite(menudata.favorites[i], (i <= #favs))
|
||||
retval = retval .. "," .. render_serverlist_row(menudata.favorites[i], (i <= #favs))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -92,17 +131,19 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(tabview, fields, name, tabdata)
|
||||
local serverlist = menudata.search_result or menudata.favorites
|
||||
|
||||
if fields.te_name then
|
||||
gamedata.playername = fields.te_name
|
||||
core.setting_set("name", fields.te_name)
|
||||
core.settings:set("name", fields.te_name)
|
||||
end
|
||||
|
||||
if fields.favourites then
|
||||
local event = core.explode_table_event(fields.favourites)
|
||||
local fav = menudata.favorites[event.row]
|
||||
local fav = serverlist[event.row]
|
||||
|
||||
if event.type == "DCL" then
|
||||
if event.row <= #menudata.favorites then
|
||||
if event.row <= #serverlist then
|
||||
if menudata.favorites_is_public and
|
||||
not is_server_protocol_compat_or_error(
|
||||
fav.proto_min, fav.proto_max) then
|
||||
@@ -122,8 +163,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
gamedata.serverdescription = fav.description
|
||||
|
||||
if gamedata.address and gamedata.port then
|
||||
core.setting_set("address", gamedata.address)
|
||||
core.setting_set("remote_port", gamedata.port)
|
||||
core.settings:set("address", gamedata.address)
|
||||
core.settings:set("remote_port", gamedata.port)
|
||||
core.start()
|
||||
end
|
||||
end
|
||||
@@ -131,7 +172,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
end
|
||||
|
||||
if event.type == "CHG" then
|
||||
if event.row <= #menudata.favorites then
|
||||
if event.row <= #serverlist then
|
||||
gamedata.fav = false
|
||||
local favs = core.get_favorites("local")
|
||||
local address = fav.address
|
||||
@@ -146,8 +187,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
end
|
||||
|
||||
if address and port then
|
||||
core.setting_set("address", address)
|
||||
core.setting_set("remote_port", port)
|
||||
core.settings:set("address", address)
|
||||
core.settings:set("remote_port", port)
|
||||
end
|
||||
tabdata.fav_selected = event.row
|
||||
end
|
||||
@@ -157,7 +198,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
if fields.key_up or fields.key_down then
|
||||
local fav_idx = core.get_table_index("favourites")
|
||||
local fav = menudata.favorites[fav_idx]
|
||||
local fav = serverlist[fav_idx]
|
||||
|
||||
if fav_idx then
|
||||
if fields.key_up and fav_idx > 1 then
|
||||
@@ -176,10 +217,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
local address = fav.address
|
||||
local port = fav.port
|
||||
|
||||
gamedata.serverdescription = fav.description
|
||||
if address and port then
|
||||
core.setting_set("address", address)
|
||||
core.setting_set("remote_port", port)
|
||||
core.settings:set("address", address)
|
||||
core.settings:set("remote_port", port)
|
||||
end
|
||||
|
||||
tabdata.fav_selected = fav_idx
|
||||
@@ -194,21 +235,81 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
asyncOnlineFavourites()
|
||||
tabdata.fav_selected = nil
|
||||
|
||||
core.setting_set("address", "")
|
||||
core.setting_set("remote_port", "30000")
|
||||
core.settings:set("address", "")
|
||||
core.settings:set("remote_port", "30000")
|
||||
return true
|
||||
end
|
||||
|
||||
if (fields.btn_mp_connect or fields.key_enter) and fields.te_address and fields.te_port then
|
||||
if fields.btn_mp_search or fields.key_enter_field == "te_search" then
|
||||
tabdata.fav_selected = 1
|
||||
local input = fields.te_search:lower()
|
||||
tabdata.search_for = fields.te_search
|
||||
|
||||
if #menudata.favorites < 2 then
|
||||
return true
|
||||
end
|
||||
|
||||
menudata.search_result = {}
|
||||
|
||||
-- setup the keyword list
|
||||
local keywords = {}
|
||||
for word in input:gmatch("%S+") do
|
||||
table.insert(keywords, word)
|
||||
end
|
||||
|
||||
if #keywords == 0 then
|
||||
menudata.search_result = nil
|
||||
return true
|
||||
end
|
||||
|
||||
-- Search the serverlist
|
||||
local search_result = {}
|
||||
for i = 1, #menudata.favorites do
|
||||
local server = menudata.favorites[i]
|
||||
local found = 0
|
||||
for k = 1, #keywords do
|
||||
local keyword = keywords[k]
|
||||
if server.name then
|
||||
local name = server.name:lower()
|
||||
local _, count = name:gsub(keyword, keyword)
|
||||
found = found + count * 4
|
||||
end
|
||||
|
||||
if server.description then
|
||||
local desc = server.description:lower()
|
||||
local _, count = desc:gsub(keyword, keyword)
|
||||
found = found + count * 2
|
||||
end
|
||||
end
|
||||
if found > 0 then
|
||||
local points = (#menudata.favorites - i) / 5 + found
|
||||
server.points = points
|
||||
table.insert(search_result, server)
|
||||
end
|
||||
end
|
||||
if #search_result > 0 then
|
||||
table.sort(search_result, function(a, b)
|
||||
return a.points > b.points
|
||||
end)
|
||||
menudata.search_result = search_result
|
||||
local first_server = search_result[1]
|
||||
core.settings:set("address", first_server.address)
|
||||
core.settings:set("remote_port", first_server.port)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if (fields.btn_mp_connect or fields.key_enter)
|
||||
and fields.te_address ~= "" and fields.te_port then
|
||||
gamedata.playername = fields.te_name
|
||||
gamedata.password = fields.te_pwd
|
||||
gamedata.address = fields.te_address
|
||||
gamedata.port = fields.te_port
|
||||
gamedata.selected_world = 0
|
||||
local fav_idx = core.get_table_index("favourites")
|
||||
local fav = menudata.favorites[fav_idx]
|
||||
local fav = serverlist[fav_idx]
|
||||
|
||||
if fav_idx and fav_idx <= #menudata.favorites and
|
||||
if fav_idx and fav_idx <= #serverlist and
|
||||
fav.address == fields.te_address and
|
||||
fav.port == fields.te_port then
|
||||
|
||||
@@ -225,8 +326,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
gamedata.serverdescription = ""
|
||||
end
|
||||
|
||||
core.setting_set("address", fields.te_address)
|
||||
core.setting_set("remote_port", fields.te_port)
|
||||
core.settings:set("address", fields.te_address)
|
||||
core.settings:set("remote_port", fields.te_port)
|
||||
|
||||
core.start()
|
||||
return true
|
||||
@@ -241,8 +342,8 @@ end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
return {
|
||||
name = "multiplayer",
|
||||
caption = fgettext("Client"),
|
||||
name = "online",
|
||||
caption = fgettext("Play Online"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = on_change
|
||||
@@ -1,195 +0,0 @@
|
||||
--Minetest
|
||||
--Copyright (C) 2014 sapier
|
||||
--
|
||||
--This program is free software; you can redistribute it and/or modify
|
||||
--it under the terms of the GNU Lesser General Public License as published by
|
||||
--the Free Software Foundation; either version 2.1 of the License, or
|
||||
--(at your option) any later version.
|
||||
--
|
||||
--This program is distributed in the hope that it will be useful,
|
||||
--but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
--GNU Lesser General Public License for more details.
|
||||
--
|
||||
--You should have received a copy of the GNU Lesser General Public License along
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function get_formspec(tabview, name, tabdata)
|
||||
|
||||
local index = menudata.worldlist:get_current_index(
|
||||
tonumber(core.setting_get("mainmenu_last_selected_world"))
|
||||
)
|
||||
|
||||
local retval =
|
||||
"button[4,4.15;2.6,0.5;world_delete;" .. fgettext("Delete") .. "]" ..
|
||||
"button[6.5,4.15;2.8,0.5;world_create;" .. fgettext("New") .. "]" ..
|
||||
"button[9.2,4.15;2.55,0.5;world_configure;" .. fgettext("Configure") .. "]" ..
|
||||
"button[8.5,4.95;3.25,0.5;start_server;" .. fgettext("Start Game") .. "]" ..
|
||||
"label[4,-0.25;" .. fgettext("Select World:") .. "]" ..
|
||||
"checkbox[0.25,0.25;cb_creative_mode;" .. fgettext("Creative Mode") .. ";" ..
|
||||
dump(core.setting_getbool("creative_mode")) .. "]" ..
|
||||
"checkbox[0.25,0.7;cb_enable_damage;" .. fgettext("Enable Damage") .. ";" ..
|
||||
dump(core.setting_getbool("enable_damage")) .. "]" ..
|
||||
"checkbox[0.25,1.15;cb_server_announce;" .. fgettext("Public") .. ";" ..
|
||||
dump(core.setting_getbool("server_announce")) .. "]" ..
|
||||
"label[0.25,2.2;" .. fgettext("Name/Password") .. "]" ..
|
||||
"field[0.55,3.2;3.5,0.5;te_playername;;" ..
|
||||
core.formspec_escape(core.setting_get("name")) .. "]" ..
|
||||
"pwdfield[0.55,4;3.5,0.5;te_passwd;]"
|
||||
|
||||
local bind_addr = core.setting_get("bind_address")
|
||||
if bind_addr ~= nil and bind_addr ~= "" then
|
||||
retval = retval ..
|
||||
"field[0.55,5.2;2.25,0.5;te_serveraddr;" .. fgettext("Bind Address") .. ";" ..
|
||||
core.formspec_escape(core.setting_get("bind_address")) .. "]" ..
|
||||
"field[2.8,5.2;1.25,0.5;te_serverport;" .. fgettext("Port") .. ";" ..
|
||||
core.formspec_escape(core.setting_get("port")) .. "]"
|
||||
else
|
||||
retval = retval ..
|
||||
"field[0.55,5.2;3.5,0.5;te_serverport;" .. fgettext("Server Port") .. ";" ..
|
||||
core.formspec_escape(core.setting_get("port")) .. "]"
|
||||
end
|
||||
|
||||
retval = retval ..
|
||||
"textlist[4,0.25;7.5,3.7;srv_worlds;" ..
|
||||
menu_render_worldlist() ..
|
||||
";" .. index .. "]"
|
||||
|
||||
return retval
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
local function main_button_handler(this, fields, name, tabdata)
|
||||
|
||||
local world_doubleclick = false
|
||||
|
||||
if fields["srv_worlds"] ~= nil then
|
||||
local event = core.explode_textlist_event(fields["srv_worlds"])
|
||||
local selected = core.get_textlist_index("srv_worlds")
|
||||
|
||||
menu_worldmt_legacy(selected)
|
||||
|
||||
if event.type == "DCL" then
|
||||
world_doubleclick = true
|
||||
end
|
||||
if event.type == "CHG" then
|
||||
core.setting_set("mainmenu_last_selected_world",
|
||||
menudata.worldlist:get_raw_index(core.get_textlist_index("srv_worlds")))
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if menu_handle_key_up_down(fields,"srv_worlds","mainmenu_last_selected_world") then
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_creative_mode"] then
|
||||
core.setting_set("creative_mode", fields["cb_creative_mode"])
|
||||
local selected = core.get_textlist_index("srv_worlds")
|
||||
menu_worldmt(selected, "creative_mode", fields["cb_creative_mode"])
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_enable_damage"] then
|
||||
core.setting_set("enable_damage", fields["cb_enable_damage"])
|
||||
local selected = core.get_textlist_index("srv_worlds")
|
||||
menu_worldmt(selected, "enable_damage", fields["cb_enable_damage"])
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["cb_server_announce"] then
|
||||
core.setting_set("server_announce", fields["cb_server_announce"])
|
||||
local selected = core.get_textlist_index("srv_worlds")
|
||||
menu_worldmt(selected, "server_announce", fields["cb_server_announce"])
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["start_server"] ~= nil or
|
||||
world_doubleclick or
|
||||
fields["key_enter"] then
|
||||
local selected = core.get_textlist_index("srv_worlds")
|
||||
gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
|
||||
if selected ~= nil and gamedata.selected_world ~= 0 then
|
||||
gamedata.playername = fields["te_playername"]
|
||||
gamedata.password = fields["te_passwd"]
|
||||
gamedata.port = fields["te_serverport"]
|
||||
gamedata.address = ""
|
||||
|
||||
core.setting_set("port",gamedata.port)
|
||||
if fields["te_serveraddr"] ~= nil then
|
||||
core.setting_set("bind_address",fields["te_serveraddr"])
|
||||
end
|
||||
|
||||
--update last game
|
||||
local world = menudata.worldlist:get_raw_element(gamedata.selected_world)
|
||||
if world then
|
||||
local game, index = gamemgr.find_by_gameid(world.gameid)
|
||||
core.setting_set("menu_last_game", game.id)
|
||||
end
|
||||
|
||||
core.start()
|
||||
else
|
||||
gamedata.errormessage =
|
||||
fgettext("No world created or selected!")
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["world_create"] ~= nil then
|
||||
local create_world_dlg = create_create_world_dlg(true)
|
||||
create_world_dlg:set_parent(this)
|
||||
create_world_dlg:show()
|
||||
this:hide()
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["world_delete"] ~= nil then
|
||||
local selected = core.get_textlist_index("srv_worlds")
|
||||
if selected ~= nil and
|
||||
selected <= menudata.worldlist:size() then
|
||||
local world = menudata.worldlist:get_list()[selected]
|
||||
if world ~= nil and
|
||||
world.name ~= nil and
|
||||
world.name ~= "" then
|
||||
local index = menudata.worldlist:get_raw_index(selected)
|
||||
local delete_world_dlg = create_delete_world_dlg(world.name,index)
|
||||
delete_world_dlg:set_parent(this)
|
||||
delete_world_dlg:show()
|
||||
this:hide()
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if fields["world_configure"] ~= nil then
|
||||
local selected = core.get_textlist_index("srv_worlds")
|
||||
if selected ~= nil then
|
||||
local configdialog =
|
||||
create_configure_world_dlg(
|
||||
menudata.worldlist:get_raw_index(selected))
|
||||
|
||||
if (configdialog ~= nil) then
|
||||
configdialog:set_parent(this)
|
||||
configdialog:show()
|
||||
this:hide()
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
return {
|
||||
name = "server",
|
||||
caption = fgettext("Server"),
|
||||
cbf_formspec = get_formspec,
|
||||
cbf_button_handler = main_button_handler,
|
||||
on_change = nil
|
||||
}
|
||||
@@ -25,7 +25,8 @@ local labels = {
|
||||
},
|
||||
node_highlighting = {
|
||||
fgettext("Node Outlining"),
|
||||
fgettext("Node Highlighting")
|
||||
fgettext("Node Highlighting"),
|
||||
fgettext("None")
|
||||
},
|
||||
filters = {
|
||||
fgettext("No Filter"),
|
||||
@@ -52,7 +53,7 @@ local dd_options = {
|
||||
},
|
||||
node_highlighting = {
|
||||
table.concat(labels.node_highlighting, ","),
|
||||
{"box", "halo"}
|
||||
{"box", "halo", "none"}
|
||||
},
|
||||
filters = {
|
||||
table.concat(labels.filters, ","),
|
||||
@@ -70,39 +71,39 @@ local dd_options = {
|
||||
|
||||
local getSettingIndex = {
|
||||
Leaves = function()
|
||||
local style = core.setting_get("leaves_style")
|
||||
local style = core.settings:get("leaves_style")
|
||||
for idx, name in pairs(dd_options.leaves[2]) do
|
||||
if style == name then return idx end
|
||||
end
|
||||
return 1
|
||||
end,
|
||||
NodeHighlighting = function()
|
||||
local style = core.setting_get("node_highlighting")
|
||||
local style = core.settings:get("node_highlighting")
|
||||
for idx, name in pairs(dd_options.node_highlighting[2]) do
|
||||
if style == name then return idx end
|
||||
end
|
||||
return 1
|
||||
end,
|
||||
Filter = function()
|
||||
if core.setting_get(dd_options.filters[2][3]) == "true" then
|
||||
if core.settings:get(dd_options.filters[2][3]) == "true" then
|
||||
return 3
|
||||
elseif core.setting_get(dd_options.filters[2][3]) == "false" and
|
||||
core.setting_get(dd_options.filters[2][2]) == "true" then
|
||||
elseif core.settings:get(dd_options.filters[2][3]) == "false" and
|
||||
core.settings:get(dd_options.filters[2][2]) == "true" then
|
||||
return 2
|
||||
end
|
||||
return 1
|
||||
end,
|
||||
Mipmap = function()
|
||||
if core.setting_get(dd_options.mipmap[2][3]) == "true" then
|
||||
if core.settings:get(dd_options.mipmap[2][3]) == "true" then
|
||||
return 3
|
||||
elseif core.setting_get(dd_options.mipmap[2][3]) == "false" and
|
||||
core.setting_get(dd_options.mipmap[2][2]) == "true" then
|
||||
elseif core.settings:get(dd_options.mipmap[2][3]) == "false" and
|
||||
core.settings:get(dd_options.mipmap[2][2]) == "true" then
|
||||
return 2
|
||||
end
|
||||
return 1
|
||||
end,
|
||||
Antialiasing = function()
|
||||
local antialiasing_setting = core.setting_get("fsaa")
|
||||
local antialiasing_setting = core.settings:get("fsaa")
|
||||
for i = 1, #dd_options.antialiasing[2] do
|
||||
if antialiasing_setting == dd_options.antialiasing[2][i] then
|
||||
return i
|
||||
@@ -177,20 +178,20 @@ local function formspec(tabview, name, tabdata)
|
||||
local tab_string =
|
||||
"box[0,0;3.5,4.5;#999999]" ..
|
||||
"checkbox[0.25,0;cb_smooth_lighting;" .. fgettext("Smooth Lighting") .. ";"
|
||||
.. dump(core.setting_getbool("smooth_lighting")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("smooth_lighting")) .. "]" ..
|
||||
"checkbox[0.25,0.5;cb_particles;" .. fgettext("Particles") .. ";"
|
||||
.. dump(core.setting_getbool("enable_particles")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("enable_particles")) .. "]" ..
|
||||
"checkbox[0.25,1;cb_3d_clouds;" .. fgettext("3D Clouds") .. ";"
|
||||
.. dump(core.setting_getbool("enable_3d_clouds")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("enable_3d_clouds")) .. "]" ..
|
||||
"checkbox[0.25,1.5;cb_opaque_water;" .. fgettext("Opaque Water") .. ";"
|
||||
.. dump(core.setting_getbool("opaque_water")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("opaque_water")) .. "]" ..
|
||||
"checkbox[0.25,2.0;cb_connected_glass;" .. fgettext("Connected Glass") .. ";"
|
||||
.. dump(core.setting_getbool("connected_glass")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("connected_glass")) .. "]" ..
|
||||
"dropdown[0.25,2.8;3.3;dd_node_highlighting;" .. dd_options.node_highlighting[1] .. ";"
|
||||
.. getSettingIndex.NodeHighlighting() .. "]" ..
|
||||
"dropdown[0.25,3.6;3.3;dd_leaves_style;" .. dd_options.leaves[1] .. ";"
|
||||
.. getSettingIndex.Leaves() .. "]" ..
|
||||
"box[3.75,0;3.75,3.45;#999999]" ..
|
||||
"box[3.75,0;3.75,4.45;#999999]" ..
|
||||
"label[3.85,0.1;" .. fgettext("Texturing:") .. "]" ..
|
||||
"dropdown[3.85,0.55;3.85;dd_filters;" .. dd_options.filters[1] .. ";"
|
||||
.. getSettingIndex.Filter() .. "]" ..
|
||||
@@ -199,9 +200,12 @@ local function formspec(tabview, name, tabdata)
|
||||
"label[3.85,2.15;" .. fgettext("Antialiasing:") .. "]" ..
|
||||
"dropdown[3.85,2.6;3.85;dd_antialiasing;" .. dd_options.antialiasing[1] .. ";"
|
||||
.. getSettingIndex.Antialiasing() .. "]" ..
|
||||
"label[3.85,3.45;" .. fgettext("Screen:") .. "]" ..
|
||||
"checkbox[3.85,3.6;cb_autosave_screensize;" .. fgettext("Autosave screen size") .. ";"
|
||||
.. dump(core.settings:get_bool("autosave_screensize")) .. "]" ..
|
||||
"box[7.75,0;4,4.4;#999999]" ..
|
||||
"checkbox[8,0;cb_shaders;" .. fgettext("Shaders") .. ";"
|
||||
.. dump(core.setting_getbool("enable_shaders")) .. "]"
|
||||
.. dump(core.settings:get_bool("enable_shaders")) .. "]"
|
||||
|
||||
if PLATFORM == "Android" then
|
||||
tab_string = tab_string ..
|
||||
@@ -209,38 +213,38 @@ local function formspec(tabview, name, tabdata)
|
||||
.. fgettext("Reset singleplayer world") .. "]"
|
||||
else
|
||||
tab_string = tab_string ..
|
||||
"button[8,4.75;3.75,0.5;btn_change_keys;"
|
||||
"button[8,4.85;3.75,0.5;btn_change_keys;"
|
||||
.. fgettext("Change keys") .. "]"
|
||||
end
|
||||
|
||||
tab_string = tab_string ..
|
||||
"button[0,4.75;3.75,0.5;btn_advanced_settings;"
|
||||
"button[0,4.85;3.75,0.5;btn_advanced_settings;"
|
||||
.. fgettext("Advanced Settings") .. "]"
|
||||
|
||||
|
||||
if core.setting_get("touchscreen_threshold") ~= nil then
|
||||
if core.settings:get("touchscreen_threshold") ~= nil then
|
||||
tab_string = tab_string ..
|
||||
"label[4.3,4.1;" .. fgettext("Touchthreshold (px)") .. "]" ..
|
||||
"dropdown[3.85,4.55;3.85;dd_touchthreshold;0,10,20,30,40,50;" ..
|
||||
((tonumber(core.setting_get("touchscreen_threshold")) / 10) + 1) .. "]"
|
||||
((tonumber(core.settings:get("touchscreen_threshold")) / 10) + 1) .. "]"
|
||||
end
|
||||
|
||||
if core.setting_getbool("enable_shaders") then
|
||||
if core.settings:get_bool("enable_shaders") then
|
||||
tab_string = tab_string ..
|
||||
"checkbox[8,0.5;cb_bumpmapping;" .. fgettext("Bump Mapping") .. ";"
|
||||
.. dump(core.setting_getbool("enable_bumpmapping")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("enable_bumpmapping")) .. "]" ..
|
||||
"checkbox[8,1;cb_tonemapping;" .. fgettext("Tone Mapping") .. ";"
|
||||
.. dump(core.setting_getbool("tone_mapping")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("tone_mapping")) .. "]" ..
|
||||
"checkbox[8,1.5;cb_generate_normalmaps;" .. fgettext("Normal Mapping") .. ";"
|
||||
.. dump(core.setting_getbool("generate_normalmaps")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("generate_normalmaps")) .. "]" ..
|
||||
"checkbox[8,2;cb_parallax;" .. fgettext("Parallax Occlusion") .. ";"
|
||||
.. dump(core.setting_getbool("enable_parallax_occlusion")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("enable_parallax_occlusion")) .. "]" ..
|
||||
"checkbox[8,2.5;cb_waving_water;" .. fgettext("Waving Water") .. ";"
|
||||
.. dump(core.setting_getbool("enable_waving_water")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("enable_waving_water")) .. "]" ..
|
||||
"checkbox[8,3;cb_waving_leaves;" .. fgettext("Waving Leaves") .. ";"
|
||||
.. dump(core.setting_getbool("enable_waving_leaves")) .. "]" ..
|
||||
.. dump(core.settings:get_bool("enable_waving_leaves")) .. "]" ..
|
||||
"checkbox[8,3.5;cb_waving_plants;" .. fgettext("Waving Plants") .. ";"
|
||||
.. dump(core.setting_getbool("enable_waving_plants")) .. "]"
|
||||
.. dump(core.settings:get_bool("enable_waving_plants")) .. "]"
|
||||
else
|
||||
tab_string = tab_string ..
|
||||
"tablecolumns[color;text]" ..
|
||||
@@ -271,60 +275,64 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||
return true
|
||||
end
|
||||
if fields["cb_smooth_lighting"] then
|
||||
core.setting_set("smooth_lighting", fields["cb_smooth_lighting"])
|
||||
core.settings:set("smooth_lighting", fields["cb_smooth_lighting"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_particles"] then
|
||||
core.setting_set("enable_particles", fields["cb_particles"])
|
||||
core.settings:set("enable_particles", fields["cb_particles"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_3d_clouds"] then
|
||||
core.setting_set("enable_3d_clouds", fields["cb_3d_clouds"])
|
||||
core.settings:set("enable_3d_clouds", fields["cb_3d_clouds"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_opaque_water"] then
|
||||
core.setting_set("opaque_water", fields["cb_opaque_water"])
|
||||
core.settings:set("opaque_water", fields["cb_opaque_water"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_connected_glass"] then
|
||||
core.setting_set("connected_glass", fields["cb_connected_glass"])
|
||||
core.settings:set("connected_glass", fields["cb_connected_glass"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_autosave_screensize"] then
|
||||
core.settings:set("autosave_screensize", fields["cb_autosave_screensize"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_shaders"] then
|
||||
if (core.setting_get("video_driver") == "direct3d8" or
|
||||
core.setting_get("video_driver") == "direct3d9") then
|
||||
core.setting_set("enable_shaders", "false")
|
||||
if (core.settings:get("video_driver") == "direct3d8" or
|
||||
core.settings:get("video_driver") == "direct3d9") then
|
||||
core.settings:set("enable_shaders", "false")
|
||||
gamedata.errormessage = fgettext("To enable shaders the OpenGL driver needs to be used.")
|
||||
else
|
||||
core.setting_set("enable_shaders", fields["cb_shaders"])
|
||||
core.settings:set("enable_shaders", fields["cb_shaders"])
|
||||
end
|
||||
return true
|
||||
end
|
||||
if fields["cb_bumpmapping"] then
|
||||
core.setting_set("enable_bumpmapping", fields["cb_bumpmapping"])
|
||||
core.settings:set("enable_bumpmapping", fields["cb_bumpmapping"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_tonemapping"] then
|
||||
core.setting_set("tone_mapping", fields["cb_tonemapping"])
|
||||
core.settings:set("tone_mapping", fields["cb_tonemapping"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_generate_normalmaps"] then
|
||||
core.setting_set("generate_normalmaps", fields["cb_generate_normalmaps"])
|
||||
core.settings:set("generate_normalmaps", fields["cb_generate_normalmaps"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_parallax"] then
|
||||
core.setting_set("enable_parallax_occlusion", fields["cb_parallax"])
|
||||
core.settings:set("enable_parallax_occlusion", fields["cb_parallax"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_waving_water"] then
|
||||
core.setting_set("enable_waving_water", fields["cb_waving_water"])
|
||||
core.settings:set("enable_waving_water", fields["cb_waving_water"])
|
||||
return true
|
||||
end
|
||||
if fields["cb_waving_leaves"] then
|
||||
core.setting_set("enable_waving_leaves", fields["cb_waving_leaves"])
|
||||
core.settings:set("enable_waving_leaves", fields["cb_waving_leaves"])
|
||||
end
|
||||
if fields["cb_waving_plants"] then
|
||||
core.setting_set("enable_waving_plants", fields["cb_waving_plants"])
|
||||
core.settings:set("enable_waving_plants", fields["cb_waving_plants"])
|
||||
return true
|
||||
end
|
||||
if fields["btn_change_keys"] then
|
||||
@@ -332,7 +340,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||
return true
|
||||
end
|
||||
if fields["cb_touchscreen_target"] then
|
||||
core.setting_set("touchtarget", fields["cb_touchscreen_target"])
|
||||
core.settings:set("touchtarget", fields["cb_touchscreen_target"])
|
||||
return true
|
||||
end
|
||||
if fields["btn_reset_singleplayer"] then
|
||||
@@ -345,49 +353,49 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
|
||||
|
||||
for i = 1, #labels.leaves do
|
||||
if fields["dd_leaves_style"] == labels.leaves[i] then
|
||||
core.setting_set("leaves_style", dd_options.leaves[2][i])
|
||||
core.settings:set("leaves_style", dd_options.leaves[2][i])
|
||||
ddhandled = true
|
||||
end
|
||||
end
|
||||
for i = 1, #labels.node_highlighting do
|
||||
if fields["dd_node_highlighting"] == labels.node_highlighting[i] then
|
||||
core.setting_set("node_highlighting", dd_options.node_highlighting[2][i])
|
||||
core.settings:set("node_highlighting", dd_options.node_highlighting[2][i])
|
||||
ddhandled = true
|
||||
end
|
||||
end
|
||||
if fields["dd_filters"] == labels.filters[1] then
|
||||
core.setting_set("bilinear_filter", "false")
|
||||
core.setting_set("trilinear_filter", "false")
|
||||
core.settings:set("bilinear_filter", "false")
|
||||
core.settings:set("trilinear_filter", "false")
|
||||
ddhandled = true
|
||||
elseif fields["dd_filters"] == labels.filters[2] then
|
||||
core.setting_set("bilinear_filter", "true")
|
||||
core.setting_set("trilinear_filter", "false")
|
||||
core.settings:set("bilinear_filter", "true")
|
||||
core.settings:set("trilinear_filter", "false")
|
||||
ddhandled = true
|
||||
elseif fields["dd_filters"] == labels.filters[3] then
|
||||
core.setting_set("bilinear_filter", "false")
|
||||
core.setting_set("trilinear_filter", "true")
|
||||
core.settings:set("bilinear_filter", "false")
|
||||
core.settings:set("trilinear_filter", "true")
|
||||
ddhandled = true
|
||||
end
|
||||
if fields["dd_mipmap"] == labels.mipmap[1] then
|
||||
core.setting_set("mip_map", "false")
|
||||
core.setting_set("anisotropic_filter", "false")
|
||||
core.settings:set("mip_map", "false")
|
||||
core.settings:set("anisotropic_filter", "false")
|
||||
ddhandled = true
|
||||
elseif fields["dd_mipmap"] == labels.mipmap[2] then
|
||||
core.setting_set("mip_map", "true")
|
||||
core.setting_set("anisotropic_filter", "false")
|
||||
core.settings:set("mip_map", "true")
|
||||
core.settings:set("anisotropic_filter", "false")
|
||||
ddhandled = true
|
||||
elseif fields["dd_mipmap"] == labels.mipmap[3] then
|
||||
core.setting_set("mip_map", "true")
|
||||
core.setting_set("anisotropic_filter", "true")
|
||||
core.settings:set("mip_map", "true")
|
||||
core.settings:set("anisotropic_filter", "true")
|
||||
ddhandled = true
|
||||
end
|
||||
if fields["dd_antialiasing"] then
|
||||
core.setting_set("fsaa",
|
||||
core.settings:set("fsaa",
|
||||
antialiasing_fname_to_name(fields["dd_antialiasing"]))
|
||||
ddhandled = true
|
||||
end
|
||||
if fields["dd_touchthreshold"] then
|
||||
core.setting_set("touchscreen_threshold", fields["dd_touchthreshold"])
|
||||
core.settings:set("touchscreen_threshold", fields["dd_touchthreshold"])
|
||||
ddhandled = true
|
||||
end
|
||||
|
||||
|
||||
@@ -25,12 +25,12 @@ local function get_formspec(tabview, name, tabdata)
|
||||
local retval =
|
||||
"label[9.5,0;".. fgettext("Name / Password") .. "]" ..
|
||||
"field[0.25,3.35;5.5,0.5;te_address;;" ..
|
||||
core.formspec_escape(core.setting_get("address")) .."]" ..
|
||||
core.formspec_escape(core.settings:get("address")) .."]" ..
|
||||
"field[5.75,3.35;2.25,0.5;te_port;;" ..
|
||||
core.formspec_escape(core.setting_get("remote_port")) .."]" ..
|
||||
core.formspec_escape(core.settings:get("remote_port")) .."]" ..
|
||||
"button[10,2.6;2,1.5;btn_mp_connect;".. fgettext("Connect") .. "]" ..
|
||||
"field[9.8,1;2.6,0.5;te_name;;" ..
|
||||
core.formspec_escape(core.setting_get("name")) .."]" ..
|
||||
core.formspec_escape(core.settings:get("name")) .."]" ..
|
||||
"pwdfield[9.8,2;2.6,0.5;te_pwd;]"
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||
|
||||
retval = retval .. "tablecolumns[" ..
|
||||
image_column(fgettext("Favorite"), "favorite") .. ";" ..
|
||||
image_column(fgettext("Ping"), "") .. ",padding=0.25;" ..
|
||||
"color,span=3;" ..
|
||||
"text,align=right;" .. -- clients
|
||||
"text,align=center,padding=0.25;" .. -- "/"
|
||||
@@ -70,9 +71,9 @@ local function get_formspec(tabview, name, tabdata)
|
||||
end
|
||||
end
|
||||
end
|
||||
retval = retval .. render_favorite(menudata.favorites[1], (#favs > 0))
|
||||
retval = retval .. render_serverlist_row(menudata.favorites[1], (#favs > 0))
|
||||
for i = 2, #menudata.favorites do
|
||||
retval = retval .. "," .. render_favorite(menudata.favorites[i], (i <= #favs))
|
||||
retval = retval .. "," .. render_serverlist_row(menudata.favorites[i], (i <= #favs))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -88,9 +89,9 @@ local function get_formspec(tabview, name, tabdata)
|
||||
-- checkboxes
|
||||
retval = retval ..
|
||||
"checkbox[8.0,3.9;cb_creative;".. fgettext("Creative Mode") .. ";" ..
|
||||
dump(core.setting_getbool("creative_mode")) .. "]"..
|
||||
dump(core.settings:get_bool("creative_mode")) .. "]"..
|
||||
"checkbox[8.0,4.4;cb_damage;".. fgettext("Enable Damage") .. ";" ..
|
||||
dump(core.setting_getbool("enable_damage")) .. "]"
|
||||
dump(core.settings:get_bool("enable_damage")) .. "]"
|
||||
-- buttons
|
||||
retval = retval ..
|
||||
"button[0,3.7;8,1.5;btn_start_singleplayer;" .. fgettext("Start Singleplayer") .. "]" ..
|
||||
@@ -127,8 +128,8 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
end
|
||||
|
||||
if address and port then
|
||||
core.setting_set("address", address)
|
||||
core.setting_set("remote_port", port)
|
||||
core.settings:set("address", address)
|
||||
core.settings:set("remote_port", port)
|
||||
end
|
||||
tabdata.fav_selected = event.row
|
||||
end
|
||||
@@ -144,18 +145,18 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
asyncOnlineFavourites()
|
||||
tabdata.fav_selected = nil
|
||||
|
||||
core.setting_set("address", "")
|
||||
core.setting_set("remote_port", "30000")
|
||||
core.settings:set("address", "")
|
||||
core.settings:set("remote_port", "30000")
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.cb_creative then
|
||||
core.setting_set("creative_mode", fields.cb_creative)
|
||||
core.settings:set("creative_mode", fields.cb_creative)
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.cb_damage then
|
||||
core.setting_set("enable_damage", fields.cb_damage)
|
||||
core.settings:set("enable_damage", fields.cb_damage)
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -185,12 +186,12 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
|
||||
gamedata.selected_world = 0
|
||||
|
||||
core.setting_set("address", fields.te_address)
|
||||
core.setting_set("remote_port", fields.te_port)
|
||||
|
||||
core.start()
|
||||
return true
|
||||
end
|
||||
core.settings:set("address", fields.te_address)
|
||||
core.settings:set("remote_port", fields.te_port)
|
||||
|
||||
core.start()
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.btn_config_sp_world then
|
||||
local configdialog = create_configure_world_dlg(1)
|
||||
|
||||
@@ -54,9 +54,9 @@ local function get_formspec(tabview, name, tabdata)
|
||||
local retval = "label[4,-0.25;" .. fgettext("Select texture pack:") .. "]" ..
|
||||
"textlist[4,0.25;7.5,5.0;TPs;"
|
||||
|
||||
local current_texture_path = core.setting_get("texture_path")
|
||||
local current_texture_path = core.settings:get("texture_path")
|
||||
local list = filter_texture_pack_list(core.get_dir_list(core.get_texturepath(), true))
|
||||
local index = tonumber(core.setting_get("mainmenu_last_selected_TP"))
|
||||
local index = tonumber(core.settings:get("mainmenu_last_selected_TP"))
|
||||
|
||||
if not index then index = 1 end
|
||||
|
||||
@@ -73,7 +73,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||
if not file_exists(infofile) then
|
||||
infofile = current_texture_path .. DIR_DELIM .. "info.txt"
|
||||
if file_exists(infofile) then
|
||||
core.log("info.txt is depreciated. description.txt should be used instead.")
|
||||
core.log("deprecated", "info.txt is deprecated. description.txt should be used instead.")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -96,8 +96,8 @@ local function get_formspec(tabview, name, tabdata)
|
||||
return retval ..
|
||||
render_texture_pack_list(list) ..
|
||||
";" .. index .. "]" ..
|
||||
"image[0.25,0.25;4.0,3.7;" .. core.formspec_escape(screenfile or no_screenshot) .. "]" ..
|
||||
"textarea[0.6,3.5;3.7,1.5;;" .. core.formspec_escape(infotext or "") .. ";]"
|
||||
"image[0.25,0.25;4.05,2.7;" .. core.formspec_escape(screenfile or no_screenshot) .. "]" ..
|
||||
"textarea[0.6,2.85;3.7,1.5;;" .. core.formspec_escape(infotext or "") .. ";]"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -106,7 +106,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
local event = core.explode_textlist_event(fields["TPs"])
|
||||
if event.type == "CHG" or event.type == "DCL" then
|
||||
local index = core.get_textlist_index("TPs")
|
||||
core.setting_set("mainmenu_last_selected_TP", index)
|
||||
core.settings:set("mainmenu_last_selected_TP", index)
|
||||
local list = filter_texture_pack_list(core.get_dir_list(core.get_texturepath(), true))
|
||||
local current_index = core.get_textlist_index("TPs")
|
||||
if current_index and #list >= current_index then
|
||||
@@ -114,7 +114,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||
if list[current_index] == fgettext("None") then
|
||||
new_path = ""
|
||||
end
|
||||
core.setting_set("texture_path", new_path)
|
||||
core.settings:set("texture_path", new_path)
|
||||
end
|
||||
end
|
||||
return true
|
||||
|
||||
@@ -24,7 +24,7 @@ function mm_texture.init()
|
||||
DIR_DELIM .. "pack" .. DIR_DELIM
|
||||
mm_texture.basetexturedir = mm_texture.defaulttexturedir
|
||||
|
||||
mm_texture.texturepack = core.setting_get("texture_path")
|
||||
mm_texture.texturepack = core.settings:get("texture_path")
|
||||
|
||||
mm_texture.gameid = nil
|
||||
end
|
||||
@@ -61,7 +61,7 @@ function mm_texture.reset()
|
||||
mm_texture.set_generic("header")
|
||||
|
||||
if not have_bg then
|
||||
if core.setting_getbool("menu_clouds") then
|
||||
if core.settings:get_bool("menu_clouds") then
|
||||
core.set_clouds(true)
|
||||
else
|
||||
mm_texture.set_dirt_bg()
|
||||
@@ -88,7 +88,7 @@ function mm_texture.update_game(gamedetails)
|
||||
|
||||
if not have_bg then
|
||||
|
||||
if core.setting_getbool("menu_clouds") then
|
||||
if core.settings:get_bool("menu_clouds") then
|
||||
core.set_clouds(true)
|
||||
else
|
||||
mm_texture.set_dirt_bg()
|
||||
|
||||
80
builtin/profiler/init.lua
Normal file
80
builtin/profiler/init.lua
Normal file
@@ -0,0 +1,80 @@
|
||||
--Minetest
|
||||
--Copyright (C) 2016 T4im
|
||||
--
|
||||
--This program is free software; you can redistribute it and/or modify
|
||||
--it under the terms of the GNU Lesser General Public License as published by
|
||||
--the Free Software Foundation; either version 2.1 of the License, or
|
||||
--(at your option) any later version.
|
||||
--
|
||||
--This program is distributed in the hope that it will be useful,
|
||||
--but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
--GNU Lesser General Public License for more details.
|
||||
--
|
||||
--You should have received a copy of the GNU Lesser General Public License along
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
local function get_bool_default(name, default)
|
||||
local val = core.settings:get_bool(name)
|
||||
if val == nil then
|
||||
return default
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
local profiler_path = core.get_builtin_path()..DIR_DELIM.."profiler"..DIR_DELIM
|
||||
local profiler = {}
|
||||
local sampler = assert(loadfile(profiler_path .. "sampling.lua"))(profiler)
|
||||
local instrumentation = assert(loadfile(profiler_path .. "instrumentation.lua"))(profiler, sampler, get_bool_default)
|
||||
local reporter = dofile(profiler_path .. "reporter.lua")
|
||||
profiler.instrument = instrumentation.instrument
|
||||
|
||||
---
|
||||
-- Delayed registration of the /profiler chat command
|
||||
-- Is called later, after `core.register_chatcommand` was set up.
|
||||
--
|
||||
function profiler.init_chatcommand()
|
||||
local instrument_profiler = get_bool_default("instrument.profiler", false)
|
||||
if instrument_profiler then
|
||||
instrumentation.init_chatcommand()
|
||||
end
|
||||
|
||||
local param_usage = "print [filter] | dump [filter] | save [format [filter]] | reset"
|
||||
core.register_chatcommand("profiler", {
|
||||
description = "handle the profiler and profiling data",
|
||||
params = param_usage,
|
||||
privs = { server=true },
|
||||
func = function(name, param)
|
||||
local command, arg0 = string.match(param, "([^ ]+) ?(.*)")
|
||||
local args = arg0 and string.split(arg0, " ")
|
||||
|
||||
if command == "dump" then
|
||||
core.log("action", reporter.print(sampler.profile, arg0))
|
||||
return true, "Statistics written to action log"
|
||||
elseif command == "print" then
|
||||
return true, reporter.print(sampler.profile, arg0)
|
||||
elseif command == "save" then
|
||||
return reporter.save(sampler.profile, args[1] or "txt", args[2])
|
||||
elseif command == "reset" then
|
||||
sampler.reset()
|
||||
return true, "Statistics were reset"
|
||||
end
|
||||
|
||||
return false, string.format(
|
||||
"Usage: %s\n" ..
|
||||
"Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).",
|
||||
param_usage
|
||||
)
|
||||
end
|
||||
})
|
||||
|
||||
if not instrument_profiler then
|
||||
instrumentation.init_chatcommand()
|
||||
end
|
||||
end
|
||||
|
||||
sampler.init()
|
||||
instrumentation.init()
|
||||
|
||||
return profiler
|
||||
232
builtin/profiler/instrumentation.lua
Normal file
232
builtin/profiler/instrumentation.lua
Normal file
@@ -0,0 +1,232 @@
|
||||
--Minetest
|
||||
--Copyright (C) 2016 T4im
|
||||
--
|
||||
--This program is free software; you can redistribute it and/or modify
|
||||
--it under the terms of the GNU Lesser General Public License as published by
|
||||
--the Free Software Foundation; either version 2.1 of the License, or
|
||||
--(at your option) any later version.
|
||||
--
|
||||
--This program is distributed in the hope that it will be useful,
|
||||
--but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
--GNU Lesser General Public License for more details.
|
||||
--
|
||||
--You should have received a copy of the GNU Lesser General Public License along
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
local format, pairs, type = string.format, pairs, type
|
||||
local core, get_current_modname = core, core.get_current_modname
|
||||
local profiler, sampler, get_bool_default = ...
|
||||
|
||||
local instrument_builtin = get_bool_default("instrument.builtin", false)
|
||||
|
||||
local register_functions = {
|
||||
register_globalstep = 0,
|
||||
register_playerevent = 0,
|
||||
register_on_placenode = 0,
|
||||
register_on_dignode = 0,
|
||||
register_on_punchnode = 0,
|
||||
register_on_generated = 0,
|
||||
register_on_newplayer = 0,
|
||||
register_on_dieplayer = 0,
|
||||
register_on_respawnplayer = 0,
|
||||
register_on_prejoinplayer = 0,
|
||||
register_on_joinplayer = 0,
|
||||
register_on_leaveplayer = 0,
|
||||
register_on_cheat = 0,
|
||||
register_on_chat_message = 0,
|
||||
register_on_player_receive_fields = 0,
|
||||
register_on_craft = 0,
|
||||
register_craft_predict = 0,
|
||||
register_on_protection_violation = 0,
|
||||
register_on_item_eat = 0,
|
||||
register_on_punchplayer = 0,
|
||||
register_on_player_hpchange = 0,
|
||||
}
|
||||
|
||||
---
|
||||
-- Create an unique instrument name.
|
||||
-- Generate a missing label with a running index number.
|
||||
--
|
||||
local counts = {}
|
||||
local function generate_name(def)
|
||||
local class, label, func_name = def.class, def.label, def.func_name
|
||||
if label then
|
||||
if class or func_name then
|
||||
return format("%s '%s' %s", class or "", label, func_name or ""):trim()
|
||||
end
|
||||
return format("%s", label):trim()
|
||||
elseif label == false then
|
||||
return format("%s", class or func_name):trim()
|
||||
end
|
||||
|
||||
local index_id = def.mod .. (class or func_name)
|
||||
local index = counts[index_id] or 1
|
||||
counts[index_id] = index + 1
|
||||
return format("%s[%d] %s", class or func_name, index, class and func_name or ""):trim()
|
||||
end
|
||||
|
||||
---
|
||||
-- Keep `measure` and the closure in `instrument` lean, as these, and their
|
||||
-- directly called functions are the overhead that is caused by instrumentation.
|
||||
--
|
||||
local time, log = core.get_us_time, sampler.log
|
||||
local function measure(modname, instrument_name, start, ...)
|
||||
log(modname, instrument_name, time() - start)
|
||||
return ...
|
||||
end
|
||||
--- Automatically instrument a function to measure and log to the sampler.
|
||||
-- def = {
|
||||
-- mod = "",
|
||||
-- class = "",
|
||||
-- func_name = "",
|
||||
-- -- if nil, will create a label based on registration order
|
||||
-- label = "" | false,
|
||||
-- }
|
||||
local function instrument(def)
|
||||
if not def or not def.func then
|
||||
return
|
||||
end
|
||||
def.mod = def.mod or get_current_modname()
|
||||
local modname = def.mod
|
||||
local instrument_name = generate_name(def)
|
||||
local func = def.func
|
||||
|
||||
if not instrument_builtin and modname == "*builtin*" then
|
||||
return func
|
||||
end
|
||||
|
||||
return function(...)
|
||||
-- This tail-call allows passing all return values of `func`
|
||||
-- also called https://en.wikipedia.org/wiki/Continuation_passing_style
|
||||
-- Compared to table creation and unpacking it won't lose `nil` returns
|
||||
-- and is expected to be faster
|
||||
-- `measure` will be executed after time() and func(...)
|
||||
return measure(modname, instrument_name, time(), func(...))
|
||||
end
|
||||
end
|
||||
|
||||
local function can_be_called(func)
|
||||
-- It has to be a function or callable table
|
||||
return type(func) == "function" or
|
||||
((type(func) == "table" or type(func) == "userdata") and
|
||||
getmetatable(func) and getmetatable(func).__call)
|
||||
end
|
||||
|
||||
local function assert_can_be_called(func, func_name, level)
|
||||
if not can_be_called(func) then
|
||||
-- Then throw an *helpful* error, by pointing on our caller instead of us.
|
||||
error(format("Invalid argument to %s. Expected function-like type instead of '%s'.", func_name, type(func)), level + 1)
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- Wraps a registration function `func` in such a way,
|
||||
-- that it will automatically instrument any callback function passed as first argument.
|
||||
--
|
||||
local function instrument_register(func, func_name)
|
||||
local register_name = func_name:gsub("^register_", "", 1)
|
||||
return function(callback, ...)
|
||||
assert_can_be_called(callback, func_name, 2)
|
||||
register_functions[func_name] = register_functions[func_name] + 1
|
||||
return func(instrument {
|
||||
func = callback,
|
||||
func_name = register_name
|
||||
}), ...
|
||||
end
|
||||
end
|
||||
|
||||
local function init_chatcommand()
|
||||
if get_bool_default("instrument.chatcommand", true) then
|
||||
local orig_register_chatcommand = core.register_chatcommand
|
||||
core.register_chatcommand = function(cmd, def)
|
||||
def.func = instrument {
|
||||
func = def.func,
|
||||
label = "/" .. cmd,
|
||||
}
|
||||
orig_register_chatcommand(cmd, def)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- Start instrumenting selected functions
|
||||
--
|
||||
local function init()
|
||||
if get_bool_default("instrument.entity", true) then
|
||||
-- Explicitly declare entity api-methods.
|
||||
-- Simple iteration would ignore lookup via __index.
|
||||
local entity_instrumentation = {
|
||||
"on_activate",
|
||||
"on_step",
|
||||
"on_punch",
|
||||
"rightclick",
|
||||
"get_staticdata",
|
||||
}
|
||||
-- Wrap register_entity() to instrument them on registration.
|
||||
local orig_register_entity = core.register_entity
|
||||
core.register_entity = function(name, prototype)
|
||||
local modname = get_current_modname()
|
||||
for _, func_name in pairs(entity_instrumentation) do
|
||||
prototype[func_name] = instrument {
|
||||
func = prototype[func_name],
|
||||
mod = modname,
|
||||
func_name = func_name,
|
||||
label = prototype.label,
|
||||
}
|
||||
end
|
||||
orig_register_entity(name,prototype)
|
||||
end
|
||||
end
|
||||
|
||||
if get_bool_default("instrument.abm", true) then
|
||||
-- Wrap register_abm() to automatically instrument abms.
|
||||
local orig_register_abm = core.register_abm
|
||||
core.register_abm = function(spec)
|
||||
spec.action = instrument {
|
||||
func = spec.action,
|
||||
class = "ABM",
|
||||
label = spec.label,
|
||||
}
|
||||
orig_register_abm(spec)
|
||||
end
|
||||
end
|
||||
|
||||
if get_bool_default("instrument.lbm", true) then
|
||||
-- Wrap register_lbm() to automatically instrument lbms.
|
||||
local orig_register_lbm = core.register_lbm
|
||||
core.register_lbm = function(spec)
|
||||
spec.action = instrument {
|
||||
func = spec.action,
|
||||
class = "LBM",
|
||||
label = spec.label or spec.name,
|
||||
}
|
||||
orig_register_lbm(spec)
|
||||
end
|
||||
end
|
||||
|
||||
if get_bool_default("instrument.global_callback", true) then
|
||||
for func_name, _ in pairs(register_functions) do
|
||||
core[func_name] = instrument_register(core[func_name], func_name)
|
||||
end
|
||||
end
|
||||
|
||||
if get_bool_default("instrument.profiler", false) then
|
||||
-- Measure overhead of instrumentation, but keep it down for functions
|
||||
-- So keep the `return` for better optimization.
|
||||
profiler.empty_instrument = instrument {
|
||||
func = function() return end,
|
||||
mod = "*profiler*",
|
||||
class = "Instrumentation overhead",
|
||||
label = false,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
register_functions = register_functions,
|
||||
instrument = instrument,
|
||||
init = init,
|
||||
init_chatcommand = init_chatcommand,
|
||||
}
|
||||
277
builtin/profiler/reporter.lua
Normal file
277
builtin/profiler/reporter.lua
Normal file
@@ -0,0 +1,277 @@
|
||||
--Minetest
|
||||
--Copyright (C) 2016 T4im
|
||||
--
|
||||
--This program is free software; you can redistribute it and/or modify
|
||||
--it under the terms of the GNU Lesser General Public License as published by
|
||||
--the Free Software Foundation; either version 2.1 of the License, or
|
||||
--(at your option) any later version.
|
||||
--
|
||||
--This program is distributed in the hope that it will be useful,
|
||||
--but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
--GNU Lesser General Public License for more details.
|
||||
--
|
||||
--You should have received a copy of the GNU Lesser General Public License along
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
local DIR_DELIM, LINE_DELIM = DIR_DELIM, "\n"
|
||||
local table, unpack, string, pairs, io, os = table, unpack, string, pairs, io, os
|
||||
local rep, sprintf, tonumber = string.rep, string.format, tonumber
|
||||
local core, settings = core, core.settings
|
||||
local reporter = {}
|
||||
|
||||
---
|
||||
-- Shorten a string. End on an ellipsis if shortened.
|
||||
--
|
||||
local function shorten(str, length)
|
||||
if str and str:len() > length then
|
||||
return "..." .. str:sub(-(length-3))
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
local function filter_matches(filter, text)
|
||||
return not filter or string.match(text, filter)
|
||||
end
|
||||
|
||||
local function format_number(number, fmt)
|
||||
number = tonumber(number)
|
||||
if not number then
|
||||
return "N/A"
|
||||
end
|
||||
return sprintf(fmt or "%d", number)
|
||||
end
|
||||
|
||||
local Formatter = {
|
||||
new = function(self, object)
|
||||
object = object or {}
|
||||
object.out = {} -- output buffer
|
||||
self.__index = self
|
||||
return setmetatable(object, self)
|
||||
end,
|
||||
__tostring = function (self)
|
||||
return table.concat(self.out, LINE_DELIM)
|
||||
end,
|
||||
print = function(self, text, ...)
|
||||
if (...) then
|
||||
text = sprintf(text, ...)
|
||||
end
|
||||
|
||||
if text then
|
||||
-- Avoid format unicode issues.
|
||||
text = text:gsub("Ms", "µs")
|
||||
end
|
||||
|
||||
table.insert(self.out, text or LINE_DELIM)
|
||||
end,
|
||||
flush = function(self)
|
||||
table.insert(self.out, LINE_DELIM)
|
||||
local text = table.concat(self.out, LINE_DELIM)
|
||||
self.out = {}
|
||||
return text
|
||||
end
|
||||
}
|
||||
|
||||
local widths = { 55, 9, 9, 9, 5, 5, 5 }
|
||||
local txt_row_format = sprintf(" %%-%ds | %%%ds | %%%ds | %%%ds | %%%ds | %%%ds | %%%ds", unpack(widths))
|
||||
|
||||
local HR = {}
|
||||
for i=1, #widths do
|
||||
HR[i]= rep("-", widths[i])
|
||||
end
|
||||
-- ' | ' should break less with github than '-+-', when people are pasting there
|
||||
HR = sprintf("-%s-", table.concat(HR, " | "))
|
||||
|
||||
local TxtFormatter = Formatter:new {
|
||||
format_row = function(self, modname, instrument_name, statistics)
|
||||
local label
|
||||
if instrument_name then
|
||||
label = shorten(instrument_name, widths[1] - 5)
|
||||
label = sprintf(" - %s %s", label, rep(".", widths[1] - 5 - label:len()))
|
||||
else -- Print mod_stats
|
||||
label = shorten(modname, widths[1] - 2) .. ":"
|
||||
end
|
||||
|
||||
self:print(txt_row_format, label,
|
||||
format_number(statistics.time_min),
|
||||
format_number(statistics.time_max),
|
||||
format_number(statistics:get_time_avg()),
|
||||
format_number(statistics.part_min, "%.1f"),
|
||||
format_number(statistics.part_max, "%.1f"),
|
||||
format_number(statistics:get_part_avg(), "%.1f")
|
||||
)
|
||||
end,
|
||||
format = function(self, filter)
|
||||
local profile = self.profile
|
||||
self:print("Values below show absolute/relative times spend per server step by the instrumented function.")
|
||||
self:print("A total of %d samples were taken", profile.stats_total.samples)
|
||||
|
||||
if filter then
|
||||
self:print("The output is limited to '%s'", filter)
|
||||
end
|
||||
|
||||
self:print()
|
||||
self:print(
|
||||
txt_row_format,
|
||||
"instrumentation", "min Ms", "max Ms", "avg Ms", "min %", "max %", "avg %"
|
||||
)
|
||||
self:print(HR)
|
||||
for modname,mod_stats in pairs(profile.stats) do
|
||||
if filter_matches(filter, modname) then
|
||||
self:format_row(modname, nil, mod_stats)
|
||||
|
||||
if mod_stats.instruments ~= nil then
|
||||
for instrument_name, instrument_stats in pairs(mod_stats.instruments) do
|
||||
self:format_row(nil, instrument_name, instrument_stats)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self:print(HR)
|
||||
if not filter then
|
||||
self:format_row("total", nil, profile.stats_total)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local CsvFormatter = Formatter:new {
|
||||
format_row = function(self, modname, instrument_name, statistics)
|
||||
self:print(
|
||||
"%q,%q,%d,%d,%d,%d,%d,%f,%f,%f",
|
||||
modname, instrument_name,
|
||||
statistics.samples,
|
||||
statistics.time_min,
|
||||
statistics.time_max,
|
||||
statistics:get_time_avg(),
|
||||
statistics.time_all,
|
||||
statistics.part_min,
|
||||
statistics.part_max,
|
||||
statistics:get_part_avg()
|
||||
)
|
||||
end,
|
||||
format = function(self, filter)
|
||||
self:print(
|
||||
"%q,%q,%q,%q,%q,%q,%q,%q,%q,%q",
|
||||
"modname", "instrumentation",
|
||||
"samples",
|
||||
"time min µs",
|
||||
"time max µs",
|
||||
"time avg µs",
|
||||
"time all µs",
|
||||
"part min %",
|
||||
"part max %",
|
||||
"part avg %"
|
||||
)
|
||||
for modname, mod_stats in pairs(self.profile.stats) do
|
||||
if filter_matches(filter, modname) then
|
||||
self:format_row(modname, "*", mod_stats)
|
||||
|
||||
if mod_stats.instruments ~= nil then
|
||||
for instrument_name, instrument_stats in pairs(mod_stats.instruments) do
|
||||
self:format_row(modname, instrument_name, instrument_stats)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local function format_statistics(profile, format, filter)
|
||||
local formatter
|
||||
if format == "csv" then
|
||||
formatter = CsvFormatter:new {
|
||||
profile = profile
|
||||
}
|
||||
else
|
||||
formatter = TxtFormatter:new {
|
||||
profile = profile
|
||||
}
|
||||
end
|
||||
formatter:format(filter)
|
||||
return formatter:flush()
|
||||
end
|
||||
|
||||
---
|
||||
-- Format the profile ready for display and
|
||||
-- @return string to be printed to the console
|
||||
--
|
||||
function reporter.print(profile, filter)
|
||||
if filter == "" then filter = nil end
|
||||
return format_statistics(profile, "txt", filter)
|
||||
end
|
||||
|
||||
---
|
||||
-- Serialize the profile data and
|
||||
-- @return serialized data to be saved to a file
|
||||
--
|
||||
local function serialize_profile(profile, format, filter)
|
||||
if format == "lua" or format == "json" or format == "json_pretty" then
|
||||
local stats = filter and {} or profile.stats
|
||||
if filter then
|
||||
for modname, mod_stats in pairs(profile.stats) do
|
||||
if filter_matches(filter, modname) then
|
||||
stats[modname] = mod_stats
|
||||
end
|
||||
end
|
||||
end
|
||||
if format == "lua" then
|
||||
return core.serialize(stats)
|
||||
elseif format == "json" then
|
||||
return core.write_json(stats)
|
||||
elseif format == "json_pretty" then
|
||||
return core.write_json(stats, true)
|
||||
end
|
||||
end
|
||||
-- Fall back to textual formats.
|
||||
return format_statistics(profile, format, filter)
|
||||
end
|
||||
|
||||
local worldpath = core.get_worldpath()
|
||||
local function get_save_path(format, filter)
|
||||
local report_path = settings:get("profiler.report_path") or ""
|
||||
if report_path ~= "" then
|
||||
core.mkdir(sprintf("%s%s%s", worldpath, DIR_DELIM, report_path))
|
||||
end
|
||||
return (sprintf(
|
||||
"%s/%s/profile-%s%s.%s",
|
||||
worldpath,
|
||||
report_path,
|
||||
os.date("%Y%m%dT%H%M%S"),
|
||||
filter and ("-" .. filter) or "",
|
||||
format
|
||||
):gsub("[/\\]+", DIR_DELIM))-- Clean up delims
|
||||
end
|
||||
|
||||
---
|
||||
-- Save the profile to the world path.
|
||||
-- @return success, log message
|
||||
--
|
||||
function reporter.save(profile, format, filter)
|
||||
if not format or format == "" then
|
||||
format = settings:get("profiler.default_report_format") or "txt"
|
||||
end
|
||||
if filter == "" then
|
||||
filter = nil
|
||||
end
|
||||
|
||||
local path = get_save_path(format, filter)
|
||||
|
||||
local output, io_err = io.open(path, "w")
|
||||
if not output then
|
||||
return false, "Saving of profile failed with: " .. io_err
|
||||
end
|
||||
local content, err = serialize_profile(profile, format, filter)
|
||||
if not content then
|
||||
output:close()
|
||||
return false, "Saving of profile failed with: " .. err
|
||||
end
|
||||
output:write(content)
|
||||
output:close()
|
||||
|
||||
local logmessage = "Profile saved to " .. path
|
||||
core.log("action", logmessage)
|
||||
return true, logmessage
|
||||
end
|
||||
|
||||
return reporter
|
||||
206
builtin/profiler/sampling.lua
Normal file
206
builtin/profiler/sampling.lua
Normal file
@@ -0,0 +1,206 @@
|
||||
--Minetest
|
||||
--Copyright (C) 2016 T4im
|
||||
--
|
||||
--This program is free software; you can redistribute it and/or modify
|
||||
--it under the terms of the GNU Lesser General Public License as published by
|
||||
--the Free Software Foundation; either version 2.1 of the License, or
|
||||
--(at your option) any later version.
|
||||
--
|
||||
--This program is distributed in the hope that it will be useful,
|
||||
--but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
--GNU Lesser General Public License for more details.
|
||||
--
|
||||
--You should have received a copy of the GNU Lesser General Public License along
|
||||
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
local setmetatable = setmetatable
|
||||
local pairs, format = pairs, string.format
|
||||
local min, max, huge = math.min, math.max, math.huge
|
||||
local core = core
|
||||
|
||||
local profiler = ...
|
||||
-- Split sampler and profile up, to possibly allow for rotation later.
|
||||
local sampler = {}
|
||||
local profile
|
||||
local stats_total
|
||||
local logged_time, logged_data
|
||||
|
||||
local _stat_mt = {
|
||||
get_time_avg = function(self)
|
||||
return self.time_all/self.samples
|
||||
end,
|
||||
get_part_avg = function(self)
|
||||
if not self.part_all then
|
||||
return 100 -- Extra handling for "total"
|
||||
end
|
||||
return self.part_all/self.samples
|
||||
end,
|
||||
}
|
||||
_stat_mt.__index = _stat_mt
|
||||
|
||||
function sampler.reset()
|
||||
-- Accumulated logged time since last sample.
|
||||
-- This helps determining, the relative time a mod used up.
|
||||
logged_time = 0
|
||||
-- The measurements taken through instrumentation since last sample.
|
||||
logged_data = {}
|
||||
|
||||
profile = {
|
||||
-- Current mod statistics (max/min over the entire mod lifespan)
|
||||
-- Mod specific instrumentation statistics are nested within.
|
||||
stats = {},
|
||||
-- Current stats over all mods.
|
||||
stats_total = setmetatable({
|
||||
samples = 0,
|
||||
time_min = huge,
|
||||
time_max = 0,
|
||||
time_all = 0,
|
||||
part_min = 100,
|
||||
part_max = 100
|
||||
}, _stat_mt)
|
||||
}
|
||||
stats_total = profile.stats_total
|
||||
|
||||
-- Provide access to the most recent profile.
|
||||
sampler.profile = profile
|
||||
end
|
||||
|
||||
---
|
||||
-- Log a measurement for the sampler to pick up later.
|
||||
-- Keep `log` and its often called functions lean.
|
||||
-- It will directly add to the instrumentation overhead.
|
||||
--
|
||||
function sampler.log(modname, instrument_name, time_diff)
|
||||
if time_diff <= 0 then
|
||||
if time_diff < 0 then
|
||||
-- This **might** have happened on a semi-regular basis with huge mods,
|
||||
-- resulting in negative statistics (perhaps midnight time jumps or ntp corrections?).
|
||||
core.log("warning", format(
|
||||
"Time travel of %s::%s by %dµs.",
|
||||
modname, instrument_name, time_diff
|
||||
))
|
||||
end
|
||||
-- Throwing these away is better, than having them mess with the overall result.
|
||||
return
|
||||
end
|
||||
|
||||
local mod_data = logged_data[modname]
|
||||
if mod_data == nil then
|
||||
mod_data = {}
|
||||
logged_data[modname] = mod_data
|
||||
end
|
||||
|
||||
mod_data[instrument_name] = (mod_data[instrument_name] or 0) + time_diff
|
||||
-- Update logged time since last sample.
|
||||
logged_time = logged_time + time_diff
|
||||
end
|
||||
|
||||
---
|
||||
-- Return a requested statistic.
|
||||
-- Initialize if necessary.
|
||||
--
|
||||
local function get_statistic(stats_table, name)
|
||||
local statistic = stats_table[name]
|
||||
if statistic == nil then
|
||||
statistic = setmetatable({
|
||||
samples = 0,
|
||||
time_min = huge,
|
||||
time_max = 0,
|
||||
time_all = 0,
|
||||
part_min = 100,
|
||||
part_max = 0,
|
||||
part_all = 0,
|
||||
}, _stat_mt)
|
||||
stats_table[name] = statistic
|
||||
end
|
||||
return statistic
|
||||
end
|
||||
|
||||
---
|
||||
-- Update a statistic table
|
||||
--
|
||||
local function update_statistic(stats_table, time)
|
||||
stats_table.samples = stats_table.samples + 1
|
||||
|
||||
-- Update absolute time (µs) spend by the subject
|
||||
stats_table.time_min = min(stats_table.time_min, time)
|
||||
stats_table.time_max = max(stats_table.time_max, time)
|
||||
stats_table.time_all = stats_table.time_all + time
|
||||
|
||||
-- Update relative time (%) of this sample spend by the subject
|
||||
local current_part = (time/logged_time) * 100
|
||||
stats_table.part_min = min(stats_table.part_min, current_part)
|
||||
stats_table.part_max = max(stats_table.part_max, current_part)
|
||||
stats_table.part_all = stats_table.part_all + current_part
|
||||
end
|
||||
|
||||
---
|
||||
-- Sample all logged measurements each server step.
|
||||
-- Like any globalstep function, this should not be too heavy,
|
||||
-- but does not add to the instrumentation overhead.
|
||||
--
|
||||
local function sample(dtime)
|
||||
-- Rare, but happens and is currently of no informational value.
|
||||
if logged_time == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
for modname, instruments in pairs(logged_data) do
|
||||
local mod_stats = get_statistic(profile.stats, modname)
|
||||
if mod_stats.instruments == nil then
|
||||
-- Current statistics for each instrumentation component
|
||||
mod_stats.instruments = {}
|
||||
end
|
||||
|
||||
local mod_time = 0
|
||||
for instrument_name, time in pairs(instruments) do
|
||||
if time > 0 then
|
||||
mod_time = mod_time + time
|
||||
local instrument_stats = get_statistic(mod_stats.instruments, instrument_name)
|
||||
|
||||
-- Update time of this sample spend by the instrumented function.
|
||||
update_statistic(instrument_stats, time)
|
||||
-- Reset logged data for the next sample.
|
||||
instruments[instrument_name] = 0
|
||||
end
|
||||
end
|
||||
|
||||
-- Update time of this sample spend by this mod.
|
||||
update_statistic(mod_stats, mod_time)
|
||||
end
|
||||
|
||||
-- Update the total time spend over all mods.
|
||||
stats_total.time_min = min(stats_total.time_min, logged_time)
|
||||
stats_total.time_max = max(stats_total.time_max, logged_time)
|
||||
stats_total.time_all = stats_total.time_all + logged_time
|
||||
|
||||
stats_total.samples = stats_total.samples + 1
|
||||
logged_time = 0
|
||||
end
|
||||
|
||||
---
|
||||
-- Setup empty profile and register the sampling function
|
||||
--
|
||||
function sampler.init()
|
||||
sampler.reset()
|
||||
|
||||
if core.settings:get_bool("instrument.profiler") then
|
||||
core.register_globalstep(function()
|
||||
if logged_time == 0 then
|
||||
return
|
||||
end
|
||||
return profiler.empty_instrument()
|
||||
end)
|
||||
core.register_globalstep(profiler.instrument {
|
||||
func = sample,
|
||||
mod = "*profiler*",
|
||||
class = "Sampler (update stats)",
|
||||
label = false,
|
||||
})
|
||||
else
|
||||
core.register_globalstep(sample)
|
||||
end
|
||||
end
|
||||
|
||||
return sampler
|
||||
@@ -3,7 +3,7 @@
|
||||
# General format:
|
||||
# name (Readable name) type type_args
|
||||
#
|
||||
# Note that the parts are seperated by exactly one space
|
||||
# Note that the parts are separated by exactly one space
|
||||
#
|
||||
# `type` can be:
|
||||
# - int
|
||||
@@ -70,7 +70,7 @@ fast_move (Fast movement) bool false
|
||||
# This requires the "noclip" privilege on the server.
|
||||
noclip (Noclip) bool false
|
||||
|
||||
# Smooths camera when moving and looking around.
|
||||
# Smooths camera when looking around. Also called look or mouse smoothing.
|
||||
# Useful for recording videos.
|
||||
cinematic (Cinematic mode) bool false
|
||||
|
||||
@@ -104,6 +104,23 @@ random_input (Random input) bool false
|
||||
# Continuous forward movement (only used for testing).
|
||||
continuous_forward (Continuous forward) bool false
|
||||
|
||||
# Enable Joysticks
|
||||
enable_joysticks (Enable Joysticks) bool false
|
||||
|
||||
# The identifier of the joystick to use
|
||||
joystick_id (Joystick ID) int 0
|
||||
|
||||
# The type of joystick
|
||||
joystick_type (Joystick Type) enum auto auto,generic,xbox
|
||||
|
||||
# The time in seconds it takes between repeated events
|
||||
# when holding down a joystick button combination.
|
||||
repeat_joystick_button_time (Joystick button repetition interval) float 0.17
|
||||
|
||||
# The sensitivity of the joystick axes for moving the
|
||||
# ingame view frustum around.
|
||||
joystick_frustum_sensitivity (Joystick frustum sensitivity) float 170
|
||||
|
||||
# Key for moving the player forward.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_forward (Forward key) key KEY_KEY_W
|
||||
@@ -145,6 +162,10 @@ keymap_chat (Chat key) key KEY_KEY_T
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_cmd (Command key) key /
|
||||
|
||||
# Key for opening the chat window to type local commands.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_cmd_local (Command key) key .
|
||||
|
||||
# Key for opening the chat console.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keyman_console (Console key) key KEY_F10
|
||||
@@ -165,9 +186,33 @@ keymap_fastmove (Fast key) key KEY_KEY_J
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_noclip (Noclip key) key KEY_KEY_H
|
||||
|
||||
# Key for selecting the next item in the hotbar.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_hotbar_next (Hotbar next key) key KEY_KEY_N
|
||||
|
||||
# Key for selecting the previous item in the hotbar.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_hotbar_previous (Hotbar previous key) key KEY_KEY_B
|
||||
|
||||
# Key for muting the game.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_mute (Mute key) key KEY_KEY_M
|
||||
|
||||
# Key for increasing the volume.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_increase_volume (Inc. volume key) key
|
||||
|
||||
# Key for decreasing the volume.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_decrease_volume (Dec. volume key) key
|
||||
|
||||
# Key for toggling autorun.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_autorun (Autorun key) key
|
||||
|
||||
# Key for toggling cinematic mode.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_cinematic (Cinematic mode key) key KEY_F8
|
||||
keymap_cinematic (Cinematic mode key) key
|
||||
|
||||
# Key for toggling display of minimap.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
@@ -181,6 +226,10 @@ keymap_screenshot (Screenshot) key KEY_F12
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_drop (Drop item key) key KEY_KEY_Q
|
||||
|
||||
# Key to use view zoom when possible.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_zoom (View zoom key) key KEY_KEY_Z
|
||||
|
||||
# Key for toggling the display of the HUD.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_toggle_hud (HUD toggle key) key KEY_F1
|
||||
@@ -189,11 +238,15 @@ keymap_toggle_hud (HUD toggle key) key KEY_F1
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_toggle_chat (Chat toggle key) key KEY_F2
|
||||
|
||||
# Key for toggling the display of the large chat console.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_console (Large chat console key) key KEY_F10
|
||||
|
||||
# Key for toggling the display of the fog.
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_toggle_force_fog_off (Fog toggle key) key KEY_F3
|
||||
|
||||
# Key for toggling the camrea update. Only used for development
|
||||
# Key for toggling the camera update. Only used for development
|
||||
# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3
|
||||
keymap_toggle_update_camera (Camera update toggle key) key
|
||||
|
||||
@@ -236,7 +289,7 @@ remote_port (Remote port) int 30000 1 65535
|
||||
# Enable if you want to connect to 0.4.12 servers and before.
|
||||
# Servers starting with 0.4.13 will work, 0.4.12-dev servers may work.
|
||||
# Disabling this option will protect your password better.
|
||||
send_pre_v25_init (Support older servers) bool true
|
||||
send_pre_v25_init (Support older servers) bool false
|
||||
|
||||
# Save the map received by the client on disk.
|
||||
enable_local_map_saving (Saving map received from server) bool false
|
||||
@@ -249,12 +302,19 @@ show_entity_selectionbox (Show entity selection boxes) bool true
|
||||
# when connecting to the server.
|
||||
enable_remote_media_server (Connect to external media server) bool true
|
||||
|
||||
# Enable Lua modding support on client.
|
||||
# This support is experimental and API can change.
|
||||
enable_client_modding (Client modding) bool false
|
||||
|
||||
# URL to the server list displayed in the Multiplayer Tab.
|
||||
serverlist_url (Serverlist URL) string servers.minetest.net
|
||||
|
||||
# File in client/serverlist/ that contains your favorite servers displayed in the Multiplayer Tab.
|
||||
serverlist_file (Serverlist file) string favoriteservers.txt
|
||||
|
||||
# Maximum size of the out chat queue. 0 to disable queueing and -1 to make the queue size unlimited
|
||||
max_out_chat_queue_size (Maximum size of the out chat queue) int 20
|
||||
|
||||
[*Graphics]
|
||||
|
||||
[**In-Game]
|
||||
@@ -287,7 +347,10 @@ enable_clouds (Clouds) bool true
|
||||
enable_3d_clouds (3D clouds) bool true
|
||||
|
||||
# Method used to highlight selected object.
|
||||
node_highlighting (Node highlighting) enum box box,halo
|
||||
node_highlighting (Node highlighting) enum box box,halo,none
|
||||
|
||||
# Adds particles when digging a node.
|
||||
enable_particles (Digging particles) bool true
|
||||
|
||||
[***Filtering]
|
||||
|
||||
@@ -322,12 +385,20 @@ texture_min_size (Minimum texture size for filters) int 64
|
||||
# when set to higher number than 0.
|
||||
fsaa (FSAA) enum 0 0,1,2,4,8,16
|
||||
|
||||
# Undersampling is similar to using lower screen resolution, but it applies
|
||||
# to the game world only, keeping the GUI intact.
|
||||
# It should give significant performance boost at the cost of less detailed image.
|
||||
undersampling (Undersampling) enum 0 0,2,3,4
|
||||
|
||||
[***Shaders]
|
||||
|
||||
# Shaders allow advanced visul effects and may increase performance on some video cards.
|
||||
# Thy only work with the OpenGL video backend.
|
||||
# Shaders allow advanced visual effects and may increase performance on some video cards.
|
||||
# This only works with the OpenGL video backend.
|
||||
enable_shaders (Shaders) bool true
|
||||
|
||||
# Path to shader directory. If no path is defined, default location will be used.
|
||||
shader_path (Shader path) path
|
||||
|
||||
[****Tone Mapping]
|
||||
|
||||
# Enables filmic tone mapping
|
||||
@@ -362,7 +433,7 @@ enable_parallax_occlusion (Parallax occlusion) bool false
|
||||
parallax_occlusion_mode (Parallax occlusion mode) int 1 0 1
|
||||
|
||||
# Strength of parallax.
|
||||
3d_parallax_strength (Parallax occlusion strength) float 0.025
|
||||
3d_paralax_strength (Parallax occlusion strength) float 0.025
|
||||
|
||||
# Number of parallax occlusion iterations.
|
||||
parallax_occlusion_iterations (Parallax occlusion iterations) int 4
|
||||
@@ -403,8 +474,7 @@ fps_max (Maximum FPS) int 60
|
||||
pause_fps_max (FPS in pause menu) int 20
|
||||
|
||||
# View distance in nodes.
|
||||
# Min = 20
|
||||
viewing_range (Viewing range) int 100
|
||||
viewing_range (Viewing range) int 100 20 4000
|
||||
|
||||
# Width component of the initial window size.
|
||||
screenW (Screen width) int 800
|
||||
@@ -412,6 +482,9 @@ screenW (Screen width) int 800
|
||||
# Height component of the initial window size.
|
||||
screenH (Screen height) int 600
|
||||
|
||||
# Save window size automatically when modified.
|
||||
autosave_screensize (Autosave Screen Size) bool true
|
||||
|
||||
# Fullscreen mode.
|
||||
fullscreen (Full screen) bool false
|
||||
|
||||
@@ -424,9 +497,13 @@ vsync (V-Sync) bool false
|
||||
# Field of view in degrees.
|
||||
fov (Field of view) int 72 30 160
|
||||
|
||||
# Adjust the gamma encoding for the light tables. Lower numbers are brighter.
|
||||
# Field of view while zooming in degrees.
|
||||
# This requires the "zoom" privilege on the server.
|
||||
zoom_fov (Field of view for zoom) int 15 7 160
|
||||
|
||||
# Adjust the gamma encoding for the light tables. Higher numbers are brighter.
|
||||
# This setting is for the client only and is ignored by the server.
|
||||
display_gamma (Gamma) float 1.8 1.0 3.0
|
||||
display_gamma (Gamma) float 2.2 1.0 3.0
|
||||
|
||||
# Path to texture directory. All textures are first searched from here.
|
||||
texture_path (Texture path) path
|
||||
@@ -441,13 +518,13 @@ cloud_height (Cloud height) int 120
|
||||
# Values larger than 26 will start to produce sharp cutoffs at cloud area corners.
|
||||
cloud_radius (Cloud radius) int 12
|
||||
|
||||
# Multiplier for view bobbing.
|
||||
# Enable view bobbing and amount of view bobbing.
|
||||
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
|
||||
view_bobbing_amount (View bobbing) float 1.0
|
||||
view_bobbing_amount (View bobbing factor) float 1.0
|
||||
|
||||
# Multiplier for fall bobbing.
|
||||
# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.
|
||||
fall_bobbing_amount (Fall bobbing) float 0.0
|
||||
fall_bobbing_amount (Fall bobbing factor) float 0.0
|
||||
|
||||
# 3D support.
|
||||
# Currently supported:
|
||||
@@ -459,6 +536,9 @@ fall_bobbing_amount (Fall bobbing) float 0.0
|
||||
# - pageflip: quadbuffer based 3d.
|
||||
3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,pageflip
|
||||
|
||||
# In-game chat console height, between 0.1 (10%) and 1.0 (100%).
|
||||
console_height (Console height) float 1.0 0.1 1.0
|
||||
|
||||
# In-game chat console background color (R,G,B).
|
||||
console_color (Console color) string (0,0,0)
|
||||
|
||||
@@ -484,9 +564,21 @@ desynchronize_mapblock_texture_animation (Desynchronize block animation) bool tr
|
||||
# Useful if there's something to be displayed right or left of hotbar.
|
||||
hud_hotbar_max_width (Maximum hotbar width) float 1.0
|
||||
|
||||
# Modifies the size of the hudbar elements.
|
||||
hud_scaling (HUD scale factor) float 1.0
|
||||
|
||||
# Enables caching of facedir rotated meshes.
|
||||
enable_mesh_cache (Mesh cache) bool false
|
||||
|
||||
# Delay between mesh updates on the client in ms. Increasing this will slow
|
||||
# down the rate of mesh updates, thus reducing jitter on slower clients.
|
||||
mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50
|
||||
|
||||
# Size of the MapBlock cache of the mesh generator. Increasing this will
|
||||
# increase the cache hit %, reducing the data being copied from the main
|
||||
# thread, thus reducing jitter.
|
||||
meshgen_block_cache_size (Mapblock mesh generator's MapBlock cache size MB) int 20 0 1000
|
||||
|
||||
# Enables minimap.
|
||||
enable_minimap (Minimap) bool true
|
||||
|
||||
@@ -510,6 +602,16 @@ ambient_occlusion_gamma (Ambient occlusion gamma) float 2.2 0.25 4.0
|
||||
# Enables animation of inventory items.
|
||||
inventory_items_animations (Inventory items animations) bool false
|
||||
|
||||
# Android systems only: Tries to create inventory textures from meshes
|
||||
# when no supported render was found.
|
||||
inventory_image_hack (Inventory image hack) bool false
|
||||
|
||||
# Fraction of the visible distance at which fog starts to be rendered
|
||||
fog_start (Fog Start) float 0.4 0.0 0.99
|
||||
|
||||
# Makes all liquids opaque
|
||||
opaque_water (Opaque liquids) bool false
|
||||
|
||||
[**Menus]
|
||||
|
||||
# Use a cloud animation for the main menu background.
|
||||
@@ -530,7 +632,7 @@ gui_scaling_filter (GUI scaling filter) bool false
|
||||
# When gui_scaling_filter_txr2img is true, copy those images
|
||||
# from hardware to software for scaling. When false, fall back
|
||||
# to the old scaling method, for video drivers that don't
|
||||
# propery support downloading textures back from hardware.
|
||||
# properly support downloading textures back from hardware.
|
||||
gui_scaling_filter_txr2img (GUI scaling filter txr2img) bool true
|
||||
|
||||
# Delay showing tooltips, stated in milliseconds.
|
||||
@@ -542,13 +644,13 @@ freetype (Freetype fonts) bool true
|
||||
# Path to TrueTypeFont or bitmap.
|
||||
font_path (Font path) path fonts/liberationsans.ttf
|
||||
|
||||
font_size (Font size) int 15
|
||||
font_size (Font size) int 16
|
||||
|
||||
# Font shadow offset, if 0 then shadow will not be drawn.
|
||||
font_shadow (Font shadow) int 1
|
||||
|
||||
# Font shadow alpha (opaqueness, between 0 and 255).
|
||||
font_shadow_alpha (Font shadow alpha) int 128 0 255
|
||||
font_shadow_alpha (Font shadow alpha) int 127 0 255
|
||||
|
||||
mono_font_path (Monospace font path) path fonts/liberationmono.ttf
|
||||
|
||||
@@ -576,6 +678,10 @@ screenshot_quality (Screenshot quality) int 0 0 100
|
||||
# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens.
|
||||
screen_dpi (DPI) int 72
|
||||
|
||||
# Windows systems only: Start Minetest with the command line window in the background.
|
||||
# Contains the same information as the file debug.txt (default name).
|
||||
enable_console (Enable console window) bool false
|
||||
|
||||
[*Sound]
|
||||
|
||||
enable_sound (Sound) bool true
|
||||
@@ -615,6 +721,11 @@ server_announce (Announce server) bool false
|
||||
# If you want to announce your ipv6 address, use serverlist_url = v6.servers.minetest.net.
|
||||
serverlist_url (Serverlist URL) string servers.minetest.net
|
||||
|
||||
# Disable escape sequences, e.g. chat coloring.
|
||||
# Use this if you want to run a server with pre-0.4.14 clients and you want to disable
|
||||
# the escape sequences generated by mods.
|
||||
disable_escape_sequences (Disable escape sequences) bool false
|
||||
|
||||
[*Network]
|
||||
|
||||
# Network port to listen (UDP).
|
||||
@@ -642,15 +753,15 @@ ipv6_server (IPv6 server) bool false
|
||||
|
||||
[**Advanced]
|
||||
|
||||
# How many blocks are flying in the wire simultaneously per client.
|
||||
max_simultaneous_block_sends_per_client (Maximum simultaneously blocks send per client) int 10
|
||||
# Maximum number of blocks that are simultaneously sent per client.
|
||||
max_simultaneous_block_sends_per_client (Maximum simultaneous block sends per client) int 10
|
||||
|
||||
# How many blocks are flying in the wire simultaneously for the whole server.
|
||||
max_simultaneous_block_sends_server_total (Maximum simultaneously bocks send total) int 40
|
||||
# Maximum number of blocks that are simultaneously sent in total.
|
||||
max_simultaneous_block_sends_server_total (Maximum simultaneous block sends total) int 40
|
||||
|
||||
# To reduce lag, block transfers are slowed down when a player is building something.
|
||||
# This determines how long they are slowed down after placing or removing a node.
|
||||
full_block_send_enable_min_time_from_building () float 2.0
|
||||
full_block_send_enable_min_time_from_building (Delay in sending blocks after building) float 2.0
|
||||
|
||||
# Maximum number of packets sent per send step, if you have a slow connection
|
||||
# try reducing it, but don't reduce it to a number below double of targeted
|
||||
@@ -677,9 +788,15 @@ map-dir (Map directory) path
|
||||
# Setting it to -1 disables the feature.
|
||||
item_entity_ttl (Item entity TTL) int 900
|
||||
|
||||
# If enabled, show the server status message on player connection.
|
||||
show_statusline_on_connect (Status message on connection) bool true
|
||||
|
||||
# Enable players getting damage and dying.
|
||||
enable_damage (Damage) bool false
|
||||
|
||||
# Enable creative mode for new created maps.
|
||||
creative_mode (Creative) bool false
|
||||
|
||||
# A chosen map seed for a new map, leave empty for random.
|
||||
# Will be overridden when creating a new world in the main menu.
|
||||
fixed_map_seed (Fixed map seed) string
|
||||
@@ -732,7 +849,7 @@ active_object_send_range_blocks (Active object send range) int 3
|
||||
|
||||
# How large area of blocks are subject to the active block stuff, stated in mapblocks (16 nodes).
|
||||
# In active blocks objects are loaded and ABMs run.
|
||||
active_block_range (Active block range) int 2
|
||||
active_block_range (Active block range) int 3
|
||||
|
||||
# From how far blocks are sent to clients, stated in mapblocks (16 nodes).
|
||||
max_block_send_distance (Max block send distance) int 10
|
||||
@@ -750,6 +867,15 @@ time_speed (Time speed) int 72
|
||||
# Interval of saving important changes in the world, stated in seconds.
|
||||
server_map_save_interval (Map save interval) float 5.3
|
||||
|
||||
# Set the maximum character length of a chat message sent by clients.
|
||||
# chat_message_max_size int 500
|
||||
|
||||
# Limit a single player to send X messages per 10 seconds.
|
||||
# chat_message_limit_per_10sec float 10.0
|
||||
|
||||
# Kick player if send more than X messages per 10 seconds.
|
||||
# chat_message_limit_trigger_kick int 50
|
||||
|
||||
[**Physics]
|
||||
|
||||
movement_acceleration_default (Default acceleration) float 3
|
||||
@@ -758,9 +884,8 @@ movement_acceleration_fast (Fast mode acceleration) float 10
|
||||
movement_speed_walk (Walking speed) float 4
|
||||
movement_speed_crouch (Crouch speed) float 1.35
|
||||
movement_speed_fast (Fast mode speed) float 20
|
||||
movement_speed_climb (Climbing speed) float 2
|
||||
movement_speed_climb (Climbing speed) float 3
|
||||
movement_speed_jump (Jumping speed) float 6.5
|
||||
movement_speed_descend (Descending speed) float 6
|
||||
movement_liquid_fluidity (Liquid fluidity) float 1
|
||||
movement_liquid_fluidity_smooth (Liquid fluidity smoothing) float 0.5
|
||||
movement_liquid_sink (Liquid sink) float 10
|
||||
@@ -774,15 +899,6 @@ movement_gravity (Gravity) float 9.81
|
||||
# - error: abort on usage of deprecated call (suggested for mod developers).
|
||||
deprecated_lua_api_handling (Deprecated Lua API handling) enum legacy legacy,log,error
|
||||
|
||||
# Useful for mod developers.
|
||||
mod_profiling (Mod profiling) bool false
|
||||
|
||||
# Detailed mod profile data. Useful for mod developers.
|
||||
detailed_profiling (Detailed mod profiling) bool false
|
||||
|
||||
# Profiler data print interval. 0 = disable. Useful for developers.
|
||||
profiler_print_interval (Profiling print interval) int 0
|
||||
|
||||
# Number of extra blocks that can be loaded by /clearobjects at once.
|
||||
# This is a trade-off between sqlite transaction overhead and
|
||||
# memory consumption (4096=100MB, as a rule of thumb).
|
||||
@@ -793,7 +909,7 @@ max_clearobjects_extra_loaded_blocks (Max. clearobjects extra blocks) int 4096
|
||||
server_unload_unused_data_timeout (Unload unused server data) int 29
|
||||
|
||||
# Maximum number of statically stored objects in a block.
|
||||
max_objects_per_block (Maxmimum objects per block) int 49
|
||||
max_objects_per_block (Maximum objects per block) int 64
|
||||
|
||||
# See http://www.sqlite.org/pragma.html#pragma_synchronous
|
||||
sqlite_synchronous (Synchronous SQLite) enum 2 0,1,2
|
||||
@@ -808,7 +924,7 @@ active_block_mgmt_interval (Active Block Management interval) float 2.0
|
||||
abm_interval (Active Block Modifier interval) float 1.0
|
||||
|
||||
# Length of time between NodeTimer execution cycles
|
||||
nodetimer_interval (NodeTimer interval) float 1.0
|
||||
nodetimer_interval (NodeTimer interval) float 0.2
|
||||
|
||||
# If enabled, invalid world data won't cause the server to shut down.
|
||||
# Only enable this if you know what you are doing.
|
||||
@@ -825,11 +941,24 @@ liquid_queue_purge_time (Liquid queue purge time) int 0
|
||||
# Liquid update interval in seconds.
|
||||
liquid_update (Liquid update tick) float 1.0
|
||||
|
||||
# At this distance the server will aggressively optimize which blocks are sent to clients.
|
||||
# Small values potentially improve performance a lot, at the expense of visible rendering glitches.
|
||||
# (some blocks will not be rendered under water and in caves, as well as sometimes on land)
|
||||
# Setting this to a value greater than max_block_send_distance disables this optimization.
|
||||
# Stated in mapblocks (16 nodes)
|
||||
block_send_optimize_distance (block send optimize distance) int 4 2
|
||||
|
||||
# If enabled the server will perform map block occlusion culling based on
|
||||
# on the eye position of the player. This can reduce the number of blocks
|
||||
# sent to the client 50-80%. The client will not longer receive most invisible
|
||||
# so that the utility of noclip mode is reduced.
|
||||
server_side_occlusion_culling (Server side occlusion culling) bool true
|
||||
|
||||
[*Mapgen]
|
||||
|
||||
# Name of map generator to be used when creating a new world.
|
||||
# Creating a world in the main menu will override this.
|
||||
mg_name (Mapgen name) enum v6 v5,v6,v7,flat,valleys,fractal,singlenode
|
||||
mg_name (Mapgen name) enum v7 v5,v6,v7,flat,valleys,fractal,singlenode
|
||||
|
||||
# Water surface level of the world.
|
||||
water_level (Water level) int 1
|
||||
@@ -837,19 +966,14 @@ water_level (Water level) int 1
|
||||
# From how far blocks are generated for clients, stated in mapblocks (16 nodes).
|
||||
max_block_generate_distance (Max block generate distance) int 6
|
||||
|
||||
# Where the map generator stops.
|
||||
# Please note:
|
||||
# - Limited to 31000 (setting above has no effect)
|
||||
# - The map generator works in groups of 80x80x80 nodes (5x5x5 MapBlocks).
|
||||
# - Those groups have an offset of -32, -32 nodes from the origin.
|
||||
# - Only groups which are within the map_generation_limit are generated
|
||||
map_generation_limit (Map generation limit) int 31000 0 31000
|
||||
# Limit of map generation, in nodes, in all 6 directions from (0, 0, 0).
|
||||
# Only mapchunks completely within the mapgen limit are generated.
|
||||
# Value is stored per-world.
|
||||
mapgen_limit (Map generation limit) int 31000 0 31000
|
||||
|
||||
# Global map generation attributes.
|
||||
# In Mapgen v6 the 'decorations' flag controls all decorations except trees
|
||||
# and junglegrass, in all other mapgens this flag controls all decorations.
|
||||
# The default flags set in the engine are: caves, light, decorations
|
||||
# The flags string modifies the engine defaults.
|
||||
# Flags that are not specified in the flag string are not modified from the default.
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
mg_flags (Mapgen flags) flags caves,dungeons,light,decorations caves,dungeons,light,decorations,nocaves,nodungeons,nolight,nodecorations
|
||||
@@ -878,23 +1002,63 @@ emergequeue_limit_generate (Limit of emerge queues to generate) int 32
|
||||
# at the cost of slightly buggy caves.
|
||||
num_emerge_threads (Number of emerge threads) int 1
|
||||
|
||||
# Noise parameters for biome API temperature, humidity and biome blend.
|
||||
mg_biome_np_heat (Mapgen biome heat noise parameters) noise_params 50, 50, (750, 750, 750), 5349, 3, 0.5, 2.0
|
||||
mg_biome_np_heat_blend (Mapgen heat blend noise parameters) noise_params 0, 1.5, (8, 8, 8), 13, 2, 1.0, 2.0
|
||||
mg_biome_np_humidity (Mapgen biome humidity noise parameters) noise_params 50, 50, (750, 750, 750), 842, 3, 0.5, 2.0
|
||||
mg_biome_np_humidity_blend (Mapgen biome humidity blend noise parameters) noise_params 0, 1.5, (8, 8, 8), 90003, 2, 1.0, 2.0
|
||||
[***Biome API temperature and humidity noise parameters]
|
||||
|
||||
# Temperature variation for biomes.
|
||||
mg_biome_np_heat (Heat noise) noise_params 50, 50, (1000, 1000, 1000), 5349, 3, 0.5, 2.0
|
||||
|
||||
# Small-scale temperature variation for blending biomes on borders.
|
||||
mg_biome_np_heat_blend (Heat blend noise) noise_params 0, 1.5, (8, 8, 8), 13, 2, 1.0, 2.0
|
||||
|
||||
# Humidity variation for biomes.
|
||||
mg_biome_np_humidity (Humidity noise) noise_params 50, 50, (1000, 1000, 1000), 842, 3, 0.5, 2.0
|
||||
|
||||
# Small-scale humidity variation for blending biomes on borders.
|
||||
mg_biome_np_humidity_blend (Humidity blend noise) noise_params 0, 1.5, (8, 8, 8), 90003, 2, 1.0, 2.0
|
||||
|
||||
[***Mapgen v5]
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgv5_cave_width (Mapgen v5 cave width) float 0.125
|
||||
# Map generation attributes specific to Mapgen v5.
|
||||
# Flags that are not specified in the flag string are not modified from the default.
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
mgv5_spflags (Mapgen v5 specific flags) flags caverns caverns,nocaverns
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgv5_cave_width (Cave width) float 0.125
|
||||
|
||||
# Y-level of cavern upper limit.
|
||||
mgv5_cavern_limit (Cavern limit) int -256
|
||||
|
||||
# Y-distance over which caverns expand to full size.
|
||||
mgv5_cavern_taper (Cavern taper) int 256
|
||||
|
||||
# Defines full size of caverns, smaller values create larger caverns.
|
||||
mgv5_cavern_threshold (Cavern threshold) float 0.7
|
||||
|
||||
# Variation of biome filler depth.
|
||||
mgv5_np_filler_depth (Filler depth noise) noise_params 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0
|
||||
|
||||
# Variation of terrain vertical scale.
|
||||
# When noise is < -0.55 terrain is near-flat.
|
||||
mgv5_np_factor (Factor noise) noise_params 0, 1, (250, 250, 250), 920381, 3, 0.45, 2.0
|
||||
|
||||
# Y-level of average terrain surface.
|
||||
mgv5_np_height (Height noise) noise_params 0, 10, (250, 250, 250), 84174, 4, 0.5, 2.0
|
||||
|
||||
# First of 2 3D noises that together define tunnels.
|
||||
mgv5_np_cave1 (Cave1 noise) noise_params 0, 12, (50, 50, 50), 52534, 4, 0.5, 2.0
|
||||
|
||||
# Second of 2 3D noises that together define tunnels.
|
||||
mgv5_np_cave2 (Cave2 noise) noise_params 0, 12, (50, 50, 50), 10325, 4, 0.5, 2.0
|
||||
|
||||
# 3D noise defining giant caverns.
|
||||
mgv5_np_cavern (Cavern noise) noise_params 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0
|
||||
|
||||
mgv5_np_filler_depth (Mapgen v5 filler depth noise parameters) noise_params 0, 1, (150, 150, 150), 261, 4, 0.7, 2.0
|
||||
mgv5_np_factor (Mapgen v5 factor noise parameters) noise_params 0, 1, (250, 250, 250), 920381, 3, 0.45, 2.0
|
||||
mgv5_np_height (Mapgen v5 height noise parameters) noise_params 0, 10, (250, 250, 250), 84174, 4, 0.5, 2.0
|
||||
mgv5_np_cave1 (Mapgen v5 cave1 noise parameters) noise_params 0, 12, (50, 50, 50), 52534, 4, 0.5, 2.0
|
||||
mgv5_np_cave2 (Mapgen v5 cave2 noise parameters) noise_params 0, 12, (50, 50, 50), 10325, 4, 0.5, 2.0
|
||||
# TODO
|
||||
# Noise parameters in group format, unsupported by advanced settings
|
||||
# menu but settable in minetest.conf.
|
||||
# See documentation of noise parameter formats in minetest.conf.example.
|
||||
# 3D noise defining terrain.
|
||||
#mgv5_np_ground = {
|
||||
# offset = 0
|
||||
# scale = 40
|
||||
@@ -909,103 +1073,181 @@ mgv5_np_cave2 (Mapgen v5 cave2 noise parameters) noise_params 0, 12, (50, 50, 50
|
||||
[***Mapgen v6]
|
||||
|
||||
# Map generation attributes specific to Mapgen v6.
|
||||
# When snowbiomes are enabled jungles are automatically enabled, the 'jungles' flag is ignored.
|
||||
# The default flags set in the engine are: biomeblend, mudflow
|
||||
# The flags string modifies the engine defaults.
|
||||
# The 'snowbiomes' flag enables the new 5 biome system.
|
||||
# When the new biome system is enabled jungles are automatically enabled and
|
||||
# the 'jungles' flag is ignored.
|
||||
# Flags that are not specified in the flag string are not modified from the default.
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
mgv6_spflags (Mapgen v6 flags) flags jungles,biomeblend,mudflow,snowbiomes,trees jungles,biomeblend,mudflow,snowbiomes,flat,trees,nojungles,nobiomeblend,nomudflow,nosnowbiomes,noflat,notrees
|
||||
mgv6_spflags (Mapgen v6 specific flags) flags jungles,biomeblend,mudflow,snowbiomes,trees jungles,biomeblend,mudflow,snowbiomes,flat,trees,nojungles,nobiomeblend,nomudflow,nosnowbiomes,noflat,notrees
|
||||
|
||||
# Controls size of deserts and beaches in Mapgen v6.
|
||||
# When snowbiomes are enabled 'mgv6_freq_desert' is ignored.
|
||||
mgv6_freq_desert (Mapgen v6 desert frequency) float 0.45
|
||||
mgv6_freq_beach (Mapgen v6 beach frequency) float 0.15
|
||||
# Deserts occur when np_biome exceeds this value.
|
||||
# When the new biome system is enabled, this is ignored.
|
||||
mgv6_freq_desert (Desert noise threshold) float 0.45
|
||||
|
||||
mgv6_np_terrain_base (Mapgen v6 terrain base noise parameters) noise_params -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0
|
||||
mgv6_np_terrain_higher (Mapgen v6 terrain altitude noise parameters) noise_params 20, 16, (500, 500, 500), 85039, 5, 0.6, 2.0
|
||||
mgv6_np_steepness (Mapgen v6 steepness noise parameters) noise_params 0.85, 0.5, (125, 125, 125), -932, 5, 0.7, 2.0
|
||||
mgv6_np_height_select (Mapgen v6 height select noise parameters) noise_params 0.5, 1, (250, 250, 250), 4213, 5, 0.69, 2.0
|
||||
mgv6_np_mud (Mapgen v6 mud noise parameters) noise_params 4, 2, (200, 200, 200), 91013, 3, 0.55, 2.0
|
||||
mgv6_np_beach (Mapgen v6 beach noise parameters) noise_params 0, 1, (250, 250, 250), 59420, 3, 0.50, 2.0
|
||||
mgv6_np_biome (Mapgen v6 biome noise parameters) noise_params 0, 1, (500, 500, 500), 9130, 3, 0.50, 2.0
|
||||
mgv6_np_cave (Mapgen v6 cave noise parameters) noise_params 6, 6, (250, 250, 250), 34329, 3, 0.50, 2.0
|
||||
mgv6_np_humidity (Mapgen v6 humidity noise parameters) noise_params 0.5, 0.5, (500, 500, 500), 72384, 3, 0.50, 2.0
|
||||
mgv6_np_trees (Mapgen v6 trees noise parameters) noise_params 0, 1, (125, 125, 125), 2, 4, 0.66, 2.0
|
||||
mgv6_np_apple_trees (Mapgen v6 apple trees noise parameters) noise_params 0, 1, (100, 100, 100), 342902, 3, 0.45, 2.0
|
||||
# Sandy beaches occur when np_beach exceeds this value.
|
||||
mgv6_freq_beach (Beach noise threshold) float 0.15
|
||||
|
||||
# Y-level of lower terrain and lakebeds.
|
||||
mgv6_np_terrain_base (Terrain base noise) noise_params -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0
|
||||
|
||||
# Y-level of higher (cliff-top) terrain.
|
||||
mgv6_np_terrain_higher (Terrain higher noise) noise_params 20, 16, (500, 500, 500), 85039, 5, 0.6, 2.0
|
||||
|
||||
# Varies steepness of cliffs.
|
||||
mgv6_np_steepness (Steepness noise) noise_params 0.85, 0.5, (125, 125, 125), -932, 5, 0.7, 2.0
|
||||
|
||||
# Defines areas of 'terrain_higher' (cliff-top terrain).
|
||||
mgv6_np_height_select (Height select noise) noise_params 0.5, 1, (250, 250, 250), 4213, 5, 0.69, 2.0
|
||||
|
||||
# Varies depth of biome surface nodes.
|
||||
mgv6_np_mud (Mud noise) noise_params 4, 2, (200, 200, 200), 91013, 3, 0.55, 2.0
|
||||
|
||||
# Defines areas with sandy beaches.
|
||||
mgv6_np_beach (Beach noise) noise_params 0, 1, (250, 250, 250), 59420, 3, 0.50, 2.0
|
||||
|
||||
# Temperature variation for biomes.
|
||||
mgv6_np_biome (Biome noise) noise_params 0, 1, (500, 500, 500), 9130, 3, 0.50, 2.0
|
||||
|
||||
# Variation of number of caves.
|
||||
mgv6_np_cave (Cave noise) noise_params 6, 6, (250, 250, 250), 34329, 3, 0.50, 2.0
|
||||
|
||||
# Humidity variation for biomes.
|
||||
mgv6_np_humidity (Humidity noise) noise_params 0.5, 0.5, (500, 500, 500), 72384, 3, 0.50, 2.0
|
||||
|
||||
# Defines tree areas and tree density.
|
||||
mgv6_np_trees (Trees noise) noise_params 0, 1, (125, 125, 125), 2, 4, 0.66, 2.0
|
||||
|
||||
# Defines areas where trees have apples.
|
||||
mgv6_np_apple_trees (Apple trees noise) noise_params 0, 1, (100, 100, 100), 342902, 3, 0.45, 2.0
|
||||
|
||||
[***Mapgen v7]
|
||||
|
||||
# Map generation attributes specific to Mapgen v7.
|
||||
# The 'ridges' flag controls the rivers.
|
||||
# The default flags set in the engine are: mountains, ridges
|
||||
# The flags string modifies the engine defaults.
|
||||
# The 'ridges' flag enables the rivers.
|
||||
# Floatlands are currently experimental and subject to change.
|
||||
# Flags that are not specified in the flag string are not modified from the default.
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
mgv7_spflags (Mapgen v7 flags) flags mountains,ridges mountains,ridges,nomountains,noridges
|
||||
mgv7_spflags (Mapgen v7 specific flags) flags mountains,ridges,nofloatlands,caverns mountains,ridges,floatlands,caverns,nomountains,noridges,nofloatlands,nocaverns
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgv7_cave_width (Mapgen v7 cave width) float 0.3
|
||||
mgv7_cave_width (Cave width) float 0.09
|
||||
|
||||
mgv7_np_terrain_base (Mapgen v7 terrain base noise parameters) noise_params 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0
|
||||
mgv7_np_terrain_alt (Mapgen v7 terrain altitude noise parameters) noise_params 4, 25, (600, 600, 600), 5934, 5, 0.6, 2.0
|
||||
mgv7_np_terrain_persist (Mapgen v7 terrain persistation noise parameters) noise_params 0.6, 0.1, (2000, 2000, 2000), 539, 3, 0.6, 2.0
|
||||
mgv7_np_height_select (Mapgen v7 height select noise parameters) noise_params -8, 16, (500, 500, 500), 4213, 6, 0.7, 2.0
|
||||
mgv7_np_filler_depth (Mapgen v7 filler depth noise parameters) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
|
||||
mgv7_np_mount_height (Mapgen v7 mount height noise parameters) noise_params 256, 112, (1000, 1000, 1000), 72449, 3, 0.6, 2.0
|
||||
mgv7_np_ridge_uwater (Mapgen v7 ridge water noise parameters) noise_params 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0
|
||||
mgv7_np_mountain (Mapgen v7 mountain noise parameters) noise_params -0.6, 1, (250, 350, 250), 5333, 5, 0.63, 2.0
|
||||
mgv7_np_ridge (Mapgen v7 ridge noise parameters) noise_params 0, 1, (100, 100, 100), 6467, 4, 0.75, 2.0
|
||||
mgv7_np_cave1 (Mapgen v7 cave1 noise parameters) noise_params 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0
|
||||
mgv7_np_cave2 (Mapgen v7 cave2 noise parameters) noise_params 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0
|
||||
# Controls the density of floatland mountain terrain.
|
||||
# Is an offset added to the 'np_mountain' noise value.
|
||||
mgv7_float_mount_density (Floatland mountain density) float 0.6
|
||||
|
||||
# Typical maximum height, above and below midpoint, of floatland mountain terrain.
|
||||
mgv7_float_mount_height (Floatland mountain height) float 128.0
|
||||
|
||||
# Y-level of floatland midpoint and lake surface.
|
||||
mgv7_floatland_level (Floatland level) int 1280
|
||||
|
||||
# Y-level to which floatland shadows extend.
|
||||
mgv7_shadow_limit (Shadow limit) int 1024
|
||||
|
||||
# Y-level of cavern upper limit.
|
||||
mgv7_cavern_limit (Cavern limit) int -256
|
||||
|
||||
# Y-distance over which caverns expand to full size.
|
||||
mgv7_cavern_taper (Cavern taper) int 256
|
||||
|
||||
# Defines full size of caverns, smaller values create larger caverns.
|
||||
mgv7_cavern_threshold (Cavern threshold) float 0.7
|
||||
|
||||
# Y-level of higher (cliff-top) terrain.
|
||||
mgv7_np_terrain_base (Terrain base noise) noise_params 4, 70, (600, 600, 600), 82341, 5, 0.6, 2.0
|
||||
|
||||
# Y-level of lower terrain and lakebeds.
|
||||
mgv7_np_terrain_alt (Terrain alt noise) noise_params 4, 25, (600, 600, 600), 5934, 5, 0.6, 2.0
|
||||
|
||||
# Varies roughness of terrain.
|
||||
# Defines the 'persistence' value for terrain_base and terrain_alt noises.
|
||||
mgv7_np_terrain_persist (Terrain persistence noise) noise_params 0.6, 0.1, (2000, 2000, 2000), 539, 3, 0.6, 2.0
|
||||
|
||||
# Defines areas of higher (cliff-top) terrain and affects steepness of cliffs.
|
||||
mgv7_np_height_select (Height select noise) noise_params -8, 16, (500, 500, 500), 4213, 6, 0.7, 2.0
|
||||
|
||||
# Variation of biome filler depth.
|
||||
mgv7_np_filler_depth (Filler depth noise) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
|
||||
|
||||
# Variation of maximum mountain height (in nodes).
|
||||
mgv7_np_mount_height (Mountain height noise) noise_params 256, 112, (1000, 1000, 1000), 72449, 3, 0.6, 2.0
|
||||
|
||||
# Defines large-scale river channel structure.
|
||||
mgv7_np_ridge_uwater (Ridge underwater noise) noise_params 0, 1, (1000, 1000, 1000), 85039, 5, 0.6, 2.0
|
||||
|
||||
# Defines areas of floatland smooth terrain.
|
||||
# Smooth floatlands occur when noise > 0.
|
||||
mgv7_np_floatland_base (Floatland base noise) noise_params -0.6, 1.5, (600, 600, 600), 114, 5, 0.6, 2.0
|
||||
|
||||
# Variation of hill height and lake depth on floatland smooth terrain.
|
||||
mgv7_np_float_base_height (Floatland base height noise) noise_params 48, 24, (300, 300, 300), 907, 4, 0.7, 2.0
|
||||
|
||||
# 3D noise defining mountain structure and height.
|
||||
# Also defines structure of floatland mountain terrain.
|
||||
mgv7_np_mountain (Mountain noise) noise_params -0.6, 1, (250, 350, 250), 5333, 5, 0.63, 2.0
|
||||
|
||||
# 3D noise defining structure of river canyon walls.
|
||||
mgv7_np_ridge (Ridge noise) noise_params 0, 1, (100, 100, 100), 6467, 4, 0.75, 2.0
|
||||
|
||||
# 3D noise defining giant caverns.
|
||||
mgv7_np_cavern (Cavern noise) noise_params 0, 1, (384, 128, 384), 723, 5, 0.63, 2.0
|
||||
|
||||
# First of 2 3D noises that together define tunnels.
|
||||
mgv7_np_cave1 (Cave1 noise) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
|
||||
|
||||
# Second of 2 3D noises that together define tunnels.
|
||||
mgv7_np_cave2 (Cave2 noise) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
|
||||
|
||||
[***Mapgen flat]
|
||||
|
||||
# Map generation attributes specific to Mapgen flat.
|
||||
# Occasional lakes and hills can be added to the flat world.
|
||||
# The default flags set in the engine are: none
|
||||
# The flags string modifies the engine defaults.
|
||||
# Flags that are not specified in the flag string are not modified from the default.
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
mgflat_spflags (Mapgen flat flags) flags lakes,hills,,nolakes,nohills
|
||||
mgflat_spflags (Mapgen flat specific flags) flags nolakes,nohills lakes,hills,nolakes,nohills
|
||||
|
||||
# Y of flat ground.
|
||||
mgflat_ground_level (Mapgen flat ground level) int 8
|
||||
mgflat_ground_level (Ground level) int 8
|
||||
|
||||
# Y of upper limit of large pseudorandom caves.
|
||||
mgflat_large_cave_depth (Mapgen flat large cave depth) int -33
|
||||
mgflat_large_cave_depth (Large cave depth) int -33
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgflat_cave_width (Mapgen flat cave width) float 0.3
|
||||
mgflat_cave_width (Cave width) float 0.09
|
||||
|
||||
# Terrain noise threshold for lakes.
|
||||
# Controls proportion of world area covered by lakes.
|
||||
# Adjust towards 0.0 for a larger proportion.
|
||||
mgflat_lake_threshold (Mapgen flat lake threshold) float -0.45
|
||||
mgflat_lake_threshold (Lake threshold) float -0.45
|
||||
|
||||
# Controls steepness/depth of lake depressions.
|
||||
mgflat_lake_steepness (Mapgen flat lake steepness) float 48.0
|
||||
mgflat_lake_steepness (Lake steepness) float 48.0
|
||||
|
||||
# Terrain noise threshold for hills.
|
||||
# Controls proportion of world area covered by hills.
|
||||
# Adjust towards 0.0 for a larger proportion.
|
||||
mgflat_hill_threshold (Mapgen flat hill threshold) float 0.45
|
||||
mgflat_hill_threshold (Hill threshold) float 0.45
|
||||
|
||||
# Controls steepness/height of hills.
|
||||
mgflat_hill_steepness (Mapgen flat hill steepness) float 64.0
|
||||
mgflat_hill_steepness (Hill steepness) float 64.0
|
||||
|
||||
# Determines terrain shape.
|
||||
# The 3 numbers in brackets control the scale of the
|
||||
# terrain, the 3 numbers should be identical.
|
||||
mgflat_np_terrain (Mapgen flat terrain noise parameters) noise_params 0, 1, (600, 600, 600), 7244, 5, 0.6, 2.0
|
||||
# Defines location and terrain of optional hills and lakes.
|
||||
mgflat_np_terrain (Terrain noise) noise_params 0, 1, (600, 600, 600), 7244, 5, 0.6, 2.0
|
||||
|
||||
mgflat_np_filler_depth (Mapgen flat filler depth noise parameters) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
|
||||
mgflat_np_cave1 (Mapgen flat cave1 noise parameters) noise_params 0, 12, (128, 128, 128), 52534, 4, 0.5, 2.0
|
||||
mgflat_np_cave2 (Mapgen flat cave2 noise parameters) noise_params 0, 12, (128, 128, 128), 10325, 4, 0.5, 2.0
|
||||
# Variation of biome filler depth.
|
||||
mgflat_np_filler_depth (Filler depth noise) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
|
||||
|
||||
# First of 2 3D noises that together define tunnels.
|
||||
mgflat_np_cave1 (Cave1 noise) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
|
||||
|
||||
# Second of 2 3D noises that together define tunnels.
|
||||
mgflat_np_cave2 (Cave2 noise) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
|
||||
|
||||
[***Mapgen fractal]
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgfractal_cave_width (Mapgen fractal cave width) float 0.3
|
||||
mgfractal_cave_width (Cave width) float 0.09
|
||||
|
||||
# Choice of 18 fractals from 9 formulas.
|
||||
# 1 = 4D "Roundy" mandelbrot set.
|
||||
@@ -1026,48 +1268,55 @@ mgfractal_cave_width (Mapgen fractal cave width) float 0.3
|
||||
# 16 = 3D "Cosine Mandelbulb" julia set.
|
||||
# 17 = 4D "Mandelbulb" mandelbrot set.
|
||||
# 18 = 4D "Mandelbulb" julia set.
|
||||
mgfractal_fractal (Mapgen fractal fractal) int 1 1 18
|
||||
mgfractal_fractal (Fractal type) int 1 1 18
|
||||
|
||||
# Iterations of the recursive function.
|
||||
# Controls the amount of fine detail.
|
||||
mgfractal_iterations (Mapgen fractal iterations) int 11
|
||||
mgfractal_iterations (Iterations) int 11
|
||||
|
||||
# Approximate (X,Y,Z) scale of fractal in nodes.
|
||||
mgfractal_scale (Mapgen fractal scale) v3f (4096.0, 1024.0, 4096.0)
|
||||
mgfractal_scale (Scale) v3f (4096.0, 1024.0, 4096.0)
|
||||
|
||||
# (X,Y,Z) offset of fractal from world centre in units of 'scale'.
|
||||
# Used to move a suitable spawn area of low land close to (0, 0).
|
||||
# The default is suitable for mandelbrot sets, it needs to be edited for julia sets.
|
||||
# Range roughly -2 to 2. Multiply by 'scale' for offset in nodes.
|
||||
mgfractal_offset (Mapgen fractal offset) v3f (1.79, 0.0, 0.0)
|
||||
mgfractal_offset (Offset) v3f (1.79, 0.0, 0.0)
|
||||
|
||||
# W co-ordinate of the generated 3D slice of a 4D fractal.
|
||||
# Determines which 3D slice of the 4D shape is generated.
|
||||
# Has no effect on 3D fractals.
|
||||
# Range roughly -2 to 2.
|
||||
mgfractal_slice_w (Mapgen fractal slice w) float 0.0
|
||||
mgfractal_slice_w (Slice w) float 0.0
|
||||
|
||||
# Julia set only: X component of hypercomplex constant determining julia shape.
|
||||
# Range roughly -2 to 2.
|
||||
mgfractal_julia_x (Mapgen fractal julia x) float 0.33
|
||||
mgfractal_julia_x (Julia x) float 0.33
|
||||
|
||||
# Julia set only: Y component of hypercomplex constant determining julia shape.
|
||||
# Range roughly -2 to 2.
|
||||
mgfractal_julia_y (Mapgen fractal julia y) float 0.33
|
||||
mgfractal_julia_y (Julia y) float 0.33
|
||||
|
||||
# Julia set only: Z component of hypercomplex constant determining julia shape.
|
||||
# Range roughly -2 to 2.
|
||||
mgfractal_julia_z (Mapgen fractal julia z) float 0.33
|
||||
mgfractal_julia_z (Julia z) float 0.33
|
||||
|
||||
# Julia set only: W component of hypercomplex constant determining julia shape.
|
||||
# Has no effect on 3D fractals.
|
||||
# Range roughly -2 to 2.
|
||||
mgfractal_julia_w (Mapgen fractal julia w) float 0.33
|
||||
mgfractal_julia_w (Julia w) float 0.33
|
||||
|
||||
mgfractal_np_seabed (Mapgen fractal seabed noise parameters) noise_params -14, 9, (600, 600, 600), 41900, 5, 0.6, 2.0
|
||||
mgfractal_np_filler_depth (Mapgen fractal filler depth noise parameters) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
|
||||
mgfractal_np_cave1 (Mapgen fractal cave1 noise parameters) noise_params 0, 12, (128, 128, 128), 52534, 4, 0.5, 2.0
|
||||
mgfractal_np_cave2 (Mapgen fractal cave2 noise parameters) noise_params 0, 12, (128, 128, 128), 10325, 4, 0.5, 2.0
|
||||
# Y-level of seabed.
|
||||
mgfractal_np_seabed (Seabed noise) noise_params -14, 9, (600, 600, 600), 41900, 5, 0.6, 2.0
|
||||
|
||||
# Variation of biome filler depth.
|
||||
mgfractal_np_filler_depth (Filler depth noise) noise_params 0, 1.2, (150, 150, 150), 261, 3, 0.7, 2.0
|
||||
|
||||
# First of 2 3D noises that together define tunnels.
|
||||
mgfractal_np_cave1 (Cave1 noise) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
|
||||
|
||||
# Second of 2 3D noises that together define tunnels.
|
||||
mgfractal_np_cave2 (Cave2 noise) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
|
||||
|
||||
# Mapgen Valleys parameters
|
||||
[***Mapgen Valleys]
|
||||
@@ -1079,8 +1328,6 @@ mgfractal_np_cave2 (Mapgen fractal cave2 noise parameters) noise_params 0, 12, (
|
||||
# 'altitude_chill' makes higher elevations colder, which may cause biome issues.
|
||||
# 'humid_rivers' modifies the humidity around rivers and in areas where water would tend to pool,
|
||||
# it may interfere with delicately adjusted biomes.
|
||||
# The default flags set in the engine are: altitude_chill, humid_rivers
|
||||
# The flags string modifies the engine defaults.
|
||||
# Flags that are not specified in the flag string are not modified from the default.
|
||||
# Flags starting with 'no' are used to explicitly disable them.
|
||||
mg_valleys_spflags (Valleys C Flags) flags altitude_chill,humid_rivers altitude_chill,noaltitude_chill,humid_rivers,nohumid_rivers
|
||||
@@ -1109,16 +1356,16 @@ mgvalleys_river_size (River Size) int 5
|
||||
mgvalleys_water_features (Water Features) int 0
|
||||
|
||||
# Controls width of tunnels, a smaller value creates wider tunnels.
|
||||
mgvalleys_cave_width (Cave width) float 0.3
|
||||
mgvalleys_cave_width (Cave width) float 0.09
|
||||
|
||||
# Noise parameters
|
||||
[****Noises]
|
||||
|
||||
# Caves and tunnels form at the intersection of the two noises
|
||||
mgvalleys_np_cave1 (Cave noise #1) noise_params 0, 12, (100, 100, 100), 52534, 4, 0.5, 2.0
|
||||
mgvalleys_np_cave1 (Cave noise #1) noise_params 0, 12, (61, 61, 61), 52534, 3, 0.5, 2.0
|
||||
|
||||
# Caves and tunnels form at the intersection of the two noises
|
||||
mgvalleys_np_cave2 (Cave noise #2) noise_params 0, 12, (100, 100, 100), 10325, 4, 0.5, 2.0
|
||||
mgvalleys_np_cave2 (Cave noise #2) noise_params 0, 12, (67, 67, 67), 10325, 3, 0.5, 2.0
|
||||
|
||||
# The depth of dirt or other filler
|
||||
mgvalleys_np_filler_depth (Filler Depth) noise_params 0, 1.2, (256, 256, 256), 1605, 3, 0.5, 2.0
|
||||
@@ -1147,16 +1394,60 @@ mgvalleys_np_inter_valley_slope (Valley Slope) noise_params 0.5, 0.5, (128, 128,
|
||||
[*Security]
|
||||
|
||||
# Prevent mods from doing insecure things like running shell commands.
|
||||
secure.enable_security (Enable mod security) bool false
|
||||
secure.enable_security (Enable mod security) bool true
|
||||
|
||||
# Comma-separated list of trusted mods that are allowed to access insecure
|
||||
# functions even when mod security is on (via request_insecure_environment()).
|
||||
secure.trusted_mods (Trusted mods) string
|
||||
|
||||
# Comma-seperated list of mods that are allowed to access HTTP APIs, which
|
||||
# Comma-separated list of mods that are allowed to access HTTP APIs, which
|
||||
# allow them to upload and download data to/from the internet.
|
||||
secure.http_mods (HTTP Mods) string
|
||||
|
||||
[*Advanced]
|
||||
|
||||
[**Profiling]
|
||||
# Load the game profiler to collect game profiling data.
|
||||
# Provides a /profiler command to access the compiled profile.
|
||||
# Useful for mod developers and server operators.
|
||||
profiler.load (Load the game profiler) bool false
|
||||
|
||||
# The default format in which profiles are being saved,
|
||||
# when calling `/profiler save [format]` without format.
|
||||
profiler.default_report_format (Default report format) enum txt txt,csv,lua,json,json_pretty
|
||||
|
||||
# The file path relative to your worldpath in which profiles will be saved to.
|
||||
profiler.report_path (Report path) string ""
|
||||
|
||||
[***Instrumentation]
|
||||
|
||||
# Instrument the methods of entities on registration.
|
||||
instrument.entity (Entity methods) bool true
|
||||
|
||||
# Instrument the action function of Active Block Modifiers on registration.
|
||||
instrument.abm (Active Block Modifiers) bool true
|
||||
|
||||
# Instrument the action function of Loading Block Modifiers on registration.
|
||||
instrument.lbm (Loading Block Modifiers) bool true
|
||||
|
||||
# Instrument chatcommands on registration.
|
||||
instrument.chatcommand (Chatcommands) bool true
|
||||
|
||||
# Instrument global callback functions on registration.
|
||||
# (anything you pass to a minetest.register_*() function)
|
||||
instrument.global_callback (Global callbacks) bool true
|
||||
|
||||
[****Advanced]
|
||||
# Instrument builtin.
|
||||
# This is usually only needed by core/builtin contributors
|
||||
instrument.builtin (Builtin) bool false
|
||||
|
||||
# Have the profiler instrument itself:
|
||||
# * Instrument an empty function.
|
||||
# This estimates the overhead, that instrumentation is adding (+1 function call).
|
||||
# * Instrument the sampler being used to update the statistics.
|
||||
instrument.profiler (Profiler) bool false
|
||||
|
||||
[Client and Server]
|
||||
|
||||
# Name of the player.
|
||||
@@ -1166,7 +1457,7 @@ name (Player name) string
|
||||
|
||||
# Set the language. Leave empty to use the system language.
|
||||
# A restart is required after changing this.
|
||||
language (Language) enum ,be,cs,da,de,eo,es,et,fr,hu,id,it,ja,jbo,ko,ky,lt,nb,nl,pl,pt,pt_BR,ro,ru,tr,uk,zh_CN,zh_TW
|
||||
language (Language) enum ,be,ca,cs,da,de,en,eo,es,et,fr,he,hu,id,it,ja,jbo,ko,ky,lt,nb,nl,pl,pt,pt_BR,ro,ru,sr_Cyrl,tr,uk,zh_CN,zh_TW
|
||||
|
||||
# Level of logging to be written to debug.txt:
|
||||
# - <nothing> (no logging)
|
||||
@@ -1176,7 +1467,7 @@ language (Language) enum ,be,cs,da,de,eo,es,et,fr,hu,id,it,ja,jbo,ko,ky,lt,nb,
|
||||
# - action
|
||||
# - info
|
||||
# - verbose
|
||||
debug_log_level (Debug log level) enum action ,warning,action,info,verbose
|
||||
debug_log_level (Debug log level) enum action ,none,error,warning,action,info,verbose
|
||||
|
||||
# IPv6 support.
|
||||
enable_ipv6 (IPv6) bool true
|
||||
@@ -1212,3 +1503,6 @@ modstore_download_url (Modstore download URL) string https://forum.minetest.net/
|
||||
modstore_listmods_url (Modstore mods list URL) string https://forum.minetest.net/mmdb/mods/
|
||||
|
||||
modstore_details_url (Modstore details URL) string https://forum.minetest.net/mmdb/mod/*/
|
||||
|
||||
# Print the engine's profiling data in regular intervals (in seconds). 0 = disable. Useful for developers.
|
||||
profiler_print_interval (Engine profiling data print interval) int 0
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
uniform mat4 mWorld;
|
||||
|
||||
void main(void)
|
||||
|
||||
@@ -19,6 +19,8 @@ bool normalTexturePresent = false;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
const float fogStart = FOG_START;
|
||||
const float fogShadingParameter = 1 / ( 1 - fogStart);
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
|
||||
@@ -35,7 +37,7 @@ const float BS = 10.0;
|
||||
|
||||
vec3 uncharted2Tonemap(vec3 x)
|
||||
{
|
||||
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03334;
|
||||
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03333;
|
||||
}
|
||||
|
||||
vec4 applyToneMapping(vec4 color)
|
||||
@@ -161,7 +163,8 @@ void main(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GENERATE_NORMALMAPS == 1 && normalTexturePresent == false) {
|
||||
#if GENERATE_NORMALMAPS == 1
|
||||
if (normalTexturePresent == false) {
|
||||
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
|
||||
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
|
||||
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
|
||||
@@ -175,7 +178,7 @@ void main(void)
|
||||
bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
|
||||
use_normalmap = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
vec4 base = texture2D(baseTexture, uv).rgba;
|
||||
|
||||
#ifdef ENABLE_BUMPMAPPING
|
||||
@@ -194,24 +197,23 @@ void main(void)
|
||||
|
||||
vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0);
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT
|
||||
float alpha = gl_Color.a;
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
alpha = mix(alpha, 0.0, d);
|
||||
}
|
||||
col = vec4(col.rgb, alpha);
|
||||
#else
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
}
|
||||
col = vec4(col.rgb, base.a);
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
col = applyToneMapping(col);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
gl_FragColor = applyToneMapping(col);
|
||||
#else
|
||||
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
|
||||
// the fog will only be rendered correctly if the last operation before the
|
||||
// clamp() is an addition. Else, the clamp() seems to be ignored.
|
||||
// E.g. the following won't work:
|
||||
// float clarity = clamp(fogShadingParameter
|
||||
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
|
||||
// As additions usually come for free following a multiplication, the new formula
|
||||
// should be more efficient as well.
|
||||
// Note: clarity = (1 - fogginess)
|
||||
float clarity = clamp(fogShadingParameter
|
||||
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
|
||||
col = mix(skyBgColor, col, clarity);
|
||||
col = vec4(col.rgb, base.a);
|
||||
|
||||
gl_FragColor = col;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
uniform mat4 mWorld;
|
||||
|
||||
uniform float dayNightRatio;
|
||||
// Color of the light emitted by the sun.
|
||||
uniform vec3 dayLight;
|
||||
uniform vec3 eyePosition;
|
||||
uniform float animationTimer;
|
||||
|
||||
@@ -16,6 +15,8 @@ varying vec3 tsEyeVec;
|
||||
varying vec3 tsLightVec;
|
||||
varying float area_enable_parallax;
|
||||
|
||||
// Color of the light emitted by the light sources.
|
||||
const vec3 artificialLight = vec3(1.04, 1.04, 1.04);
|
||||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
@@ -121,31 +122,23 @@ float disp_z;
|
||||
v.z = dot(eyeVec, normal);
|
||||
tsEyeVec = normalize (v);
|
||||
|
||||
// Calculate color.
|
||||
// Red, green and blue components are pre-multiplied with
|
||||
// the brightness, so now we have to multiply these
|
||||
// colors with the color of the incoming light.
|
||||
// The pre-baked colors are halved to prevent overflow.
|
||||
vec4 color;
|
||||
float day = gl_Color.r;
|
||||
float night = gl_Color.g;
|
||||
float light_source = gl_Color.b;
|
||||
|
||||
float rg = mix(night, day, dayNightRatio);
|
||||
rg += light_source * 2.5; // Make light sources brighter
|
||||
float b = rg;
|
||||
|
||||
// Moonlight is blue
|
||||
b += (day - night) / 13.0;
|
||||
rg -= (day - night) / 23.0;
|
||||
|
||||
// The alpha gives the ratio of sunlight in the incoming light.
|
||||
float nightRatio = 1 - gl_Color.a;
|
||||
color.rgb = gl_Color.rgb * (gl_Color.a * dayLight.rgb +
|
||||
nightRatio * artificialLight.rgb) * 2;
|
||||
color.a = 1;
|
||||
|
||||
// Emphase blue a bit in darker places
|
||||
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||
b += max(0.0, (1.0 - abs(b - 0.13) / 0.17) * 0.025);
|
||||
|
||||
// Artificial light is yellow-ish
|
||||
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||
rg += max(0.0, (1.0 - abs(rg - 0.85) / 0.15) * 0.065);
|
||||
|
||||
color.r = rg;
|
||||
color.g = rg;
|
||||
color.b = b;
|
||||
|
||||
color.a = gl_Color.a;
|
||||
float brightness = (color.r + color.g + color.b) / 3;
|
||||
color.b += max(0.0, 0.021 - abs(0.2 * brightness - 0.021) +
|
||||
0.07 * brightness);
|
||||
|
||||
gl_FrontColor = gl_BackColor = clamp(color, 0.0, 1.0);
|
||||
}
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
uniform sampler2D baseTexture;
|
||||
uniform sampler2D normalTexture;
|
||||
uniform sampler2D textureFlags;
|
||||
|
||||
uniform vec4 skyBgColor;
|
||||
uniform float fogDistance;
|
||||
uniform vec3 eyePosition;
|
||||
|
||||
varying vec3 vPosition;
|
||||
varying vec3 worldPosition;
|
||||
|
||||
varying vec3 eyeVec;
|
||||
varying vec3 tsEyeVec;
|
||||
varying vec3 lightVec;
|
||||
varying vec3 tsLightVec;
|
||||
|
||||
bool normalTexturePresent = false;
|
||||
bool texTileableHorizontal = false;
|
||||
bool texTileableVertical = false;
|
||||
bool texSeamless = false;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
|
||||
/* Hable's UC2 Tone mapping parameters
|
||||
A = 0.22;
|
||||
B = 0.30;
|
||||
C = 0.10;
|
||||
D = 0.20;
|
||||
E = 0.01;
|
||||
F = 0.30;
|
||||
W = 11.2;
|
||||
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
|
||||
*/
|
||||
|
||||
vec3 uncharted2Tonemap(vec3 x)
|
||||
{
|
||||
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03334;
|
||||
}
|
||||
|
||||
vec4 applyToneMapping(vec4 color)
|
||||
{
|
||||
color = vec4(pow(color.rgb, vec3(2.2)), color.a);
|
||||
const float gamma = 1.6;
|
||||
const float exposureBias = 5.5;
|
||||
color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
|
||||
// Precalculated white_scale from
|
||||
//vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||
vec3 whiteScale = vec3(1.036015346);
|
||||
color.rgb *= whiteScale;
|
||||
return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
|
||||
}
|
||||
#endif
|
||||
|
||||
void get_texture_flags()
|
||||
{
|
||||
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
|
||||
if (flags.r > 0.5) {
|
||||
normalTexturePresent = true;
|
||||
}
|
||||
if (flags.g > 0.5) {
|
||||
texTileableHorizontal = true;
|
||||
}
|
||||
if (flags.b > 0.5) {
|
||||
texTileableVertical = true;
|
||||
}
|
||||
if (texTileableHorizontal && texTileableVertical) {
|
||||
texSeamless = true;
|
||||
}
|
||||
}
|
||||
|
||||
float intensity(vec3 color)
|
||||
{
|
||||
return (color.r + color.g + color.b) / 3.0;
|
||||
}
|
||||
|
||||
float get_rgb_height(vec2 uv)
|
||||
{
|
||||
return intensity(texture2D(baseTexture,uv).rgb);
|
||||
}
|
||||
|
||||
vec4 get_normal_map(vec2 uv)
|
||||
{
|
||||
vec4 bump = texture2D(normalTexture, uv).rgba;
|
||||
bump.xyz = normalize(bump.xyz * 2.0 -1.0);
|
||||
bump.y = -bump.y;
|
||||
return bump;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec3 color;
|
||||
vec4 bump;
|
||||
vec2 uv = gl_TexCoord[0].st;
|
||||
bool use_normalmap = false;
|
||||
get_texture_flags();
|
||||
|
||||
#ifdef ENABLE_PARALLAX_OCCLUSION
|
||||
if (normalTexturePresent) {
|
||||
vec3 tsEye = normalize(tsEyeVec);
|
||||
float height = PARALLAX_OCCLUSION_SCALE * texture2D(normalTexture, uv).a - PARALLAX_OCCLUSION_BIAS;
|
||||
uv = uv + texture2D(normalTexture, uv).z * height * vec2(tsEye.x,-tsEye.y);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_NORMALMAPS
|
||||
if (normalTexturePresent) {
|
||||
bump = get_normal_map(uv);
|
||||
use_normalmap = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GENERATE_NORMALMAPS == 1 && use_normalmap == false) {
|
||||
float tl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y+SAMPLE_STEP));
|
||||
float t = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
|
||||
float tr = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y+SAMPLE_STEP));
|
||||
float r = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y));
|
||||
float br = get_rgb_height (vec2(uv.x+SAMPLE_STEP,uv.y-SAMPLE_STEP));
|
||||
float b = get_rgb_height (vec2(uv.x,uv.y-SAMPLE_STEP));
|
||||
float bl = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y-SAMPLE_STEP));
|
||||
float l = get_rgb_height (vec2(uv.x-SAMPLE_STEP,uv.y));
|
||||
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
|
||||
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
|
||||
bump = vec4 (normalize(vec3 (dX, -dY, NORMALMAPS_STRENGTH)),1.0);
|
||||
use_normalmap = true;
|
||||
}
|
||||
|
||||
vec4 base = texture2D(baseTexture, uv).rgba;
|
||||
|
||||
#ifdef ENABLE_BUMPMAPPING
|
||||
if (use_normalmap) {
|
||||
vec3 L = normalize(lightVec);
|
||||
vec3 E = normalize(eyeVec);
|
||||
float specular = pow(clamp(dot(reflect(L, bump.xyz), E), 0.0, 1.0),0.5);
|
||||
float diffuse = dot(E,bump.xyz);
|
||||
/* Mathematic optimization
|
||||
* Original: color = 0.05*base.rgb + diffuse*base.rgb + 0.2*specular*base.rgb;
|
||||
* This optimization save 2 multiplications (orig: 4 multiplications + 3 additions
|
||||
* end: 2 multiplications + 3 additions)
|
||||
*/
|
||||
color = (0.05 + diffuse + 0.2 * specular) * base.rgb;
|
||||
} else {
|
||||
color = base.rgb;
|
||||
}
|
||||
#else
|
||||
color = base.rgb;
|
||||
#endif
|
||||
|
||||
vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0);
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
|
||||
float alpha = gl_Color.a;
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
alpha = mix(alpha, 0.0, d);
|
||||
}
|
||||
col = vec4(col.rgb, alpha);
|
||||
#else
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
}
|
||||
col = vec4(col.rgb, base.a);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
gl_FragColor = applyToneMapping(col);
|
||||
#else
|
||||
gl_FragColor = col;
|
||||
#endif
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
uniform mat4 mWorld;
|
||||
|
||||
uniform float dayNightRatio;
|
||||
uniform vec3 eyePosition;
|
||||
uniform float animationTimer;
|
||||
|
||||
varying vec3 vPosition;
|
||||
varying vec3 worldPosition;
|
||||
|
||||
varying vec3 eyeVec;
|
||||
varying vec3 lightVec;
|
||||
varying vec3 tsEyeVec;
|
||||
varying vec3 tsLightVec;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
float smoothCurve(float x)
|
||||
{
|
||||
return x * x * (3.0 - 2.0 * x);
|
||||
}
|
||||
float triangleWave(float x)
|
||||
{
|
||||
return abs(fract( x + 0.5 ) * 2.0 - 1.0);
|
||||
}
|
||||
float smoothTriangleWave(float x)
|
||||
{
|
||||
return smoothCurve(triangleWave( x )) * 2.0 - 1.0;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
|
||||
#if (MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE) && ENABLE_WAVING_WATER
|
||||
vec4 pos = gl_Vertex;
|
||||
pos.y -= 2.0;
|
||||
|
||||
float posYbuf = (pos.z / WATER_WAVE_LENGTH + animationTimer * WATER_WAVE_SPEED * WATER_WAVE_LENGTH);
|
||||
|
||||
pos.y -= sin(posYbuf) * WATER_WAVE_HEIGHT + sin(posYbuf / 7.0) * WATER_WAVE_HEIGHT;
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_LEAVES && ENABLE_WAVING_LEAVES
|
||||
vec4 pos = gl_Vertex;
|
||||
vec4 pos2 = mWorld * gl_Vertex;
|
||||
/*
|
||||
* Mathematic optimization: pos2.x * A + pos2.z * A (2 multiplications + 1 addition)
|
||||
* replaced with: (pos2.x + pos2.z) * A (1 addition + 1 multiplication)
|
||||
* And bufferize calcul to a float
|
||||
*/
|
||||
float pos2XpZ = pos2.x + pos2.z;
|
||||
pos.x += (smoothTriangleWave(animationTimer*10.0 + pos2XpZ * 0.01) * 2.0 - 1.0) * 0.4;
|
||||
pos.y += (smoothTriangleWave(animationTimer*15.0 + pos2XpZ * -0.01) * 2.0 - 1.0) * 0.2;
|
||||
pos.z += (smoothTriangleWave(animationTimer*10.0 + pos2XpZ * -0.01) * 2.0 - 1.0) * 0.4;
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#elif MATERIAL_TYPE == TILE_MATERIAL_WAVING_PLANTS && ENABLE_WAVING_PLANTS
|
||||
vec4 pos = gl_Vertex;
|
||||
vec4 pos2 = mWorld * gl_Vertex;
|
||||
if (gl_TexCoord[0].y < 0.05) {
|
||||
/*
|
||||
* Mathematic optimization: pos2.x * A + pos2.z * A (2 multiplications + 1 addition)
|
||||
* replaced with: (pos2.x + pos2.z) * A (1 addition + 1 multiplication)
|
||||
* And bufferize calcul to a float
|
||||
*/
|
||||
float pos2XpZ = pos2.x + pos2.z;
|
||||
pos.x += (smoothTriangleWave(animationTimer * 20.0 + pos2XpZ * 0.1) * 2.0 - 1.0) * 0.8;
|
||||
pos.y -= (smoothTriangleWave(animationTimer * 10.0 + pos2XpZ * -0.5) * 2.0 - 1.0) * 0.4;
|
||||
}
|
||||
gl_Position = mWorldViewProj * pos;
|
||||
#else
|
||||
gl_Position = mWorldViewProj * gl_Vertex;
|
||||
#endif
|
||||
|
||||
vPosition = gl_Position.xyz;
|
||||
worldPosition = (mWorld * gl_Vertex).xyz;
|
||||
vec3 sunPosition = vec3 (0.0, eyePosition.y * BS + 900.0, 0.0);
|
||||
|
||||
vec3 normal, tangent, binormal;
|
||||
normal = normalize(gl_NormalMatrix * gl_Normal);
|
||||
if (gl_Normal.x > 0.5) {
|
||||
// 1.0, 0.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, -1.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.x < -0.5) {
|
||||
// -1.0, 0.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.y > 0.5) {
|
||||
// 0.0, 1.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
} else if (gl_Normal.y < -0.5) {
|
||||
// 0.0, -1.0, 0.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, 0.0, 1.0));
|
||||
} else if (gl_Normal.z > 0.5) {
|
||||
// 0.0, 0.0, 1.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3( 1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
} else if (gl_Normal.z < -0.5) {
|
||||
// 0.0, 0.0, -1.0
|
||||
tangent = normalize(gl_NormalMatrix * vec3(-1.0, 0.0, 0.0));
|
||||
binormal = normalize(gl_NormalMatrix * vec3( 0.0, -1.0, 0.0));
|
||||
}
|
||||
mat3 tbnMatrix = mat3(tangent.x, binormal.x, normal.x,
|
||||
tangent.y, binormal.y, normal.y,
|
||||
tangent.z, binormal.z, normal.z);
|
||||
|
||||
lightVec = sunPosition - worldPosition;
|
||||
tsLightVec = lightVec * tbnMatrix;
|
||||
eyeVec = (gl_ModelViewMatrix * gl_Vertex).xyz;
|
||||
tsEyeVec = eyeVec * tbnMatrix;
|
||||
|
||||
vec4 color;
|
||||
float day = gl_Color.r;
|
||||
float night = gl_Color.g;
|
||||
float light_source = gl_Color.b;
|
||||
|
||||
float rg = mix(night, day, dayNightRatio);
|
||||
rg += light_source * 2.5; // Make light sources brighter
|
||||
float b = rg;
|
||||
|
||||
// Moonlight is blue
|
||||
b += (day - night) / 13.0;
|
||||
rg -= (day - night) / 23.0;
|
||||
|
||||
// Emphase blue a bit in darker places
|
||||
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
|
||||
|
||||
// Artificial light is yellow-ish
|
||||
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
|
||||
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
|
||||
|
||||
color.r = rg;
|
||||
color.g = rg;
|
||||
color.b = b;
|
||||
|
||||
color.a = gl_Color.a;
|
||||
gl_FrontColor = gl_BackColor = clamp(color,0.0,1.0);
|
||||
}
|
||||
@@ -19,6 +19,8 @@ bool texSeamless = false;
|
||||
|
||||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
const float fogStart = FOG_START;
|
||||
const float fogShadingParameter = 1 / ( 1 - fogStart);
|
||||
|
||||
void get_texture_flags()
|
||||
{
|
||||
@@ -73,7 +75,8 @@ void main(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GENERATE_NORMALMAPS == 1 && normalTexturePresent == false) {
|
||||
#if GENERATE_NORMALMAPS == 1
|
||||
if (normalTexturePresent == false) {
|
||||
float tl = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y + SAMPLE_STEP));
|
||||
float t = get_rgb_height(vec2(uv.x - SAMPLE_STEP, uv.y - SAMPLE_STEP));
|
||||
float tr = get_rgb_height(vec2(uv.x + SAMPLE_STEP, uv.y + SAMPLE_STEP));
|
||||
@@ -87,6 +90,7 @@ void main(void)
|
||||
bump = vec4(normalize(vec3 (dX, dY, NORMALMAPS_STRENGTH)), 1.0);
|
||||
use_normalmap = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 base = texture2D(baseTexture, uv).rgba;
|
||||
|
||||
@@ -106,9 +110,18 @@ void main(void)
|
||||
|
||||
vec4 col = vec4(color.rgb, base.a);
|
||||
col *= gl_Color;
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
}
|
||||
// Due to a bug in some (older ?) graphics stacks (possibly in the glsl compiler ?),
|
||||
// the fog will only be rendered correctly if the last operation before the
|
||||
// clamp() is an addition. Else, the clamp() seems to be ignored.
|
||||
// E.g. the following won't work:
|
||||
// float clarity = clamp(fogShadingParameter
|
||||
// * (fogDistance - length(eyeVec)) / fogDistance), 0.0, 1.0);
|
||||
// As additions usually come for free following a multiplication, the new formula
|
||||
// should be more efficient as well.
|
||||
// Note: clarity = (1 - fogginess)
|
||||
float clarity = clamp(fogShadingParameter
|
||||
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
|
||||
col = mix(skyBgColor, col, clarity);
|
||||
|
||||
gl_FragColor = vec4(col.rgb, base.a);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
uniform mat4 mWorldViewProj;
|
||||
uniform mat4 mInvWorld;
|
||||
uniform mat4 mTransWorld;
|
||||
uniform mat4 mWorld;
|
||||
|
||||
uniform float dayNightRatio;
|
||||
uniform vec3 eyePosition;
|
||||
uniform float animationTimer;
|
||||
|
||||
|
||||
152
clientmods/preview/init.lua
Normal file
152
clientmods/preview/init.lua
Normal file
@@ -0,0 +1,152 @@
|
||||
local modname = core.get_current_modname() or "??"
|
||||
local modstorage = core.get_mod_storage()
|
||||
|
||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||
core.register_on_shutdown(function()
|
||||
print("[PREVIEW] shutdown client")
|
||||
end)
|
||||
|
||||
core.register_on_connect(function()
|
||||
print("[PREVIEW] Player connection completed")
|
||||
local server_info = core.get_server_info()
|
||||
print("Server version: " .. server_info.protocol_version)
|
||||
print("Server ip: " .. server_info.ip)
|
||||
print("Server address: " .. server_info.address)
|
||||
print("Server port: " .. server_info.port)
|
||||
end)
|
||||
|
||||
core.register_on_placenode(function(pointed_thing, node)
|
||||
print("The local player place a node!")
|
||||
print("pointed_thing :" .. dump(pointed_thing))
|
||||
print("node placed :" .. dump(node))
|
||||
return false
|
||||
end)
|
||||
|
||||
core.register_on_item_use(function(itemstack, pointed_thing)
|
||||
print("The local player used an item!")
|
||||
print("pointed_thing :" .. dump(pointed_thing))
|
||||
print("item = " .. itemstack:get_name())
|
||||
return false
|
||||
end)
|
||||
|
||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||
core.register_on_receiving_chat_messages(function(message)
|
||||
print("[PREVIEW] Received message " .. message)
|
||||
return false
|
||||
end)
|
||||
|
||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||
core.register_on_sending_chat_messages(function(message)
|
||||
print("[PREVIEW] Sending message " .. message)
|
||||
return false
|
||||
end)
|
||||
|
||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||
core.register_on_hp_modification(function(hp)
|
||||
print("[PREVIEW] HP modified " .. hp)
|
||||
end)
|
||||
|
||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||
core.register_on_damage_taken(function(hp)
|
||||
print("[PREVIEW] Damage taken " .. hp)
|
||||
end)
|
||||
|
||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||
core.register_globalstep(function(dtime)
|
||||
-- print("[PREVIEW] globalstep " .. dtime)
|
||||
end)
|
||||
|
||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||
core.register_chatcommand("dump", {
|
||||
func = function(param)
|
||||
return true, dump(_G)
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("colorize_test", {
|
||||
func = function(param)
|
||||
return true, core.colorize("red", param)
|
||||
end,
|
||||
})
|
||||
|
||||
core.register_chatcommand("test_node", {
|
||||
func = function(param)
|
||||
core.display_chat_message(dump(core.get_node({x=0, y=0, z=0})))
|
||||
core.display_chat_message(dump(core.get_node_or_nil({x=0, y=0, z=0})))
|
||||
end,
|
||||
})
|
||||
|
||||
local function preview_minimap()
|
||||
local minimap = core.ui.minimap
|
||||
if not minimap then
|
||||
print("[PREVIEW] Minimap is disabled. Skipping.")
|
||||
return
|
||||
end
|
||||
minimap:set_mode(4)
|
||||
minimap:show()
|
||||
minimap:set_pos({x=5, y=50, z=5})
|
||||
minimap:set_shape(math.random(0, 1))
|
||||
|
||||
print("[PREVIEW] Minimap: mode => " .. dump(minimap:get_mode()) ..
|
||||
" position => " .. dump(minimap:get_pos()) ..
|
||||
" angle => " .. dump(minimap:get_angle()))
|
||||
end
|
||||
|
||||
core.after(2, function()
|
||||
print("[PREVIEW] loaded " .. modname .. " mod")
|
||||
modstorage:set_string("current_mod", modname)
|
||||
print(modstorage:get_string("current_mod"))
|
||||
preview_minimap()
|
||||
end)
|
||||
|
||||
core.after(5, function()
|
||||
if core.ui.minimap then
|
||||
core.ui.minimap:show()
|
||||
end
|
||||
|
||||
print("[PREVIEW] Day count: " .. core.get_day_count() ..
|
||||
" time of day " .. core.get_timeofday())
|
||||
|
||||
print("[PREVIEW] Node level: " .. core.get_node_level({x=0, y=20, z=0}) ..
|
||||
" max level " .. core.get_node_max_level({x=0, y=20, z=0}))
|
||||
|
||||
print("[PREVIEW] Find node near: " .. dump(core.find_node_near({x=0, y=20, z=0}, 10,
|
||||
{"group:tree", "default:dirt", "default:stone"})))
|
||||
end)
|
||||
|
||||
core.register_on_dignode(function(pos, node)
|
||||
print("The local player dug a node!")
|
||||
print("pos:" .. dump(pos))
|
||||
print("node:" .. dump(node))
|
||||
return false
|
||||
end)
|
||||
|
||||
core.register_on_punchnode(function(pos, node)
|
||||
print("The local player punched a node!")
|
||||
local itemstack = core.get_wielded_item()
|
||||
--[[
|
||||
-- getters
|
||||
print(dump(itemstack:is_empty()))
|
||||
print(dump(itemstack:get_name()))
|
||||
print(dump(itemstack:get_count()))
|
||||
print(dump(itemstack:get_wear()))
|
||||
print(dump(itemstack:get_meta()))
|
||||
print(dump(itemstack:get_metadata()
|
||||
print(dump(itemstack:is_known()))
|
||||
--print(dump(itemstack:get_definition()))
|
||||
print(dump(itemstack:get_tool_capabilities()))
|
||||
print(dump(itemstack:to_string()))
|
||||
print(dump(itemstack:to_table()))
|
||||
-- setters
|
||||
print(dump(itemstack:set_name("default:dirt")))
|
||||
print(dump(itemstack:set_count("95")))
|
||||
print(dump(itemstack:set_wear(934)))
|
||||
print(dump(itemstack:get_meta()))
|
||||
print(dump(itemstack:get_metadata()))
|
||||
--]]
|
||||
print(dump(itemstack:to_table()))
|
||||
print("pos:" .. dump(pos))
|
||||
print("node:" .. dump(node))
|
||||
return false
|
||||
end)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
option(ENABLE_SYSTEM_GMP "Use GMP from system" TRUE)
|
||||
mark_as_advanced(GMP_LIBRARY GMP_INCLUDE_DIR)
|
||||
set(USE_SYSTEM_GMP FALSE)
|
||||
@@ -19,9 +18,9 @@ endif()
|
||||
|
||||
if(NOT USE_SYSTEM_GMP)
|
||||
message(STATUS "Using bundled mini-gmp library.")
|
||||
set(GMP_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/gmp)
|
||||
set(GMP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/gmp)
|
||||
set(GMP_LIBRARY gmp)
|
||||
add_subdirectory(gmp)
|
||||
add_subdirectory(lib/gmp)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
@@ -20,8 +20,7 @@ endif()
|
||||
|
||||
if(NOT JSONCPP_FOUND)
|
||||
message(STATUS "Using bundled JSONCPP library.")
|
||||
set(JSON_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/json)
|
||||
set(JSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/jsoncpp)
|
||||
set(JSON_LIBRARY jsoncpp)
|
||||
add_subdirectory(json)
|
||||
add_subdirectory(lib/jsoncpp)
|
||||
endif()
|
||||
|
||||
|
||||
28
cmake/Modules/FindLua.cmake
Normal file
28
cmake/Modules/FindLua.cmake
Normal file
@@ -0,0 +1,28 @@
|
||||
# Look for Lua library to use
|
||||
# This selects LuaJIT by default
|
||||
|
||||
option(ENABLE_LUAJIT "Enable LuaJIT support" TRUE)
|
||||
set(USE_LUAJIT FALSE)
|
||||
option(REQUIRE_LUAJIT "Require LuaJIT support" FALSE)
|
||||
if(REQUIRE_LUAJIT)
|
||||
set(ENABLE_LUAJIT TRUE)
|
||||
endif()
|
||||
if(ENABLE_LUAJIT)
|
||||
find_package(LuaJIT)
|
||||
if(LUAJIT_FOUND)
|
||||
set(USE_LUAJIT TRUE)
|
||||
message (STATUS "Using LuaJIT provided by system.")
|
||||
elseif(REQUIRE_LUAJIT)
|
||||
message(FATAL_ERROR "LuaJIT not found whereas REQUIRE_LUAJIT=\"TRUE\" is used.\n"
|
||||
"To continue, either install LuaJIT or do not use REQUIRE_LUAJIT=\"TRUE\".")
|
||||
endif()
|
||||
else()
|
||||
message (STATUS "LuaJIT detection disabled! (ENABLE_LUAJIT=0)")
|
||||
endif()
|
||||
|
||||
if(NOT USE_LUAJIT)
|
||||
message(STATUS "LuaJIT not found, using bundled Lua.")
|
||||
set(LUA_LIBRARY lua)
|
||||
set(LUA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/src)
|
||||
add_subdirectory(lib/lua)
|
||||
endif()
|
||||
@@ -115,7 +115,7 @@ if(CURSES_USE_NCURSESW)
|
||||
get_filename_component(_cursesParentDir "${_cursesLibDir}" PATH)
|
||||
|
||||
find_path(CURSES_INCLUDE_PATH
|
||||
NAMES ncursesw/ncurses.h ncursesw/curses.h
|
||||
NAMES ncursesw/ncurses.h ncursesw/curses.h ncurses.h curses.h
|
||||
HINTS "${_cursesParentDir}/include"
|
||||
)
|
||||
|
||||
|
||||
1149
doc/client_lua_api.md
Normal file
1149
doc/client_lua_api.md
Normal file
File diff suppressed because it is too large
Load Diff
1263
doc/lua_api.txt
1263
doc/lua_api.txt
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
Minetest Lua Mainmenu API Reference 0.4.14
|
||||
Minetest Lua Mainmenu API Reference 0.4.16
|
||||
========================================
|
||||
|
||||
Introduction
|
||||
@@ -210,6 +210,10 @@ string:trim()
|
||||
^ eg. string.trim("\n \t\tfoo bar\t ") == "foo bar"
|
||||
core.is_yes(arg) (possible in async calls)
|
||||
^ returns whether arg can be interpreted as yes
|
||||
minetest.encode_base64(string) (possible in async calls)
|
||||
^ Encodes a string in base64.
|
||||
minetest.decode_base64(string) (possible in async calls)
|
||||
^ Decodes a string encoded in base64.
|
||||
|
||||
Version compat:
|
||||
core.get_min_supp_proto()
|
||||
|
||||
@@ -1,345 +0,0 @@
|
||||
------------------------------------------------------------------
|
||||
The ancient comment from the beginning of main.cpp is stored here.
|
||||
------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
=============================== NOTES ==============================
|
||||
NOTE: Things starting with TODO are sometimes only suggestions.
|
||||
|
||||
NOTE: iostream.imbue(std::locale("C")) is very slow
|
||||
NOTE: Global locale is now set at initialization
|
||||
|
||||
NOTE: If VBO (EHM_STATIC) is used, remember to explicitly free the
|
||||
hardware buffer (it is not freed automatically)
|
||||
|
||||
NOTE: A random to-do list saved here as documentation:
|
||||
A list of "active blocks" in which stuff happens. (+=done)
|
||||
+ Add a never-resetted game timer to the server
|
||||
+ Add a timestamp value to blocks
|
||||
+ The simple rule: All blocks near some player are "active"
|
||||
- Do stuff in real time in active blocks
|
||||
+ Handle objects
|
||||
- Grow grass, delete leaves without a tree
|
||||
- Spawn some mobs based on some rules
|
||||
- Transform cobble to mossy cobble near water
|
||||
- Run a custom script
|
||||
- ...And all kinds of other dynamic stuff
|
||||
+ Keep track of when a block becomes active and becomes inactive
|
||||
+ When a block goes inactive:
|
||||
+ Store objects statically to block
|
||||
+ Store timer value as the timestamp
|
||||
+ When a block goes active:
|
||||
+ Create active objects out of static objects
|
||||
- Simulate the results of what would have happened if it would have
|
||||
been active for all the time
|
||||
- Grow a lot of grass and so on
|
||||
+ Initially it is fine to send information about every active object
|
||||
to every player. Eventually it should be modified to only send info
|
||||
about the nearest ones.
|
||||
+ This was left to be done by the old system and it sends only the
|
||||
nearest ones.
|
||||
|
||||
NOTE: Seeds in 1260:6c77e7dbfd29:
|
||||
5721858502589302589:
|
||||
Spawns you on a small sand island with a surface dungeon
|
||||
2983455799928051958:
|
||||
Enormous jungle + a surface dungeon at ~(250,0,0)
|
||||
|
||||
Old, wild and random suggestions that probably won't be done:
|
||||
-------------------------------------------------------------
|
||||
|
||||
SUGG: If player is on ground, mainly fetch ground-level blocks
|
||||
|
||||
SUGG: Expose Connection's seqnums and ACKs to server and client.
|
||||
- This enables saving many packets and making a faster connection
|
||||
- This also enables server to check if client has received the
|
||||
most recent block sent, for example.
|
||||
SUGG: Add a sane bandwidth throttling system to Connection
|
||||
|
||||
SUGG: More fine-grained control of client's dumping of blocks from
|
||||
memory
|
||||
- ...What does this mean in the first place?
|
||||
|
||||
SUGG: A map editing mode (similar to dedicated server mode)
|
||||
|
||||
SUGG: Transfer more blocks in a single packet
|
||||
SUGG: A blockdata combiner class, to which blocks are added and at
|
||||
destruction it sends all the stuff in as few packets as possible.
|
||||
SUGG: Make a PACKET_COMBINED which contains many subpackets. Utilize
|
||||
it by sending more stuff in a single packet.
|
||||
- Add a packet queue to RemoteClient, from which packets will be
|
||||
combined with object data packets
|
||||
- This is not exactly trivial: the object data packets are
|
||||
sometimes very big by themselves
|
||||
- This might not give much network performance gain though.
|
||||
|
||||
SUGG: Precalculate lighting translation table at runtime (at startup)
|
||||
- This is not doable because it is currently hand-made and not
|
||||
based on some mathematical function.
|
||||
- Note: This has been changing lately
|
||||
|
||||
SUGG: A version number to blocks, which increments when the block is
|
||||
modified (node add/remove, water update, lighting update)
|
||||
- This can then be used to make sure the most recent version of
|
||||
a block has been sent to client, for example
|
||||
|
||||
SUGG: Make the amount of blocks sending to client and the total
|
||||
amount of blocks dynamically limited. Transferring blocks is the
|
||||
main network eater of this system, so it is the one that has
|
||||
to be throttled so that RTTs stay low.
|
||||
|
||||
SUGG: Meshes of blocks could be split into 6 meshes facing into
|
||||
different directions and then only those drawn that need to be
|
||||
|
||||
SUGG: Background music based on cellular automata?
|
||||
http://www.earslap.com/projectslab/otomata
|
||||
|
||||
SUGG: Simple light color information to air
|
||||
|
||||
SUGG: Server-side objects could be moved based on nodes to enable very
|
||||
lightweight operation and simple AI
|
||||
- Not practical; client would still need to show smooth movement.
|
||||
|
||||
SUGG: Make a system for pregenerating quick information for mapblocks, so
|
||||
that the client can show them as cubes before they are actually sent
|
||||
or even generated.
|
||||
|
||||
SUGG: Erosion simulation at map generation time
|
||||
- This might be plausible if larger areas of map were pregenerated
|
||||
without lighting (which is slow)
|
||||
- Simulate water flows, which would carve out dirt fast and
|
||||
then turn stone into gravel and sand and relocate it.
|
||||
- How about relocating minerals, too? Coal and gold in
|
||||
downstream sand and gravel would be kind of cool
|
||||
- This would need a better way of handling minerals, mainly
|
||||
to have mineral content as a separate field. the first
|
||||
parameter field is free for this.
|
||||
- Simulate rock falling from cliffs when water has removed
|
||||
enough solid rock from the bottom
|
||||
|
||||
SUGG: For non-mapgen FarMesh: Add a per-sector database to store surface
|
||||
stuff as simple flags/values
|
||||
- Light?
|
||||
- A building?
|
||||
And at some point make the server send this data to the client too,
|
||||
instead of referring to the noise functions
|
||||
- Ground height
|
||||
- Surface ground type
|
||||
- Trees?
|
||||
|
||||
Gaming ideas:
|
||||
-------------
|
||||
|
||||
- Aim for something like controlling a single dwarf in Dwarf Fortress
|
||||
- The player could go faster by a crafting a boat, or riding an animal
|
||||
- Random NPC traders. what else?
|
||||
|
||||
Game content:
|
||||
-------------
|
||||
|
||||
- When furnace is destroyed, move items to player's inventory
|
||||
- Add lots of stuff
|
||||
- Glass blocks
|
||||
- Growing grass, decaying leaves
|
||||
- This can be done in the active blocks I guess.
|
||||
- Lots of stuff can be done in the active blocks.
|
||||
- Uh, is there an active block list somewhere? I think not. Add it.
|
||||
- Breaking weak structures
|
||||
- This can probably be accomplished in the same way as grass
|
||||
- Player health points
|
||||
- When player dies, throw items on map (needs better item-on-map
|
||||
implementation)
|
||||
- Cobble to get mossy if near water
|
||||
- More slots in furnace source list, so that multiple ingredients
|
||||
are possible.
|
||||
- Keys to chests?
|
||||
|
||||
- The Treasure Guard; a big monster with a hammer
|
||||
- The hammer does great damage, shakes the ground and removes a block
|
||||
- You can drop on top of it, and have some time to attack there
|
||||
before he shakes you off
|
||||
|
||||
- Maybe the difficulty could come from monsters getting tougher in
|
||||
far-away places, and the player starting to need something from
|
||||
there when time goes by.
|
||||
- The player would have some of that stuff at the beginning, and
|
||||
would need new supplies of it when it runs out
|
||||
|
||||
- A bomb
|
||||
- A spread-items-on-map routine for the bomb, and for dying players
|
||||
|
||||
- Fighting:
|
||||
- Proper sword swing simulation
|
||||
- Player should get damage from colliding to a wall at high speed
|
||||
|
||||
Documentation:
|
||||
--------------
|
||||
|
||||
Build system / running:
|
||||
-----------------------
|
||||
|
||||
Networking and serialization:
|
||||
-----------------------------
|
||||
|
||||
SUGG: Fix address to be ipv6 compatible
|
||||
|
||||
User Interface:
|
||||
---------------
|
||||
|
||||
Graphics:
|
||||
---------
|
||||
|
||||
SUGG: Combine MapBlock's face caches to so big pieces that VBO
|
||||
can be used
|
||||
- That is >500 vertices
|
||||
- This is not easy; all the MapBlocks close to the player would
|
||||
still need to be drawn separately and combining the blocks
|
||||
would have to happen in a background thread
|
||||
|
||||
SUGG: Make fetching sector's blocks more efficient when rendering
|
||||
sectors that have very large amounts of blocks (on client)
|
||||
- Is this necessary at all?
|
||||
|
||||
SUGG: Draw cubes in inventory directly with 3D drawing commands, so that
|
||||
animating them is easier.
|
||||
|
||||
SUGG: Option for enabling proper alpha channel for textures
|
||||
|
||||
TODO: Flowing water animation
|
||||
|
||||
TODO: A setting for enabling bilinear filtering for textures
|
||||
|
||||
TODO: Better control of draw_control.wanted_max_blocks
|
||||
|
||||
TODO: Further investigate the use of GPU lighting in addition to the
|
||||
current one
|
||||
|
||||
TODO: Artificial (night) light could be more yellow colored than sunlight.
|
||||
- This is technically doable.
|
||||
- Also the actual colors of the textures could be made less colorful
|
||||
in the dark but it's a bit more difficult.
|
||||
|
||||
SUGG: Somehow make the night less colorful
|
||||
|
||||
TODO: Occlusion culling
|
||||
- At the same time, move some of the renderMap() block choosing code
|
||||
to the same place as where the new culling happens.
|
||||
- Shoot some rays per frame and when ready, make a new list of
|
||||
blocks for usage of renderMap and give it a new pointer to it.
|
||||
|
||||
Configuration:
|
||||
--------------
|
||||
|
||||
Client:
|
||||
-------
|
||||
|
||||
TODO: Untie client network operations from framerate
|
||||
- Needs some input queues or something
|
||||
- This won't give much performance boost because calculating block
|
||||
meshes takes so long
|
||||
|
||||
SUGG: Make morning and evening transition more smooth and maybe shorter
|
||||
|
||||
TODO: Don't update all meshes always on single node changes, but
|
||||
check which ones should be updated
|
||||
- implement Map::updateNodeMeshes() and the usage of it
|
||||
- It will give almost always a 4x boost in mesh update performance.
|
||||
|
||||
- A weapon engine
|
||||
|
||||
- Tool/weapon visualization
|
||||
|
||||
FIXME: When disconnected to the menu, memory is not freed properly
|
||||
|
||||
TODO: Investigate how much the mesh generator thread gets used when
|
||||
transferring map data
|
||||
|
||||
Server:
|
||||
-------
|
||||
|
||||
SUGG: Make an option to the server to disable building and digging near
|
||||
the starting position
|
||||
|
||||
FIXME: Server sometimes goes into some infinite PeerNotFoundException loop
|
||||
|
||||
* Fix the problem with the server constantly saving one or a few
|
||||
blocks? List the first saved block, maybe it explains.
|
||||
- It is probably caused by oscillating water
|
||||
- TODO: Investigate if this still happens (this is a very old one)
|
||||
* Make a small history check to transformLiquids to detect and log
|
||||
continuous oscillations, in such detail that they can be fixed.
|
||||
|
||||
FIXME: The new optimized map sending doesn't sometimes send enough blocks
|
||||
from big caves and such
|
||||
FIXME: Block send distance configuration does not take effect for some reason
|
||||
|
||||
Environment:
|
||||
------------
|
||||
|
||||
TODO: Add proper hooks to when adding and removing active blocks
|
||||
|
||||
TODO: Finish the ActiveBlockModifier stuff and use it for something
|
||||
|
||||
Objects:
|
||||
--------
|
||||
|
||||
TODO: Get rid of MapBlockObjects and use only ActiveObjects
|
||||
- Skipping the MapBlockObject data is nasty - there is no "total
|
||||
length" stored; have to make a SkipMBOs function which contains
|
||||
enough of the current code to skip them properly.
|
||||
|
||||
SUGG: MovingObject::move and Player::move are basically the same.
|
||||
combine them.
|
||||
- NOTE: This is a bit tricky because player has the sneaking ability
|
||||
- NOTE: Player::move is more up-to-date.
|
||||
- NOTE: There is a simple move implementation now in collision.{h,cpp}
|
||||
- NOTE: MovingObject will be deleted (MapBlockObject)
|
||||
|
||||
TODO: Add a long step function to objects that is called with the time
|
||||
difference when block activates
|
||||
|
||||
Map:
|
||||
----
|
||||
|
||||
TODO: Flowing water to actually contain flow direction information
|
||||
- There is a space for this - it just has to be implemented.
|
||||
|
||||
TODO: Consider smoothening cave floors after generating them
|
||||
|
||||
TODO: Fix make_tree, make_* to use seed-position-consistent pseudorandom
|
||||
- delta also
|
||||
|
||||
Misc. stuff:
|
||||
------------
|
||||
TODO: Make sure server handles removing grass when a block is placed (etc)
|
||||
- The client should not do it by itself
|
||||
- NOTE: I think nobody does it currently...
|
||||
TODO: Block cube placement around player's head
|
||||
TODO: Protocol version field
|
||||
TODO: Think about using same bits for material for fences and doors, for
|
||||
example
|
||||
|
||||
SUGG: Restart irrlicht completely when coming back to main menu from game.
|
||||
- This gets rid of everything that is stored in irrlicht's caches.
|
||||
- This might be needed for texture pack selection in menu
|
||||
|
||||
TODO: Merge bahamada's audio stuff (clean patch available)
|
||||
|
||||
Making it more portable:
|
||||
------------------------
|
||||
|
||||
Stuff to do before release:
|
||||
---------------------------
|
||||
|
||||
Fixes to the current release:
|
||||
-----------------------------
|
||||
|
||||
Stuff to do after release:
|
||||
---------------------------
|
||||
|
||||
Doing currently:
|
||||
----------------
|
||||
|
||||
======================================================================
|
||||
|
||||
*/
|
||||
@@ -1,147 +0,0 @@
|
||||
Minetest changelog
|
||||
----------------------
|
||||
This should contain all the major changes.
|
||||
For minor stuff, refer to the commit log of the repository.
|
||||
|
||||
0.3.1: (released on 2011-11-09)
|
||||
- Fix frustum culling (previous versions have rendered too much stuff that is not actually visible (about 180 degrees, while should have been more like 100.))
|
||||
- Add occlusion culling (improves performance a lot)
|
||||
- Add “3d clouds” on/off checkbox in main menu
|
||||
- Add “opaque water” on/off checkbox
|
||||
- Fix some random minor stuff
|
||||
- Turn mipmapping off (This makes far-away textures a bit noisier but better looking)
|
||||
- Add Command-line signal handler for Windows (contributed by SpeedProg)
|
||||
- Fix network layer segmentation fault introduced in 0.3.dev-20111021
|
||||
- Fix water-glass and water-lava and lava-glass surfaces
|
||||
|
||||
0.3.0: (released on 2011-11-01)
|
||||
- Some small fixes
|
||||
0.3.dev-20111021:
|
||||
- Modify dungeon masters to only try to shoot players
|
||||
- Fix object duplication bug at block load/unload bug
|
||||
- Improve network layer
|
||||
0.3.dev-20111016:
|
||||
- Locked chest (contributed)
|
||||
- Server user limit setting (max_users)
|
||||
- Wielded tool is shown in HUD (contributed)
|
||||
- View bobbing (contributed)
|
||||
- Saplings that drop from leaf blocks and when placed on ground will grow to trees (contributed)
|
||||
- Optimized map saving (does not re-save everything all the time)
|
||||
- New mob system and new mob: dungeon master
|
||||
- Death/respawn screen
|
||||
|
||||
0.2.20110922_3:
|
||||
- Fix the build for MSVC2010; also released for windows using MSVC2010.
|
||||
|
||||
0.2.20110922_1:
|
||||
- Make client report a newer version number to the server than 2011-07-31 does and make server disallow old clients
|
||||
|
||||
0.2.20110922:
|
||||
- Map is saved in an SQLite database file (by Queatz)
|
||||
- Ladders (MarkTraceur)
|
||||
- Lava
|
||||
- Apple trees (sfan5)
|
||||
- Slightly better looking inventory with transparency
|
||||
- /me chat command (Oblomov)
|
||||
- Using chosen map seed possible through fixed_map_seed configuration option (kahrl)
|
||||
- Fix the long-existed PeerNotFound loop bug
|
||||
- Some translations and localization-related fixes
|
||||
- Lots of small fixes
|
||||
|
||||
2011-07-31_3:
|
||||
- Fixes a bug that made the server to deny non-empty passwords from players connecting the first time
|
||||
|
||||
2011-07-31_2:
|
||||
- Fixes a bug that caused the server to always read an empty password from the client when a client connected.
|
||||
|
||||
2011-07-31:
|
||||
- A number of small fixes, build system stuff and such (refer to version control log)
|
||||
- Map generator no longer crashes at generation limit
|
||||
- Fixed mapgen producing lots of cut-down trees
|
||||
- Some minor tweaks in map generator (some contributed)
|
||||
- Volumetric clouds (contributed)
|
||||
- Icon added (graphic contributed)
|
||||
- Key configuration menu (contributed)
|
||||
- Decorative blocks and items: bookshelf, sandstone, cactus, clay, brick, papyrus, rail, paper, book (contributed)
|
||||
- Jungles!
|
||||
- Hotbar is a bit smaller
|
||||
- Health is now enabled by default; You can now eat cooked rats to heal yourself.
|
||||
- Finally added sword textures, altough sword is still of no use
|
||||
- Creative mode now preserves normal mode inventory
|
||||
|
||||
2011-07-04:
|
||||
- Many small fixes
|
||||
- Code reorganizing to aid further development
|
||||
- Renewed map generator
|
||||
|
||||
2011-06-02:
|
||||
- Password crash on windows fixed
|
||||
- Optimized server CPU usage a lot
|
||||
- Furnaces now work also while players are not near to them
|
||||
|
||||
2011-05-29:
|
||||
- Optimized smooth lighting
|
||||
- A number of small fixes
|
||||
- Added clouds and simple skyboxes
|
||||
- The glass block added
|
||||
- Added key configuration to config file
|
||||
- Player privileges on server
|
||||
- Slightly updated map format
|
||||
- Player passwords
|
||||
- All textures first searched from texture_path
|
||||
- Map directory ("map") has been renamed to "world" (just rename it to load an old world)
|
||||
- Mouse inversion (invert_mouse)
|
||||
- Grass doesn't grow immediately anymore
|
||||
- Fence added
|
||||
|
||||
2011-04-24:
|
||||
- Smooth lighting with simple ambient occlusion
|
||||
- Updated main menu
|
||||
|
||||
2011-04-23_0_test:
|
||||
- Small bug fixes
|
||||
- Item drop multiplication fixed
|
||||
- HP added
|
||||
- Added A simple monster which spawns to dark places at map generation time
|
||||
- Some code refactoring and cleaning (possibly new bugs)
|
||||
|
||||
2011-04-11:
|
||||
- Fixed crafting a bit
|
||||
|
||||
2011-04-10_0:
|
||||
- Asynchronous map generation
|
||||
- New object system
|
||||
|
||||
2011-04-06:
|
||||
- Mesh update of node addition/removal is now done asynchronously on client, removing frametime spike
|
||||
- Node addition/removal is sent directly only to clients that are closer than 100 nodes to the modification. For the others, the modified blocks are set unsent. (and are re-sent when applicable)
|
||||
|
||||
2011-04-05:
|
||||
- Made furnace usable
|
||||
- Added cobblestone
|
||||
- Added wood, stone and steel tools: pickaxes, shovels and axes
|
||||
- Incremented to version 0.0.2
|
||||
|
||||
2011-04-04:
|
||||
- Cleaned client to be completely synchronous, except for the mesh calculation, which is now done with queues in a separate thread.
|
||||
- Added node metadata support
|
||||
- Added chests
|
||||
|
||||
2011-02-17:
|
||||
- Added better handling of textures. Now many file extensions are searched. Also too large textures are not put on the texture atlas, and the construction of the texture atlas is stopped when it is full.
|
||||
|
||||
2011-02-16:
|
||||
- Better handling of Ctrl-C on POSIX systems
|
||||
|
||||
2011-02-15:
|
||||
- Fixed a problem of not saving and loading the "lighting expired" value of MapBlocks properly. This caused high server CPU usage.
|
||||
- Ctrl-C handling on POSIX systems
|
||||
- Added simple command support to server
|
||||
- Added settings enable_texture_atlas and texture_path
|
||||
|
||||
2011-02-14:
|
||||
- Created changelog.txt
|
||||
- Added sneaking/crouching
|
||||
- Modified the looks of the hotbar and cleaned code
|
||||
- Added code to allow generating 3D cube images for inventory
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
Texture Overrides
|
||||
=================
|
||||
|
||||
You can override the textures of a node from a texture pack using
|
||||
texture overrides. To do this, create a file in a texture pack
|
||||
called override.txt
|
||||
|
||||
Basic Format
|
||||
------------
|
||||
|
||||
Each line in an override.txt file is a rule. It consists of
|
||||
|
||||
nodename face-selector texture
|
||||
|
||||
For example,
|
||||
|
||||
default:dirt_with_grass sides default_stone.png
|
||||
|
||||
You can use ^ operators as usual:
|
||||
|
||||
default:dirt_with_grass sides default_stone.png^[brighten
|
||||
|
||||
Face Selectors
|
||||
--------------
|
||||
|
||||
| face-selector | behavior |
|
||||
|---------------|---------------------------------------------------|
|
||||
| left | x- |
|
||||
| right | x+ |
|
||||
| front | z- |
|
||||
| back | z+ |
|
||||
| top | y+ |
|
||||
| bottom | y- |
|
||||
| sides | x-, x+, z-, z+ |
|
||||
| all | All faces. You can also use '*' instead of 'all'. |
|
||||
161
doc/texture_packs.txt
Normal file
161
doc/texture_packs.txt
Normal file
@@ -0,0 +1,161 @@
|
||||
Minetest Texture Pack Reference
|
||||
===============================
|
||||
|
||||
Texture packs allow you to replace textures provided by a mod with your own
|
||||
textures.
|
||||
|
||||
Texture pack directory structure
|
||||
--------------------------------
|
||||
|
||||
textures
|
||||
|-- Texture Pack
|
||||
| |-- screenshot.png
|
||||
| |-- description.txt
|
||||
| |-- override.txt
|
||||
| |-- your_texture_1.png
|
||||
| |-- your_texture_2.png
|
||||
`-- Another Texture Pack
|
||||
|
||||
### Texture Pack
|
||||
This is a directory containing the entire contents of a single texture pack.
|
||||
It can be chosen more or less freely and will also become the name of the
|
||||
texture pack. The name must not be “base”.
|
||||
|
||||
### `description.txt`
|
||||
A file containing a short description of the texture pack to be shown in the
|
||||
texture packs tab.
|
||||
|
||||
### `screenshot.png`
|
||||
A preview image showing an in-game screenshot of this texture pack; it will be
|
||||
shown in the texture packs tab. It should have an aspect ratio of 3:2 and a
|
||||
minimum size of 300×200 pixels.
|
||||
|
||||
### `your_texture_1.png`, `your_texture_2.png`, etc.
|
||||
Any other PNG files will be interpreted as textures. They must have the same
|
||||
names as the textures they are supposed to override. For example, to override
|
||||
the apple texture of Minetest Game, add a PNG file named `default_apple.png`.
|
||||
|
||||
The custom textures do not necceessarily require the same size as their
|
||||
originals, but this might be required for a few particular textures. When
|
||||
unsure, just test your texture pack in-game.
|
||||
|
||||
Texture modifiers
|
||||
-----------------
|
||||
|
||||
See lua_api.txt for texture modifiers
|
||||
|
||||
Special textures
|
||||
----------------
|
||||
|
||||
These texture names are hardcoded into the engine but can also be overwritten
|
||||
by texture packs. All existing fallback textures can be found in the directory
|
||||
`textures/base/pack`.
|
||||
|
||||
### Gameplay textures
|
||||
|
||||
* `bubble.png`: the bubble texture when the player is drowning
|
||||
|
||||
* `crack_anylength.png`: node overlay texture when digging
|
||||
|
||||
* `crosshair.png`
|
||||
* the crosshair texture in the center of the screen. The settings
|
||||
`crosshair_color` and `crosshair_alpha` are used to create a cross
|
||||
when no texture was found
|
||||
|
||||
* `halo.png`: used for the node highlighting mesh
|
||||
|
||||
* `heart.png`: used to display the health points of the player
|
||||
|
||||
* `minimap_mask_round.png`: round minimap mask, white gets replaced by the map
|
||||
* `minimap_mask_square.png`: mask used for the square minimap
|
||||
* `minimap_overlay_round.png`: overlay texture for the round minimap
|
||||
* `minimap_overlay_square.png`: overlay texture for the square minimap
|
||||
* `object_marker_red.png`: texture for players on the minimap
|
||||
* `player_marker.png`: texture for the own player on the square minimap
|
||||
|
||||
* `player.png`: front texture of the 2D upright sprite player
|
||||
* `player_back.png`: back texture of the 2D upright sprite player
|
||||
|
||||
* `progress_bar.png`: foreground texture of the loading screen's progress bar
|
||||
* `progress_bar_bg.png`: background texture of the loading screen's progress bar
|
||||
|
||||
* `moon.png`: texture of the moon. Default texture is generated by Minetest
|
||||
* `moon_tonemap.png`: tonemap to be used when `moon.png` was found
|
||||
* `sun.png`: texture of the sun. Default texture is generated by Minetest
|
||||
* `sun_tonemap.png`: tonemap to be used when `sun.png` was found
|
||||
* `sunrisebg.png`: shown sky texture when the sun rises
|
||||
|
||||
* `smoke_puff.png`: texture used when an object died by punching
|
||||
|
||||
* `unknown_item.png`: shown texture when an item definition was not found
|
||||
* `unknown_node.png`: shown texture when a node definition was not found
|
||||
* `unknown_object.png`: shown texture when an entity definition was not found
|
||||
|
||||
* `wieldhand.png`: texture of the wieldhand
|
||||
|
||||
### Mainmenu textures
|
||||
|
||||
* `menu_bg.png`: used as mainmenu background when the clouds are disabled
|
||||
* `menu_header.png`: header texture when no texture pack is selected
|
||||
|
||||
* `no_screenshot.png`
|
||||
* texture when no screenshot was found for a texture pack or mod
|
||||
|
||||
* `server_flags_creative.png`: icon for creative servers
|
||||
* `server_flags_damage.png`: icon for enabled damage on servers
|
||||
* `server_flags_favorite.png`: icon for your favorite servers
|
||||
* `server_flags_pvp.png`: icon for enabled PvP on servers
|
||||
|
||||
### Android textures
|
||||
|
||||
* `down_arrow.png`
|
||||
* `left_arrow.png`
|
||||
* `right_arrow.png`
|
||||
* `up_arrow.png`
|
||||
|
||||
* `drop_btn.png`
|
||||
* `fast_btn.png`
|
||||
* `fly_btn.png`
|
||||
* `jump_btn.png`
|
||||
* `noclip_btn.png`
|
||||
|
||||
* `camera_btn.png`
|
||||
* `chat_btn.png`
|
||||
* `inventory_btn.png`
|
||||
* `rangeview_btn.png`
|
||||
|
||||
* `debug_btn.png`
|
||||
* `gear_icon.png`
|
||||
* `rare_controls.png`
|
||||
|
||||
Texture Overrides
|
||||
-----------------
|
||||
|
||||
You can override the textures of a node from a texture pack using
|
||||
texture overrides. To do this, create a file in a texture pack
|
||||
called override.txt
|
||||
|
||||
Each line in an override.txt file is a rule. It consists of
|
||||
|
||||
nodename face-selector texture
|
||||
|
||||
For example,
|
||||
|
||||
default:dirt_with_grass sides default_stone.png
|
||||
|
||||
You can use ^ operators as usual:
|
||||
|
||||
default:dirt_with_grass sides default_stone.png^[brighten
|
||||
|
||||
Here are face selectors you can choose from:
|
||||
|
||||
| face-selector | behavior |
|
||||
|---------------|---------------------------------------------------|
|
||||
| left | x- |
|
||||
| right | x+ |
|
||||
| front | z- |
|
||||
| back | z+ |
|
||||
| top | y+ |
|
||||
| bottom | y- |
|
||||
| sides | x-, x+, z-, z+ |
|
||||
| all | All faces. You can also use '*' instead of 'all'. |
|
||||
@@ -1,12 +1,13 @@
|
||||
=============================
|
||||
Minetest World Format 22...25
|
||||
Minetest World Format 22...27
|
||||
=============================
|
||||
|
||||
This applies to a world format carrying the block serialization version
|
||||
22...25, used at least in
|
||||
22...27, used at least in
|
||||
- 0.4.dev-20120322 ... 0.4.dev-20120606 (22...23)
|
||||
- 0.4.0 (23)
|
||||
- 24 was never released as stable and existed for ~2 days
|
||||
- 27 was added in 0.4.15-dev
|
||||
|
||||
The block serialization version does not fully specify every aspect of this
|
||||
format; if compliance with this format is to be checked, it needs to be
|
||||
@@ -262,15 +263,36 @@ u8 flags
|
||||
- 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.
|
||||
- 0x04: lighting_expired: Not used in version 27 and above. 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.
|
||||
|
||||
u16 lighting_complete
|
||||
- Added in version 27.
|
||||
- This contains 12 flags, each of them corresponds to a direction.
|
||||
- Indicates if the light is correct at the sides of a map block.
|
||||
Lighting may not be correct if the light changed, but a neighbor
|
||||
block was not loaded at that time.
|
||||
If these flags are false, Minetest will automatically recompute light
|
||||
when both this block and its required neighbor are loaded.
|
||||
- The bit order is:
|
||||
nothing, nothing, nothing, nothing,
|
||||
night X-, night Y-, night Z-, night Z+, night Y+, night X+,
|
||||
day X-, day Y-, day Z-, day Z+, day Y+, day X+.
|
||||
Where 'day' is for the day light bank, 'night' is for the night
|
||||
light bank.
|
||||
The 'nothing' bits should be always set, as they will be used
|
||||
to indicate if direct sunlight spreading is finished.
|
||||
- Example: if the block at (0, 0, 0) has
|
||||
lighting_complete = 0b1111111111111110,
|
||||
then Minetest will correct lighting in the day light bank when
|
||||
the block at (1, 0, 0) is also loaded.
|
||||
|
||||
u8 content_width
|
||||
- Number of bytes in the content (param0) fields of nodes
|
||||
if map format version <= 23:
|
||||
|
||||
2
fonts/Arimo-LICENSE.txt
Normal file
2
fonts/Arimo-LICENSE.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Arimo - Apache License, version 2.0
|
||||
Arimo-Regular.ttf: Digitized data copyright (c) 2010-2012 Google Corporation.
|
||||
BIN
fonts/Arimo-Regular.ttf
Normal file
BIN
fonts/Arimo-Regular.ttf
Normal file
Binary file not shown.
2
fonts/Cousine-LICENSE.txt
Normal file
2
fonts/Cousine-LICENSE.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Cousine - Apache License, version 2.0
|
||||
Cousine-Regular.ttf: Digitized data copyright (c) 2010-2012 Google Corporation.
|
||||
BIN
fonts/Cousine-Regular.ttf
Normal file
BIN
fonts/Cousine-Regular.ttf
Normal file
Binary file not shown.
13
fonts/DroidSansFallbackFull-LICENSE.txt
Normal file
13
fonts/DroidSansFallbackFull-LICENSE.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright (C) 2008 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user