Compare commits
780 Commits
Author | SHA1 | Date | |
---|---|---|---|
196f206d3e | |||
1ca25eec9d | |||
b92f7431ef | |||
7f687777a6 | |||
6b2887e3bf | |||
14cc07bfd3 | |||
ad6c2cf035 | |||
2033b2cc65 | |||
bfde214c52 | |||
6e0e2b8be9 | |||
64a923f7fb | |||
2ff9058a62 | |||
a2c9523bce | |||
7fa03c7a9b | |||
8af8dc49a0 | |||
ccf03ea404 | |||
6688ddf6d4 | |||
da10af919e | |||
bae58b3806 | |||
ec248d3cb0 | |||
667e130c52 | |||
1fa8180e7f | |||
068e0b167f | |||
21f5eaade0 | |||
5f61379757 | |||
ad486bc863 | |||
5ccf965825 | |||
58f6994e08 | |||
cf0e49fb4a | |||
382e2acd9b | |||
b042106fdc | |||
f583d90c94 | |||
ab1a79b13c | |||
2696b0cd91 | |||
5b3b609270 | |||
24900f7da5 | |||
f42deb4026 | |||
e10e0f94d6 | |||
be6fe9f592 | |||
7fedf0b5d9 | |||
aafe31c14e | |||
ef20f9e12b | |||
5673a71752 | |||
02c4a05e60 | |||
6f80fd3737 | |||
3484ff23ad | |||
689f0c5478 | |||
f4f90520ec | |||
20b433881b | |||
3d02145271 | |||
70c0181b59 | |||
ab3b1a35f5 | |||
c284e52963 | |||
ab4940505e | |||
506eca22bc | |||
bf3efa0bb7 | |||
ee72bc722c | |||
57db3f748c | |||
9318c71659 | |||
d4b0b73ae0 | |||
ef7bd43829 | |||
513609dcfd | |||
5c8bd34957 | |||
7e1b07fddd | |||
ecea5364f1 | |||
59dbeebc2f | |||
876a9ca5d2 | |||
255031fc91 | |||
0df2753a68 | |||
0ea6065a09 | |||
5692c15b4d | |||
e9fbd3d75d | |||
abe1b9f559 | |||
bcf76eab1d | |||
e376d57bd2 | |||
37b206e49f | |||
e74e091e78 | |||
ed1d64d8aa | |||
145b7bfef3 | |||
b389f38120 | |||
64470dc786 | |||
3d709dfa1d | |||
ace7ec953e | |||
b52ea3de15 | |||
aedd209440 | |||
bbb88e6387 | |||
0b025e6392 | |||
8d8f2f79d0 | |||
8c71f3d826 | |||
9c459e77ac | |||
11b3407671 | |||
b0e55c52c8 | |||
f3ce25fc72 | |||
7e9000b502 | |||
fb0217042b | |||
465d8cae3e | |||
c0557b2c23 | |||
c2209c120e | |||
da877ccf57 | |||
160dc21bc1 | |||
ac50b3e3ce | |||
d4a007c051 | |||
1afb8f249e | |||
3afcd68e9b | |||
c2001b3b52 | |||
63ebdfd139 | |||
702070accb | |||
04a46d0671 | |||
70d91bc64d | |||
280f1b1c39 | |||
283636bfdb | |||
094ad004a4 | |||
b90aabec80 | |||
495fa32873 | |||
7754555707 | |||
1e9c61f241 | |||
7f3e9e65b3 | |||
ca81e9b8c6 | |||
a587972010 | |||
d5907d5f1e | |||
12f1703537 | |||
8f85ca57f3 | |||
496a1a24d2 | |||
5f121b586d | |||
ee6d2f2468 | |||
41a4073d4c | |||
a6aa68d5b4 | |||
223562d687 | |||
f52085a40f | |||
faa088e2c5 | |||
bd0c627a20 | |||
d1ece74652 | |||
d1db66bf4f | |||
8ab7c54d76 | |||
5b57815af1 | |||
dfe74948e2 | |||
62d5d5954e | |||
d603707e1a | |||
5134510356 | |||
21b3c841bd | |||
0c841771a7 | |||
0132bfe41e | |||
2824e4bb7c | |||
ed83e30d68 | |||
2c5670563a | |||
b75a17984a | |||
a2d7678ffd | |||
3ae382c913 | |||
91997d9342 | |||
8b5ad0f028 | |||
319b9eeeaf | |||
d4e1bd053e | |||
9d9e9b6709 | |||
dbfe435abf | |||
08c60cfc30 | |||
9596d00a18 | |||
49cc4c7c63 | |||
36df80fc45 | |||
3f14d1012d | |||
045abbd6d7 | |||
454e0da531 | |||
5870fd48f6 | |||
47d6fbf884 | |||
7c3854de27 | |||
cc371ac726 | |||
eb5a5b56e1 | |||
3ff296961e | |||
12a971660d | |||
b6626f76b5 | |||
e40f25f1fb | |||
3611af1dda | |||
809e5933c4 | |||
2d8207a924 | |||
a4b94a3347 | |||
db08c0d721 | |||
74ed63f46b | |||
f33cc02080 | |||
c5c9e423ca | |||
4ccafd1518 | |||
bf8404fcf7 | |||
edba1dcb02 | |||
fe67ffda7c | |||
bcf98df5fa | |||
08727bcd69 | |||
f928780946 | |||
bb084294ce | |||
20687a6301 | |||
b431ae1c77 | |||
fe710c99a6 | |||
c5e97867f3 | |||
8817d1c696 | |||
d883012491 | |||
67c01a44c2 | |||
77c9408721 | |||
3294a2a515 | |||
57577596d6 | |||
b4abb07572 | |||
271b2befaa | |||
5d19fd6923 | |||
7ffd176f48 | |||
8f1f3760f0 | |||
71dff2ac4a | |||
fa4c77feba | |||
c81165b2c8 | |||
996f168aa3 | |||
40ed77185e | |||
a1d35f3d69 | |||
c2f3c99cad | |||
48baf1acb5 | |||
886537ef50 | |||
e5189760b3 | |||
1d5bc15f9a | |||
1aafcdd7e0 | |||
0cdee1d8f5 | |||
b66a61a10f | |||
57979686d9 | |||
2e413b521a | |||
0f7d0bfd7a | |||
c51ebcb74a | |||
bae17cd88c | |||
7b46d3b6af | |||
bdc09d2313 | |||
2c666891a8 | |||
3d1fc42f66 | |||
36d024a716 | |||
120e96938d | |||
502720b14d | |||
0157175346 | |||
b3f17cda9f | |||
15ba96467d | |||
da7e8e4810 | |||
175a9f8ff5 | |||
b91e047868 | |||
7e9c5a3576 | |||
c714d43319 | |||
626cd8e9c7 | |||
f855beeda5 | |||
18956c7f69 | |||
a8a60d33a3 | |||
eec1c5a03b | |||
e523c3a296 | |||
b25317fc64 | |||
d104b9b10f | |||
758d5010b8 | |||
63b3542d00 | |||
5bd44c21ef | |||
c7d558c09e | |||
55f81d0802 | |||
a533434b58 | |||
08706313f4 | |||
6737952fbf | |||
519d166ce3 | |||
be9121214c | |||
011ad78b42 | |||
4ec0fd974b | |||
67b13a5942 | |||
ae7206c006 | |||
2917562728 | |||
c2d1a5ed4b | |||
4d9fd7ad61 | |||
24559d012e | |||
2668619638 | |||
6335525757 | |||
c54a7e882f | |||
701abc2d2f | |||
98216810ef | |||
a57d2db54a | |||
d68d2c08ef | |||
e2b3ab768a | |||
e6d0d775e3 | |||
8d43b984fc | |||
fe021281e6 | |||
9e4f0d3689 | |||
acfd58cdeb | |||
b377aaa50d | |||
5fe831ed13 | |||
2f46103ff8 | |||
077316b4cd | |||
b847888cb7 | |||
7c42c41170 | |||
08eec2beb7 | |||
9b45e7b3e9 | |||
91182d6a9e | |||
86fd616f3c | |||
2a74032745 | |||
ecf160d93d | |||
6a55e150af | |||
d2aae95c39 | |||
02921baa7a | |||
07e11427cf | |||
68212967c0 | |||
73e4666f28 | |||
bd4d2dff1c | |||
61d7c43c83 | |||
780f991a87 | |||
1c78fd346d | |||
da69fcdf91 | |||
37c81f70b0 | |||
7b90044574 | |||
b87ef5ccde | |||
07a5fca432 | |||
d5e19d70c2 | |||
efb81d188e | |||
297192dd39 | |||
f14b0a6ff5 | |||
0850314d74 | |||
ad118ea98d | |||
c52ad140ae | |||
0f0dd0f6e8 | |||
1f6d633037 | |||
a16413f96c | |||
6d67badcac | |||
1d45b27c12 | |||
496521f4a1 | |||
28ecb3b261 | |||
c68b8274fe | |||
78c632ebd4 | |||
d1b132555b | |||
9d3a526324 | |||
bb18eeccaf | |||
d5f1f964e3 | |||
1ec31d8472 | |||
60e5b299af | |||
37dd910747 | |||
89c45993ac | |||
0819d4bade | |||
f6dfa4a1cb | |||
e3dd3d19cd | |||
86849d9eec | |||
c88c0a98fd | |||
2e950ac61c | |||
2b215848d8 | |||
e86955afae | |||
d560f59a74 | |||
b06368adf2 | |||
1dd9fdb530 | |||
38500da655 | |||
bee5b316a8 | |||
ae426878d4 | |||
eb1805ea0a | |||
1104d571b0 | |||
6dcf541f6e | |||
1470b9df79 | |||
8715b83ff0 | |||
57eb906047 | |||
df19b4eab0 | |||
c8b1671ef0 | |||
96aac5ff5b | |||
b6889134d3 | |||
cadc8b34d7 | |||
48ab62db88 | |||
9ab50702fb | |||
42700a4b4b | |||
8bc93598c6 | |||
f07c4dcd83 | |||
3c9d0893ee | |||
12b1541971 | |||
e5c5c2637e | |||
55a16cd2c6 | |||
3e5852993d | |||
4a5206e3a7 | |||
fed2151d70 | |||
58038a7941 | |||
0ff09e018d | |||
7998de671f | |||
fc791d80f0 | |||
e67a60376f | |||
ea9c4012d5 | |||
d7f176dfd8 | |||
c5f11d74d4 | |||
42afe679a7 | |||
0413cb67b8 | |||
f06f66ccc2 | |||
04f045158f | |||
4f32fd253c | |||
0196c4793a | |||
fa17fe31d6 | |||
788ae97ba1 | |||
1a6ad498d7 | |||
2effe40dc5 | |||
81f8c8aef8 | |||
9bbe7f99da | |||
d42ae715b8 | |||
e837621537 | |||
fd87b04f3c | |||
e4b1c93512 | |||
b0ae488277 | |||
0bd2efcfc1 | |||
09a229b412 | |||
208c9f4901 | |||
55ab3a117d | |||
ec95f47021 | |||
1e691c4429 | |||
75caa9167c | |||
47efa2f558 | |||
2c122052d4 | |||
c3f3406e8e | |||
68192a17e9 | |||
022d22ceca | |||
af3c91862c | |||
7fbf25d6ca | |||
f8bc1e1714 | |||
ddea6c431e | |||
614e9cfe8d | |||
6e00ddee2a | |||
3109f38b3c | |||
5868274b00 | |||
c824d69182 | |||
c7e2d59461 | |||
631f7f46c7 | |||
178db04526 | |||
23ba2d3a0c | |||
7fee589e03 | |||
5b2a896180 | |||
56d6eaed85 | |||
d92034e3f7 | |||
0acd9a2ccb | |||
02a82c9d7a | |||
89b9c3e69e | |||
048aaa2616 | |||
581c390591 | |||
138eb71db6 | |||
bca0142e7f | |||
41a3345718 | |||
3c9d71e6f7 | |||
fbac9be51c | |||
fa9a34554b | |||
f7325d26b6 | |||
9b62d8a504 | |||
bcb4426ec7 | |||
4ea74466e4 | |||
3d26b33e5b | |||
7b30c26a45 | |||
78311a27a1 | |||
6fdfd2554c | |||
53179b8d10 | |||
1906ab84f5 | |||
1799754a8f | |||
32f7051eb8 | |||
67fc2247fc | |||
c0de5646d2 | |||
5e4a6e8ac6 | |||
36a78c87d7 | |||
0ad3306c79 | |||
0f6e75bcb5 | |||
3e05870706 | |||
34c768d394 | |||
b848e35ca5 | |||
0cbb516ae2 | |||
54235f3276 | |||
992f295880 | |||
6171fb43f0 | |||
7d70d25eeb | |||
e9d26e2ee3 | |||
f844a4f379 | |||
1d6fbe04cd | |||
0664570d22 | |||
5e9e3f7e84 | |||
995256744a | |||
471d1cf159 | |||
3be2f12beb | |||
cabf80b743 | |||
088385493a | |||
1b745d401d | |||
2ecbc43a7a | |||
619ac52693 | |||
61a197ffd8 | |||
14b99a72a9 | |||
76211624ac | |||
b408e9cce6 | |||
20fa037313 | |||
60cf3f85b6 | |||
6c83ea0b48 | |||
265c40b558 | |||
00c2dde4ea | |||
4fba897a96 | |||
ea49eb3f3d | |||
0ac096991c | |||
2df7ce20dd | |||
db129f4ca0 | |||
72f4c6be48 | |||
79dbafc13b | |||
1a2eb89f17 | |||
f018e06d9b | |||
9862bbc8e5 | |||
3661cb61e3 | |||
0bd13d11cf | |||
d89bb69a22 | |||
9524ff67a3 | |||
30b0a155fb | |||
4473627de0 | |||
d7a7456007 | |||
b74954969c | |||
07141b4a2e | |||
fcceec0e8c | |||
f1f96dbe6b | |||
594365310d | |||
71c7e21669 | |||
e38099225c | |||
5644ab4bd3 | |||
fe450b4144 | |||
3d44804074 | |||
60f6564c75 | |||
f17d791173 | |||
497e6f6257 | |||
98551edd94 | |||
c5b0fe72ea | |||
d42f77cc5f | |||
d476d017a4 | |||
1886d293d7 | |||
21b457c9e1 | |||
80d49095f5 | |||
f4f9e58ef2 | |||
55fd286083 | |||
1231f72628 | |||
15b82f5b03 | |||
f796194c69 | |||
84e4ae1881 | |||
f15f35c604 | |||
be918d2d98 | |||
6bf552eb10 | |||
983af7b1c0 | |||
22dc7b2d9e | |||
cd5893db02 | |||
9d6df824d6 | |||
5809c28ae3 | |||
e77ef553ff | |||
1fafed3387 | |||
e0bec501f2 | |||
3e9afe097c | |||
5775c9147c | |||
ba1ae07b4a | |||
50eb079813 | |||
da0fe31443 | |||
2199be5108 | |||
b5ea7d17b2 | |||
dcf2465441 | |||
6386684f3e | |||
ba33639887 | |||
541b2d79c7 | |||
37347d40f4 | |||
d61803b65f | |||
e0cb3fce02 | |||
70ef7864c1 | |||
fc902a77de | |||
3e5f3f28d2 | |||
d8daee7e47 | |||
7681682d28 | |||
b9422ed44e | |||
b1e0864cf1 | |||
90f24e312d | |||
e7a55734d3 | |||
b36b154257 | |||
3976dc6a5b | |||
8ea031ef77 | |||
8c3f96d738 | |||
8d3d558e42 | |||
de3adb5859 | |||
acafe5ca86 | |||
12c763a6c7 | |||
098ea0d10a | |||
f14b411157 | |||
1a6298958e | |||
fafbe2c268 | |||
dc7cbdd5ab | |||
5cd4b5a231 | |||
f62afa02b7 | |||
7a892c70e6 | |||
682d79b82a | |||
8b384fb257 | |||
d6c33da355 | |||
386dcdef06 | |||
54b87e955d | |||
f32a3ff57c | |||
16fe1efcd8 | |||
fa43bd8a56 | |||
e426f64993 | |||
ab7b7c7504 | |||
80664f9f8a | |||
0ca43e42bc | |||
33aa5e77dc | |||
f8e273da15 | |||
9ece86cc7a | |||
7d93272caa | |||
64fe69f382 | |||
a2d4e57716 | |||
8114c3dbab | |||
e6cef57661 | |||
0736d30e33 | |||
da5f4a939e | |||
a84e2669c7 | |||
ccee025ce3 | |||
8c801529df | |||
3ddff2fbea | |||
eafd1ebc43 | |||
3623398b78 | |||
b25889e742 | |||
9f4dc1412b | |||
cfef21f4d9 | |||
8556dd30e2 | |||
8cd049c224 | |||
12d5ca2f48 | |||
3ecafbcfb4 | |||
082b36d3e7 | |||
7be008936e | |||
6e1a329763 | |||
47b197e4d5 | |||
be05441e77 | |||
aadac1223d | |||
9a6cb2d7c8 | |||
f4e77edcc6 | |||
e38f69d549 | |||
874b1ae326 | |||
1977ae19ae | |||
7bbbcbf7b0 | |||
4d7dbfc826 | |||
787ccb5747 | |||
12bcfeab4d | |||
14334a1d89 | |||
6749da1070 | |||
7a29d26e3e | |||
7cba7af894 | |||
a71948c007 | |||
c3d2bc383b | |||
7d55320d5c | |||
0d3bca790c | |||
ffba9d978e | |||
1a5f89e750 | |||
51891122f2 | |||
537f94c28e | |||
da0cc7f6f6 | |||
b57dd0f9b2 | |||
8fdcfea9f9 | |||
9de43cdf7d | |||
a2ecc51fbc | |||
d90a081722 | |||
70248505ae | |||
22e32a01ad | |||
c94349eaef | |||
41c2b2aeea | |||
cb57f70aab | |||
f18871d60c | |||
c17c317669 | |||
7c966db4bc | |||
e5304ce674 | |||
28884cc784 | |||
dfee51c21e | |||
20053d6b52 | |||
079b796031 | |||
9c887e0b32 | |||
2fb40be409 | |||
f8f7502e32 | |||
b998ab1b3a | |||
d979293f14 | |||
676822d286 | |||
a5ad30748d | |||
45bc0b245f | |||
aa676ab878 | |||
f80fafbcfb | |||
7f317871d4 | |||
68f5740dcc | |||
6c6cc2159a | |||
aa254e2835 | |||
29252c6fb2 | |||
ac843f8fe7 | |||
0410b5e0ca | |||
3a98245f62 | |||
00a0d9a5d4 | |||
5d28040915 | |||
62dbf29301 | |||
6493e5fefb | |||
42cc6d2c31 | |||
3a55e19055 | |||
ea2a7d3b1f | |||
2c355a8642 | |||
777088481b | |||
6b055ae18a | |||
4c9944b263 | |||
73d998ccdf | |||
3fcb7821d7 | |||
ed9fd475de | |||
2cc6640edf | |||
bbf17c9eca | |||
1ab0fc12a7 | |||
5569950b26 | |||
363b95c003 | |||
8422f2ef52 | |||
36d18cb161 | |||
b47a556472 | |||
7d2dfe4101 | |||
04f01bc57f | |||
7a3cff5529 | |||
8f095c62a8 | |||
f600a9f645 | |||
9e54b379c8 | |||
5994ac8dc5 | |||
c198d8c57e | |||
09dbaf7972 | |||
0add474af2 | |||
0ea23a50d3 | |||
2f39cad09b | |||
a4e144e4c8 | |||
f4512cb5b6 | |||
38a8351327 | |||
a5d40e13be | |||
4b8410a982 | |||
250be40ecd | |||
322967d2d1 | |||
f41314185e | |||
6d79d157c3 | |||
6267f26027 | |||
535e611eb1 | |||
223e924edf | |||
556f0d48e3 | |||
57939c6c3f | |||
9542d119f6 | |||
7488f483c7 | |||
b0ec8f1b5a | |||
c76a91943c | |||
0472e61a9d | |||
e9a7782c88 | |||
76471dd137 | |||
11115c7d15 | |||
481d1758ad | |||
32bdb9a393 | |||
82299b94dc | |||
b1e2ece638 | |||
eaed418b10 | |||
8704afe5b1 | |||
c3a1545ca1 | |||
a1b8b68e92 | |||
b57ecb94df | |||
c66a98bbed | |||
25e1f84733 | |||
b8333cf82a | |||
abf0ca9c7e | |||
135d80eb86 | |||
0d49978341 | |||
4ef6810298 | |||
1d8def5c06 | |||
e41a411f1c | |||
e67e28d226 | |||
3d6f1685ad | |||
592ca341ea | |||
a88576afd1 | |||
6f6d46ddfc | |||
7c0abe9366 | |||
321bd66721 | |||
2729777b94 | |||
f3dc78204c | |||
b292975fbc | |||
3fb6ee5bdf | |||
ef8b7e230d | |||
c15bd9d529 | |||
41c1e99b1f | |||
70e8924082 | |||
f4a412d9c1 | |||
8148bbf95e | |||
2119054a95 | |||
ac810dbf9d | |||
8e51f318b3 | |||
93a2c40ebc | |||
ff0973fa4f | |||
1f85f001f9 | |||
279b85fc45 | |||
24578ca968 | |||
d0fad4b004 | |||
4bb9652c0f | |||
b6c12010b1 | |||
f5c8f881d7 | |||
0004c5e637 | |||
1cc8300ba9 | |||
fd5721faa8 | |||
09d910efcb | |||
acb0cecb36 | |||
c2307b8816 | |||
73113f3443 | |||
4d9b595a69 | |||
908d8e5f90 | |||
a0d7644a86 |
29
.gitignore
vendored
@ -1,9 +1,22 @@
|
||||
## Generic ignorable patterns and files
|
||||
*~
|
||||
.*.swp
|
||||
*bak*
|
||||
tags
|
||||
*.vim
|
||||
|
||||
## Files related to minetest development cycle
|
||||
*.patch
|
||||
/*.patch
|
||||
# GNU Patch reject file
|
||||
*.rej
|
||||
|
||||
## Editors and Development environments
|
||||
*~
|
||||
*.swp
|
||||
*.bak*
|
||||
*.orig
|
||||
# Vim
|
||||
*.vim
|
||||
# Kate
|
||||
.*.kate-swp
|
||||
.swp.*
|
||||
# Eclipse (LDT)
|
||||
.project
|
||||
.settings/
|
||||
.buildpath
|
||||
.metadata
|
||||
# Idea IDE
|
||||
.idea/*
|
||||
|
22
.luacheckrc
Normal file
@ -0,0 +1,22 @@
|
||||
unused_args = false
|
||||
allow_defined_top = true
|
||||
|
||||
read_globals = {
|
||||
"DIR_DELIM",
|
||||
"minetest", "core",
|
||||
"dump",
|
||||
"vector",
|
||||
"VoxelManip", "VoxelArea",
|
||||
"PseudoRandom", "PcgRandom",
|
||||
"ItemStack",
|
||||
"Settings",
|
||||
"unpack",
|
||||
-- Silence errors about custom table methods.
|
||||
table = { fields = { "copy", "indexof" } }
|
||||
}
|
||||
|
||||
-- Overwrites minetest.handle_node_drops
|
||||
files["mods/creative/init.lua"].globals = { "minetest" }
|
||||
|
||||
-- Don't report on legacy definitions of globals.
|
||||
files["mods/default/legacy.lua"].global = false
|
12
.travis.yml
Normal file
@ -0,0 +1,12 @@
|
||||
language: generic
|
||||
sudo: false
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- luarocks
|
||||
before_install:
|
||||
- luarocks install --local luacheck
|
||||
script:
|
||||
- $HOME/.luarocks/bin/luacheck --no-color ./mods
|
||||
notifications:
|
||||
email: false
|
519
LICENSE.txt
Normal file
@ -0,0 +1,519 @@
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
See README.txt in each mod directory for information about other authors.
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
License of menu/header.png
|
||||
Copyright (C) 2015 paramat CC BY-SA 3.0
|
||||
|
||||
|
||||
License of source code
|
||||
----------------------
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
See README.txt in each mod directory for information about other authors.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library 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 library 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 library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
58
README.txt
@ -1,52 +1,28 @@
|
||||
The main game for the Minetest game engine [minetest_game]
|
||||
==========================================================
|
||||
Minetest Game [minetest_game]
|
||||
=============================
|
||||
The main game for the Minetest engine
|
||||
=====================================
|
||||
|
||||
To use this game with Minetest, insert this repository as
|
||||
/games/minetest_game
|
||||
in the Minetest Engine.
|
||||
To use this game with the Minetest engine, insert this repository as
|
||||
/games/minetest_game
|
||||
|
||||
The Minetest Engine can be found in:
|
||||
https://github.com/minetest/minetest/
|
||||
The Minetest engine can be found in:
|
||||
https://github.com/minetest/minetest/
|
||||
|
||||
Compatibility
|
||||
--------------
|
||||
The minetest_game github master HEAD is generally compatible with the github
|
||||
master HEAD of minetest.
|
||||
The Minetest Game github master HEAD is generally compatible with the github
|
||||
master HEAD of the Minetest engine.
|
||||
|
||||
Additionally, when the minetest engine is tagged to be a certain version (eg.
|
||||
0.4.10), minetest_game is tagged with the version too.
|
||||
Additionally, when the Minetest engine is tagged to be a certain version (eg.
|
||||
0.4.10), Minetest Game is tagged with the version too.
|
||||
|
||||
When stable releases are made, minetest_game is packaged and made available in
|
||||
http://minetest.net/download
|
||||
When stable releases are made, Minetest Game is packaged and made available in
|
||||
http://minetest.net/downloads/
|
||||
and in case the repository has grown too much, it may be reset. In that sense,
|
||||
this is not a "real" git repository. (Package maintainers please note!)
|
||||
|
||||
License of source code
|
||||
----------------------
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
See README.txt in each mod directory for information about other authors.
|
||||
Licensing
|
||||
---------
|
||||
|
||||
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.
|
||||
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
See README.txt in each mod directory for information about other authors.
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
License of menu/header.png
|
||||
Copyright (C) 2013 BlockMen CC BY-3.0
|
||||
See LICENSE.txt
|
||||
|
@ -1 +1,3 @@
|
||||
name = Minetest
|
||||
name = Minetest Game
|
||||
author = minetest
|
||||
description = Bundled by default with Minetest, and aims to be lightweight, moddable, and fairly playable without mods.
|
||||
|
1205
game_api.txt
BIN
menu/header.png
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 1.9 KiB |
@ -1,28 +1,66 @@
|
||||
# This file contains settings of minetest_game that can be changed in
|
||||
# minetest.conf
|
||||
#
|
||||
# This file contains settings of Minetest Game that can be changed in
|
||||
# minetest.conf.
|
||||
# By default, all the settings are commented and not functional.
|
||||
# Uncomment settings by removing the preceding #.
|
||||
|
||||
# Whether creative mode (fast digging of all blocks, unlimited resources) should be enabled
|
||||
# Whether creative mode (fast digging of all blocks, unlimited resources) should
|
||||
# be enabled.
|
||||
#creative_mode = false
|
||||
|
||||
# The time in seconds after which the bones of a dead player can be looted by everyone
|
||||
# 0 to disable
|
||||
# Sets the behaviour of the inventory items when a player dies.
|
||||
# bones: Store items in a bone node but drop items if inside protected area.
|
||||
# drop: Drop items on the ground.
|
||||
# keep: Player keeps items.
|
||||
#bones_mode = bones
|
||||
|
||||
# The time in seconds after which the bones of a dead player can be looted by
|
||||
# everyone.
|
||||
# 0 to disable.
|
||||
#share_bones_time = 1200
|
||||
|
||||
# Whether fire should be disabled (all fire nodes will instantly disappear)
|
||||
#disable_fire = false
|
||||
# How much earlier the bones of a dead player can be looted by
|
||||
# everyone if the player dies in a protected area they don't own.
|
||||
# 0 to disable. By default it is "share_bones_time" divide by four.
|
||||
#share_bones_time_early = 300
|
||||
|
||||
# Whether steel tools, torches and cobblestone should be given to new players
|
||||
# Inform player of condition and location of new bones.
|
||||
#bones_position_message = false
|
||||
|
||||
# Whether fire should be enabled. If disabled, 'basic_flame' nodes will
|
||||
# disappear.
|
||||
# 'permanent_flame' nodes will remain with either setting.
|
||||
#enable_fire = true
|
||||
|
||||
# Enable flame sound.
|
||||
#flame_sound = true
|
||||
|
||||
# Whether lavacooling should be enabled.
|
||||
#enable_lavacooling = true
|
||||
|
||||
# Whether the stuff in initial_stuff should be given to new players.
|
||||
#give_initial_stuff = false
|
||||
#initial_stuff = default:pick_steel,default:axe_steel,default:shovel_steel,
|
||||
default:torch 99,default:cobble 99
|
||||
|
||||
# Whether the TNT mod should be enabled
|
||||
# Whether the TNT mod should be enabled.
|
||||
#enable_tnt = <true in singleplayer, false in multiplayer>
|
||||
|
||||
# The radius of a TNT explosion
|
||||
# The radius of a TNT explosion.
|
||||
#tnt_radius = 3
|
||||
|
||||
# Enable the stairs mod ABM that replaces the old 'upside down'
|
||||
# stair and slab nodes in old maps with the new param2 versions.
|
||||
#enable_stairs_replace_abm = false
|
||||
|
||||
# Whether to allow respawning in beds.
|
||||
# Default value is true.
|
||||
#enable_bed_respawn = true
|
||||
|
||||
# Whether players can skip night by sleeping.
|
||||
# Default value is true.
|
||||
#enable_bed_night_skip = true
|
||||
|
||||
# Whether the engine's spawn search, which does not check for a suitable
|
||||
# starting biome, is used.
|
||||
# Default value is false.
|
||||
#engine_spawn = false
|
||||
|
@ -1,18 +0,0 @@
|
||||
1.0.1 beta
|
||||
----------
|
||||
- Add backwards compatibility with PilzAdam's beds mod
|
||||
- Fix placement
|
||||
- Fix small bugs
|
||||
- Prevent possible crash
|
||||
|
||||
1.1
|
||||
---
|
||||
- Add fancy bed model (based on jp's model)
|
||||
- Add API to register beds
|
||||
- Allow players always to detach from bed (by donat-b)
|
||||
- If more than 50% of players want sleep they can skip the night
|
||||
- Don't show sleep dialog in singleplayer
|
||||
|
||||
1.1.1
|
||||
-----
|
||||
- Prevent possbile crash by trying to reposition leaving players
|
@ -1,29 +1,30 @@
|
||||
Minetest mod "Beds"
|
||||
===================
|
||||
by BlockMen (c) 2014-2015
|
||||
Minetest Game mod: beds
|
||||
=======================
|
||||
See license.txt for license information.
|
||||
|
||||
Version: 1.1.1
|
||||
Authors of source code
|
||||
----------------------
|
||||
Originally by BlockMen (MIT)
|
||||
Various Minetest developers and contributors (MIT)
|
||||
|
||||
About
|
||||
~~~~~
|
||||
This mod adds a bed to Minetest which allows to skip the night. To sleep rightclick the bed, if playing
|
||||
in singleplayer mode the night gets skipped imideatly. If playing on server you get shown how many other
|
||||
players are in bed too. If all players are sleeping the night gets skipped aswell. Also the night skip can be forced
|
||||
if more than 50% of the players are lying in bed and use this option.
|
||||
Authors of media (textures)
|
||||
---------------------------
|
||||
BlockMen (CC BY-SA 3.0)
|
||||
All textures unless otherwise noted
|
||||
|
||||
Another feature is a controled respawning. If you have slept in bed (not just lying in it) your respawn point
|
||||
is set to the beds location and you will respawn there after death.
|
||||
You can disable the respawn at beds by setting "enable_bed_respawn = false" in minetest.conf
|
||||
TumeniNodes (CC BY-SA 3.0)
|
||||
beds_bed_under.png
|
||||
|
||||
This mod adds a bed to Minetest which allows to skip the night.
|
||||
To sleep, rightclick the bed. If playing in singleplayer mode the night gets skipped
|
||||
immediately. If playing multiplayer you get shown how many other players are in bed too,
|
||||
if all players are sleeping the night gets skipped. The night skip can be forced if more
|
||||
than 50% of the players are lying in bed and use this option.
|
||||
|
||||
|
||||
License of source code, textures: WTFPL
|
||||
---------------------------------------
|
||||
(c) Copyright BlockMen (2014-2015)
|
||||
|
||||
|
||||
This program is free software. It comes without any warranty, to
|
||||
the extent permitted by applicable law. You can redistribute it
|
||||
and/or modify it under the terms of the Do What The Fuck You Want
|
||||
To Public License, Version 2, as published by Sam Hocevar. See
|
||||
http://sam.zoy.org/wtfpl/COPYING for more details.
|
||||
Another feature is a controlled respawning. If you have slept in bed (not just lying in
|
||||
it) your respawn point is set to the beds location and you will respawn there after
|
||||
death.
|
||||
You can disable the respawn at beds by setting "enable_bed_respawn = false" in
|
||||
minetest.conf.
|
||||
You can disable the night skip feature by setting "enable_bed_night_skip = false" in
|
||||
minetest.conf or by using the /set command in-game.
|
||||
|
@ -1,3 +1,27 @@
|
||||
|
||||
local reverse = true
|
||||
|
||||
local function destruct_bed(pos, n)
|
||||
local node = minetest.get_node(pos)
|
||||
local other
|
||||
|
||||
if n == 2 then
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
other = vector.subtract(pos, dir)
|
||||
elseif n == 1 then
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
other = vector.add(pos, dir)
|
||||
end
|
||||
|
||||
if reverse then
|
||||
reverse = not reverse
|
||||
minetest.remove_node(other)
|
||||
minetest.check_for_falling(other)
|
||||
else
|
||||
reverse = not reverse
|
||||
end
|
||||
end
|
||||
|
||||
function beds.register_bed(name, def)
|
||||
minetest.register_node(name .. "_bottom", {
|
||||
description = def.description,
|
||||
@ -9,8 +33,8 @@ function beds.register_bed(name, def)
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
stack_max = 1,
|
||||
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1},
|
||||
sounds = def.sounds or default.node_sound_wood_defaults(),
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = def.nodebox.bottom,
|
||||
@ -18,39 +42,74 @@ function beds.register_bed(name, def)
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = def.selectionbox,
|
||||
|
||||
},
|
||||
after_place_node = function(pos, placer, itemstack)
|
||||
local n = minetest.get_node_or_nil(pos)
|
||||
if not n or not n.param2 then
|
||||
minetest.remove_node(pos)
|
||||
return true
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = pointed_thing.under
|
||||
local node = minetest.get_node(under)
|
||||
local udef = minetest.registered_nodes[node.name]
|
||||
if udef and udef.on_rightclick and
|
||||
not (placer and placer:is_player() and
|
||||
placer:get_player_control().sneak) then
|
||||
return udef.on_rightclick(under, node, placer, itemstack,
|
||||
pointed_thing) or itemstack
|
||||
end
|
||||
local dir = minetest.facedir_to_dir(n.param2)
|
||||
local p = vector.add(pos, dir)
|
||||
local n2 = minetest.get_node_or_nil(p)
|
||||
local def = n2 and minetest.registered_items[n2.name]
|
||||
if not def or not def.buildable_to then
|
||||
minetest.remove_node(pos)
|
||||
return true
|
||||
|
||||
local pos
|
||||
if udef and udef.buildable_to then
|
||||
pos = under
|
||||
else
|
||||
pos = pointed_thing.above
|
||||
end
|
||||
minetest.set_node(p, {name = n.name:gsub("%_bottom", "_top"), param2 = n.param2})
|
||||
return false
|
||||
|
||||
local player_name = placer and placer:get_player_name() or ""
|
||||
|
||||
if minetest.is_protected(pos, player_name) and
|
||||
not minetest.check_player_privs(player_name, "protection_bypass") then
|
||||
minetest.record_protection_violation(pos, player_name)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local node_def = minetest.registered_nodes[minetest.get_node(pos).name]
|
||||
if not node_def or not node_def.buildable_to then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local dir = placer and placer:get_look_dir() and
|
||||
minetest.dir_to_facedir(placer:get_look_dir()) or 0
|
||||
local botpos = vector.add(pos, minetest.facedir_to_dir(dir))
|
||||
|
||||
if minetest.is_protected(botpos, player_name) and
|
||||
not minetest.check_player_privs(player_name, "protection_bypass") then
|
||||
minetest.record_protection_violation(botpos, player_name)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local botdef = minetest.registered_nodes[minetest.get_node(botpos).name]
|
||||
if not botdef or not botdef.buildable_to then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
minetest.set_node(pos, {name = name .. "_bottom", param2 = dir})
|
||||
minetest.set_node(botpos, {name = name .. "_top", param2 = dir})
|
||||
|
||||
if not (creative and creative.is_enabled_for
|
||||
and creative.is_enabled_for(player_name)) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
local n = minetest.get_node_or_nil(pos)
|
||||
if not n then return end
|
||||
local dir = minetest.facedir_to_dir(n.param2)
|
||||
local p = vector.add(pos, dir)
|
||||
local n2 = minetest.get_node(p)
|
||||
if minetest.get_item_group(n2.name, "bed") == 2 and n.param2 == n2.param2 then
|
||||
minetest.remove_node(p)
|
||||
end
|
||||
destruct_bed(pos, 1)
|
||||
end,
|
||||
on_rightclick = function(pos, node, clicker)
|
||||
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
beds.on_rightclick(pos, clicker)
|
||||
return itemstack
|
||||
end,
|
||||
on_rotate = function(pos, node, user, mode, new_param2)
|
||||
|
||||
on_rotate = function(pos, node, user, _, new_param2)
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
local p = vector.add(pos, dir)
|
||||
local node2 = minetest.get_node_or_nil(p)
|
||||
@ -62,13 +121,13 @@ function beds.register_bed(name, def)
|
||||
minetest.record_protection_violation(p, user:get_player_name())
|
||||
return false
|
||||
end
|
||||
if mode ~= screwdriver.ROTATE_FACE then
|
||||
if new_param2 % 32 > 3 then
|
||||
return false
|
||||
end
|
||||
local newp = vector.add(pos, minetest.facedir_to_dir(new_param2))
|
||||
local node3 = minetest.get_node_or_nil(newp)
|
||||
local def = node3 and minetest.registered_nodes[node3.name]
|
||||
if not def or not def.buildable_to then
|
||||
local node_def = node3 and minetest.registered_nodes[node3.name]
|
||||
if not node_def or not node_def.buildable_to then
|
||||
return false
|
||||
end
|
||||
if minetest.is_protected(newp, user:get_player_name()) then
|
||||
@ -76,11 +135,15 @@ function beds.register_bed(name, def)
|
||||
return false
|
||||
end
|
||||
node.param2 = new_param2
|
||||
minetest.swap_node(pos, node)
|
||||
minetest.remove_node(p)
|
||||
minetest.set_node(newp, {name = node.name:gsub("%_bottom", "_top"), param2 = new_param2})
|
||||
-- do not remove_node here - it will trigger destroy_bed()
|
||||
minetest.set_node(p, {name = "air"})
|
||||
minetest.set_node(pos, node)
|
||||
minetest.set_node(newp, {name = name .. "_top", param2 = new_param2})
|
||||
return true
|
||||
end,
|
||||
can_dig = function(pos, player)
|
||||
return beds.can_dig(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node(name .. "_top", {
|
||||
@ -89,21 +152,27 @@ function beds.register_bed(name, def)
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
pointable = false,
|
||||
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2},
|
||||
sounds = def.sounds or default.node_sound_wood_defaults(),
|
||||
drop = name .. "_bottom",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = def.nodebox.top,
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
on_destruct = function(pos)
|
||||
destruct_bed(pos, 2)
|
||||
end,
|
||||
can_dig = function(pos, player)
|
||||
local node = minetest.get_node(pos)
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
local p = vector.add(pos, dir)
|
||||
return beds.can_dig(p)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_alias(name, name .. "_bottom")
|
||||
|
||||
-- register recipe
|
||||
minetest.register_craft({
|
||||
output = name,
|
||||
recipe = def.recipe
|
||||
|
@ -1,88 +1,104 @@
|
||||
-- fancy shaped bed
|
||||
-- Fancy shaped bed
|
||||
|
||||
beds.register_bed("beds:fancy_bed", {
|
||||
description = "Fancy Bed",
|
||||
inventory_image = "beds_bed_fancy.png",
|
||||
wield_image = "beds_bed_fancy.png",
|
||||
tiles = {
|
||||
bottom = {
|
||||
"beds_bed_top1.png",
|
||||
"default_wood.png",
|
||||
"beds_bed_side1.png",
|
||||
"beds_bed_side1.png^[transformFX",
|
||||
"default_wood.png",
|
||||
"beds_bed_foot.png",
|
||||
},
|
||||
top = {
|
||||
"beds_bed_top2.png",
|
||||
"default_wood.png",
|
||||
"beds_bed_side2.png",
|
||||
"beds_bed_side2.png^[transformFX",
|
||||
"beds_bed_head.png",
|
||||
"default_wood.png",
|
||||
}
|
||||
bottom = {
|
||||
"beds_bed_top1.png",
|
||||
"beds_bed_under.png",
|
||||
"beds_bed_side1.png",
|
||||
"beds_bed_side1.png^[transformFX",
|
||||
"beds_bed_foot.png",
|
||||
"beds_bed_foot.png",
|
||||
},
|
||||
top = {
|
||||
"beds_bed_top2.png",
|
||||
"beds_bed_under.png",
|
||||
"beds_bed_side2.png",
|
||||
"beds_bed_side2.png^[transformFX",
|
||||
"beds_bed_head.png",
|
||||
"beds_bed_head.png",
|
||||
}
|
||||
},
|
||||
nodebox = {
|
||||
bottom = {
|
||||
{-0.5, -0.5, -0.5, -0.375, -0.065, -0.4375},
|
||||
{0.375, -0.5, -0.5, 0.5, -0.065, -0.4375},
|
||||
{-0.5, -0.375, -0.5, 0.5, -0.125, -0.4375},
|
||||
{-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5},
|
||||
{0.4375, -0.375, -0.5, 0.5, -0.125, 0.5},
|
||||
{-0.4375, -0.3125, -0.4375, 0.4375, -0.0625, 0.5},
|
||||
},
|
||||
top = {
|
||||
{-0.5, -0.5, 0.4375, -0.375, 0.1875, 0.5},
|
||||
{0.375, -0.5, 0.4375, 0.5, 0.1875, 0.5},
|
||||
{-0.5, 0, 0.4375, 0.5, 0.125, 0.5},
|
||||
{-0.5, -0.375, 0.4375, 0.5, -0.125, 0.5},
|
||||
{-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5},
|
||||
{0.4375, -0.375, -0.5, 0.5, -0.125, 0.5},
|
||||
{-0.4375, -0.3125, -0.5, 0.4375, -0.0625, 0.4375},
|
||||
}
|
||||
bottom = {
|
||||
{-0.5, -0.5, -0.5, -0.375, -0.065, -0.4375},
|
||||
{0.375, -0.5, -0.5, 0.5, -0.065, -0.4375},
|
||||
{-0.5, -0.375, -0.5, 0.5, -0.125, -0.4375},
|
||||
{-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5},
|
||||
{0.4375, -0.375, -0.5, 0.5, -0.125, 0.5},
|
||||
{-0.4375, -0.3125, -0.4375, 0.4375, -0.0625, 0.5},
|
||||
},
|
||||
top = {
|
||||
{-0.5, -0.5, 0.4375, -0.375, 0.1875, 0.5},
|
||||
{0.375, -0.5, 0.4375, 0.5, 0.1875, 0.5},
|
||||
{-0.5, 0, 0.4375, 0.5, 0.125, 0.5},
|
||||
{-0.5, -0.375, 0.4375, 0.5, -0.125, 0.5},
|
||||
{-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5},
|
||||
{0.4375, -0.375, -0.5, 0.5, -0.125, 0.5},
|
||||
{-0.4375, -0.3125, -0.5, 0.4375, -0.0625, 0.4375},
|
||||
}
|
||||
},
|
||||
selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.06, 1.5},
|
||||
recipe = {
|
||||
{"", "", "group:stick"},
|
||||
{"wool:red", "wool:red", "wool:white"},
|
||||
{"wool:white", "wool:white", "wool:white"},
|
||||
{"group:wood", "group:wood", "group:wood"},
|
||||
},
|
||||
})
|
||||
|
||||
-- simple shaped bed
|
||||
-- Simple shaped bed
|
||||
|
||||
beds.register_bed("beds:bed", {
|
||||
description = "Simple Bed",
|
||||
inventory_image = "beds_bed.png",
|
||||
wield_image = "beds_bed.png",
|
||||
tiles = {
|
||||
bottom = {
|
||||
"beds_bed_top_bottom.png^[transformR90",
|
||||
"default_wood.png",
|
||||
"beds_bed_side_bottom_r.png",
|
||||
"beds_bed_side_bottom_r.png^[transformfx",
|
||||
"beds_transparent.png",
|
||||
"beds_bed_side_bottom.png"
|
||||
},
|
||||
top = {
|
||||
"beds_bed_top_top.png^[transformR90",
|
||||
"default_wood.png",
|
||||
"beds_bed_side_top_r.png",
|
||||
"beds_bed_side_top_r.png^[transformfx",
|
||||
"beds_bed_side_top.png",
|
||||
"beds_transparent.png",
|
||||
}
|
||||
bottom = {
|
||||
"beds_bed_top_bottom.png^[transformR90",
|
||||
"beds_bed_under.png",
|
||||
"beds_bed_side_bottom_r.png",
|
||||
"beds_bed_side_bottom_r.png^[transformfx",
|
||||
"beds_transparent.png",
|
||||
"beds_bed_side_bottom.png"
|
||||
},
|
||||
top = {
|
||||
"beds_bed_top_top.png^[transformR90",
|
||||
"beds_bed_under.png",
|
||||
"beds_bed_side_top_r.png",
|
||||
"beds_bed_side_top_r.png^[transformfx",
|
||||
"beds_bed_side_top.png",
|
||||
"beds_transparent.png",
|
||||
}
|
||||
},
|
||||
nodebox = {
|
||||
bottom = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5},
|
||||
top = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5},
|
||||
bottom = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5},
|
||||
top = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5},
|
||||
},
|
||||
selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.06, 1.5},
|
||||
recipe = {
|
||||
{"wool:red", "wool:red", "wool:white"},
|
||||
{"wool:white", "wool:white", "wool:white"},
|
||||
{"group:wood", "group:wood", "group:wood"}
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
-- aliases for PA's beds mod
|
||||
-- Aliases for PilzAdam's beds mod
|
||||
|
||||
minetest.register_alias("beds:bed_bottom_red", "beds:bed_bottom")
|
||||
minetest.register_alias("beds:bed_top_red", "beds:bed_top")
|
||||
|
||||
-- Fuel
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "beds:fancy_bed_bottom",
|
||||
burntime = 13,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "beds:bed_bottom",
|
||||
burntime = 12,
|
||||
})
|
||||
|
@ -1,24 +1,35 @@
|
||||
local pi = math.pi
|
||||
local player_in_bed = 0
|
||||
local is_sp = minetest.is_singleplayer()
|
||||
local enable_respawn = minetest.setting_getbool("enable_bed_respawn")
|
||||
local enable_respawn = minetest.settings:get_bool("enable_bed_respawn")
|
||||
if enable_respawn == nil then
|
||||
enable_respawn = true
|
||||
end
|
||||
|
||||
|
||||
-- helper functions
|
||||
-- Helper functions
|
||||
|
||||
local function get_look_yaw(pos)
|
||||
local n = minetest.get_node(pos)
|
||||
if n.param2 == 1 then
|
||||
return 7.9, n.param2
|
||||
elseif n.param2 == 3 then
|
||||
return 4.75, n.param2
|
||||
elseif n.param2 == 0 then
|
||||
return 3.15, n.param2
|
||||
else
|
||||
return 6.28, n.param2
|
||||
local rotation = minetest.get_node(pos).param2
|
||||
if rotation > 3 then
|
||||
rotation = rotation % 4 -- Mask colorfacedir values
|
||||
end
|
||||
if rotation == 1 then
|
||||
return pi / 2, rotation
|
||||
elseif rotation == 3 then
|
||||
return -pi / 2, rotation
|
||||
elseif rotation == 0 then
|
||||
return pi, rotation
|
||||
else
|
||||
return 0, rotation
|
||||
end
|
||||
end
|
||||
|
||||
local function is_night_skip_enabled()
|
||||
local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip")
|
||||
if enable_night_skip == nil then
|
||||
enable_night_skip = true
|
||||
end
|
||||
return enable_night_skip
|
||||
end
|
||||
|
||||
local function check_in_beds(players)
|
||||
@ -50,6 +61,7 @@ local function lay_down(player, pos, bed_pos, state, skip)
|
||||
local p = beds.pos[name] or nil
|
||||
if beds.player[name] ~= nil then
|
||||
beds.player[name] = nil
|
||||
beds.bed_position[name] = nil
|
||||
player_in_bed = player_in_bed - 1
|
||||
end
|
||||
-- skip here to prevent sending player specific changes (used for leaving players)
|
||||
@ -57,12 +69,12 @@ local function lay_down(player, pos, bed_pos, state, skip)
|
||||
return
|
||||
end
|
||||
if p then
|
||||
player:setpos(p)
|
||||
player:set_pos(p)
|
||||
end
|
||||
|
||||
-- physics, eye_offset, etc
|
||||
player:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
|
||||
player:set_look_yaw(math.random(1, 180)/100)
|
||||
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
player:set_look_horizontal(math.random(1, 180) / 100)
|
||||
default.player_attached[name] = false
|
||||
player:set_physics_override(1, 1, 1)
|
||||
hud_flags.wielditem = true
|
||||
@ -72,16 +84,17 @@ local function lay_down(player, pos, bed_pos, state, skip)
|
||||
else
|
||||
beds.player[name] = 1
|
||||
beds.pos[name] = pos
|
||||
beds.bed_position[name] = bed_pos
|
||||
player_in_bed = player_in_bed + 1
|
||||
|
||||
-- physics, eye_offset, etc
|
||||
player:set_eye_offset({x=0,y=-13,z=0}, {x=0,y=0,z=0})
|
||||
player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0})
|
||||
local yaw, param2 = get_look_yaw(bed_pos)
|
||||
player:set_look_yaw(yaw)
|
||||
player:set_look_horizontal(yaw)
|
||||
local dir = minetest.facedir_to_dir(param2)
|
||||
local p = {x=bed_pos.x+dir.x/2,y=bed_pos.y,z=bed_pos.z+dir.z/2}
|
||||
local p = {x = bed_pos.x + dir.x / 2, y = bed_pos.y, z = bed_pos.z + dir.z / 2}
|
||||
player:set_physics_override(0, 0, 0)
|
||||
player:setpos(p)
|
||||
player:set_pos(p)
|
||||
default.player_attached[name] = true
|
||||
hud_flags.wielditem = false
|
||||
default.player_set_animation(player, "lay" , 0)
|
||||
@ -92,18 +105,16 @@ end
|
||||
|
||||
local function update_formspecs(finished)
|
||||
local ges = #minetest.get_connected_players()
|
||||
local form_n = ""
|
||||
local is_majority = (ges/2) < player_in_bed
|
||||
local form_n
|
||||
local is_majority = (ges / 2) < player_in_bed
|
||||
|
||||
if finished then
|
||||
form_n = beds.formspec ..
|
||||
"label[2.7,11; Good morning.]"
|
||||
form_n = beds.formspec .. "label[2.7,9; Good morning.]"
|
||||
else
|
||||
form_n = beds.formspec ..
|
||||
"label[2.2,11;"..tostring(player_in_bed).." of "..tostring(ges).." players are in bed]"
|
||||
if is_majority then
|
||||
form_n = form_n ..
|
||||
"button_exit[2,8;4,0.75;force;Force night skip]"
|
||||
form_n = beds.formspec .. "label[2.2,9;" .. tostring(player_in_bed) ..
|
||||
" of " .. tostring(ges) .. " players are in bed]"
|
||||
if is_majority and is_night_skip_enabled() then
|
||||
form_n = form_n .. "button_exit[2,6;4,0.75;force;Force night skip]"
|
||||
end
|
||||
end
|
||||
|
||||
@ -113,10 +124,10 @@ local function update_formspecs(finished)
|
||||
end
|
||||
|
||||
|
||||
-- public functions
|
||||
-- Public functions
|
||||
|
||||
function beds.kick_players()
|
||||
for name,_ in pairs(beds.player) do
|
||||
for name, _ in pairs(beds.player) do
|
||||
local player = minetest.get_player_by_name(name)
|
||||
lay_down(player, nil, nil, false)
|
||||
end
|
||||
@ -124,12 +135,11 @@ end
|
||||
|
||||
function beds.skip_night()
|
||||
minetest.set_timeofday(0.23)
|
||||
beds.set_spawns()
|
||||
end
|
||||
|
||||
function beds.on_rightclick(pos, player)
|
||||
local name = player:get_player_name()
|
||||
local ppos = player:getpos()
|
||||
local ppos = player:get_pos()
|
||||
local tod = minetest.get_timeofday()
|
||||
|
||||
if tod > 0.2 and tod < 0.805 then
|
||||
@ -143,6 +153,7 @@ function beds.on_rightclick(pos, player)
|
||||
-- move to bed
|
||||
if not beds.player[name] then
|
||||
lay_down(player, ppos, pos)
|
||||
beds.set_spawns() -- save respawn positions when entering bed
|
||||
else
|
||||
lay_down(player, nil, nil, false)
|
||||
end
|
||||
@ -154,34 +165,40 @@ function beds.on_rightclick(pos, player)
|
||||
-- skip the night and let all players stand up
|
||||
if check_in_beds() then
|
||||
minetest.after(2, function()
|
||||
beds.skip_night()
|
||||
if not is_sp then
|
||||
update_formspecs(true)
|
||||
update_formspecs(is_night_skip_enabled())
|
||||
end
|
||||
if is_night_skip_enabled() then
|
||||
beds.skip_night()
|
||||
beds.kick_players()
|
||||
end
|
||||
beds.kick_players()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- callbacks
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
beds.read_spawns()
|
||||
end)
|
||||
|
||||
-- respawn player at bed if enabled and valid position is found
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
if not enable_respawn then
|
||||
return false
|
||||
function beds.can_dig(bed_pos)
|
||||
-- Check all players in bed which one is at the expected position
|
||||
for _, player_bed_pos in pairs(beds.bed_position) do
|
||||
if vector.equals(bed_pos, player_bed_pos) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
local name = player:get_player_name()
|
||||
local pos = beds.spawn[name] or nil
|
||||
if pos then
|
||||
player:setpos(pos)
|
||||
return true
|
||||
end
|
||||
end)
|
||||
return true
|
||||
end
|
||||
|
||||
-- Callbacks
|
||||
-- Only register respawn callback if respawn enabled
|
||||
if enable_respawn then
|
||||
-- respawn player at bed if enabled and valid position is found
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
local pos = beds.spawn[name]
|
||||
if pos then
|
||||
player:set_pos(pos)
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
@ -189,9 +206,11 @@ minetest.register_on_leaveplayer(function(player)
|
||||
beds.player[name] = nil
|
||||
if check_in_beds() then
|
||||
minetest.after(2, function()
|
||||
beds.skip_night()
|
||||
update_formspecs(true)
|
||||
beds.kick_players()
|
||||
update_formspecs(is_night_skip_enabled())
|
||||
if is_night_skip_enabled() then
|
||||
beds.skip_night()
|
||||
beds.kick_players()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
@ -200,14 +219,25 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "beds_form" then
|
||||
return
|
||||
end
|
||||
|
||||
-- Because "Force night skip" button is a button_exit, it will set fields.quit
|
||||
-- and lay_down call will change value of player_in_bed, so it must be taken
|
||||
-- earlier.
|
||||
local last_player_in_bed = player_in_bed
|
||||
|
||||
if fields.quit or fields.leave then
|
||||
lay_down(player, nil, nil, false)
|
||||
update_formspecs(false)
|
||||
end
|
||||
|
||||
if fields.force then
|
||||
beds.skip_night()
|
||||
update_formspecs(true)
|
||||
beds.kick_players()
|
||||
local is_majority = (#minetest.get_connected_players() / 2) < last_player_in_bed
|
||||
if is_majority and is_night_skip_enabled() then
|
||||
update_formspecs(true)
|
||||
beds.skip_night()
|
||||
beds.kick_players()
|
||||
else
|
||||
update_formspecs(false)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
@ -1,16 +1,19 @@
|
||||
beds = {}
|
||||
beds.player = {}
|
||||
beds.bed_position = {}
|
||||
beds.pos = {}
|
||||
beds.spawn = {}
|
||||
|
||||
beds.formspec = "size[8,15;true]"..
|
||||
"bgcolor[#080808BB; true]"..
|
||||
"button_exit[2,12;4,0.75;leave;Leave Bed]"
|
||||
beds.formspec = "size[8,11;true]" ..
|
||||
"no_prepend[]" ..
|
||||
"bgcolor[#080808BB;true]" ..
|
||||
"button_exit[2,10;4,0.75;leave;Leave Bed]"
|
||||
|
||||
local modpath = minetest.get_modpath("beds")
|
||||
|
||||
-- load files
|
||||
dofile(modpath.."/functions.lua")
|
||||
dofile(modpath.."/api.lua")
|
||||
dofile(modpath.."/beds.lua")
|
||||
dofile(modpath.."/spawns.lua")
|
||||
-- Load files
|
||||
|
||||
dofile(modpath .. "/functions.lua")
|
||||
dofile(modpath .. "/api.lua")
|
||||
dofile(modpath .. "/beds.lua")
|
||||
dofile(modpath .. "/spawns.lua")
|
||||
|
61
mods/beds/license.txt
Normal file
@ -0,0 +1,61 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (C) 2014-2016 BlockMen
|
||||
Copyright (C) 2014-2016 Various Minetest developers and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
Licenses of media (textures)
|
||||
----------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2014-2016 BlockMen
|
||||
Copyright (C) 2018 TumeniNodes
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
@ -18,8 +18,8 @@ function beds.read_spawns()
|
||||
repeat
|
||||
local x = input:read("*n")
|
||||
if x == nil then
|
||||
break
|
||||
end
|
||||
break
|
||||
end
|
||||
local y = input:read("*n")
|
||||
local z = input:read("*n")
|
||||
local name = input:read("*l")
|
||||
@ -32,27 +32,32 @@ function beds.read_spawns()
|
||||
beds.save_spawns()
|
||||
os.rename(file, file .. ".backup")
|
||||
file = org_file
|
||||
else
|
||||
spawns = {}
|
||||
end
|
||||
end
|
||||
|
||||
beds.read_spawns()
|
||||
|
||||
function beds.save_spawns()
|
||||
if not beds.spawn then
|
||||
return
|
||||
end
|
||||
local data = {}
|
||||
local output = io.open(org_file, "w")
|
||||
for i, v in pairs(beds.spawn) do
|
||||
output:write(v.x.." "..v.y.." "..v.z.." "..i.."\n")
|
||||
for k, v in pairs(beds.spawn) do
|
||||
table.insert(data, string.format("%.1f %.1f %.1f %s\n", v.x, v.y, v.z, k))
|
||||
end
|
||||
output:write(table.concat(data))
|
||||
io.close(output)
|
||||
end
|
||||
|
||||
function beds.set_spawns()
|
||||
for name,_ in pairs(beds.player) do
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local p = player:getpos()
|
||||
beds.spawn[name] = p
|
||||
local p = player:get_pos()
|
||||
-- but don't change spawn location if borrowing a bed
|
||||
if not minetest.is_protected(p, name) then
|
||||
beds.spawn[name] = p
|
||||
end
|
||||
end
|
||||
beds.save_spawns()
|
||||
end
|
||||
|
BIN
mods/beds/textures/beds_bed_under.png
Normal file
After Width: | Height: | Size: 304 B |
37
mods/binoculars/README.txt
Normal file
@ -0,0 +1,37 @@
|
||||
Minetest Game mod: binoculars
|
||||
=============================
|
||||
See license.txt for license information.
|
||||
|
||||
Authors of source code
|
||||
----------------------
|
||||
paramat (MIT)
|
||||
|
||||
Authors of media (textures)
|
||||
---------------------------
|
||||
paramat (CC BY-SA 3.0):
|
||||
binoculars_binoculars.png
|
||||
|
||||
Crafting
|
||||
--------
|
||||
binoculars:binoculars
|
||||
|
||||
default:obsidian_glass O
|
||||
default:bronze_ingot B
|
||||
|
||||
O_O
|
||||
BBB
|
||||
O_O
|
||||
|
||||
Usage
|
||||
-----
|
||||
In survival mode, use of zoom requires the binoculars item in your inventory,
|
||||
they will allow a 10 degree field of view.
|
||||
It can take up to 5 seconds for adding to or removal from inventory to have an
|
||||
effect, however to instantly allow the use of this zoom 'use' (leftclick) the
|
||||
item.
|
||||
|
||||
Zoom with a field of view of 15 degrees is automatically allowed in creative
|
||||
mode and for any player with the 'creative' privilege.
|
||||
|
||||
The 'binoculars.update_player_property()' function is global so can be
|
||||
redefined by a mod for alternative behaviour.
|
2
mods/binoculars/depends.txt
Normal file
@ -0,0 +1,2 @@
|
||||
default
|
||||
creative?
|
76
mods/binoculars/init.lua
Normal file
@ -0,0 +1,76 @@
|
||||
-- Mod global namespace
|
||||
|
||||
binoculars = {}
|
||||
|
||||
|
||||
-- Detect creative mod
|
||||
local creative_mod = minetest.get_modpath("creative")
|
||||
-- Cache creative mode setting as fallback if creative mod not present
|
||||
local creative_mode_cache = minetest.settings:get_bool("creative_mode")
|
||||
|
||||
|
||||
-- Update player property
|
||||
-- Global to allow overriding
|
||||
|
||||
function binoculars.update_player_property(player)
|
||||
local creative_enabled =
|
||||
(creative_mod and creative.is_enabled_for(player:get_player_name())) or
|
||||
creative_mode_cache
|
||||
local new_zoom_fov = 0
|
||||
|
||||
if player:get_inventory():contains_item(
|
||||
"main", "binoculars:binoculars") then
|
||||
new_zoom_fov = 10
|
||||
elseif creative_enabled then
|
||||
new_zoom_fov = 15
|
||||
end
|
||||
|
||||
-- Only set property if necessary to avoid player mesh reload
|
||||
if player:get_properties().zoom_fov ~= new_zoom_fov then
|
||||
player:set_properties({zoom_fov = new_zoom_fov})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Set player property 'on joinplayer'
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
binoculars.update_player_property(player)
|
||||
end)
|
||||
|
||||
|
||||
-- Cyclic update of player property
|
||||
|
||||
local function cyclic_update()
|
||||
for _, player in ipairs(minetest.get_connected_players()) do
|
||||
binoculars.update_player_property(player)
|
||||
end
|
||||
minetest.after(4.7, cyclic_update)
|
||||
end
|
||||
|
||||
minetest.after(4.7, cyclic_update)
|
||||
|
||||
|
||||
-- Binoculars item
|
||||
|
||||
minetest.register_craftitem("binoculars:binoculars", {
|
||||
description = "Binoculars\nUse with 'Zoom' key",
|
||||
inventory_image = "binoculars_binoculars.png",
|
||||
stack_max = 1,
|
||||
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
binoculars.update_player_property(user)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
-- Crafting
|
||||
|
||||
minetest.register_craft({
|
||||
output = "binoculars:binoculars",
|
||||
recipe = {
|
||||
{"default:obsidian_glass", "", "default:obsidian_glass"},
|
||||
{"default:bronze_ingot", "default:bronze_ingot", "default:bronze_ingot"},
|
||||
{"default:obsidian_glass", "", "default:obsidian_glass"},
|
||||
}
|
||||
})
|
59
mods/binoculars/license.txt
Normal file
@ -0,0 +1,59 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (C) 2017 paramat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
Licenses of media (textures)
|
||||
----------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2017 paramat
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
BIN
mods/binoculars/textures/binoculars_binoculars.png
Normal file
After Width: | Height: | Size: 219 B |
@ -1,16 +1,31 @@
|
||||
Minetest 0.4 mod: boats
|
||||
=======================
|
||||
by PilzAdam, slightly modified for NeXt
|
||||
Minetest Game mod: boats
|
||||
========================
|
||||
See license.txt for license information.
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
WTFPL
|
||||
Authors of source code
|
||||
----------------------
|
||||
Originally by PilzAdam (MIT)
|
||||
Various Minetest developers and contributors (MIT)
|
||||
|
||||
License of media (textures and sounds):
|
||||
---------------------------------------
|
||||
WTFPL
|
||||
Authors of media (textures and model)
|
||||
-------------------------------------
|
||||
Textures: Zeg9 (CC BY-SA 3.0)
|
||||
Model: thetoon and Zeg9 (CC BY-SA 3.0),
|
||||
modified by PavelS(SokolovPavel) (CC BY-SA 3.0),
|
||||
modified by sofar (CC BY-SA 3.0)
|
||||
|
||||
Authors of media files:
|
||||
-----------------------
|
||||
textures: Zeg9
|
||||
model: thetoon and Zeg9, modified by PavelS(SokolovPavel)
|
||||
Controls
|
||||
--------
|
||||
Right mouse button = Enter or exit boat when pointing at boat.
|
||||
Forward = Speed up.
|
||||
Slow down when moving backwards.
|
||||
Forward + backward = Enable cruise mode: Boat will accelerate to maximum forward
|
||||
speed and remain at that speed without needing to hold the
|
||||
forward key.
|
||||
Backward = Slow down.
|
||||
Speed up when moving backwards.
|
||||
Disable cruise mode.
|
||||
Left = Turn to the left.
|
||||
Turn to the right when moving backwards.
|
||||
Right = Turn to the right.
|
||||
Turn to the left when moving backwards.
|
||||
|
@ -1 +1,2 @@
|
||||
default
|
||||
player_api
|
||||
|
@ -33,16 +33,21 @@ end
|
||||
--
|
||||
|
||||
local boat = {
|
||||
physical = true,
|
||||
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
|
||||
visual = "mesh",
|
||||
mesh = "boat.obj",
|
||||
textures = {"default_wood.png"},
|
||||
initial_properties = {
|
||||
physical = true,
|
||||
-- Warning: Do not change the position of the collisionbox top surface,
|
||||
-- lowering it causes the boat to fall through the world if underwater
|
||||
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
|
||||
visual = "mesh",
|
||||
mesh = "boats_boat.obj",
|
||||
textures = {"default_wood.png"},
|
||||
},
|
||||
|
||||
driver = nil,
|
||||
v = 0,
|
||||
last_v = 0,
|
||||
removed = false
|
||||
removed = false,
|
||||
auto = false
|
||||
}
|
||||
|
||||
|
||||
@ -51,29 +56,45 @@ function boat.on_rightclick(self, clicker)
|
||||
return
|
||||
end
|
||||
local name = clicker:get_player_name()
|
||||
if self.driver and clicker == self.driver then
|
||||
if self.driver and name == self.driver then
|
||||
self.driver = nil
|
||||
self.auto = false
|
||||
clicker:set_detach()
|
||||
default.player_attached[name] = false
|
||||
default.player_set_animation(clicker, "stand" , 30)
|
||||
local pos = clicker:getpos()
|
||||
player_api.player_attached[name] = false
|
||||
player_api.set_animation(clicker, "stand" , 30)
|
||||
local pos = clicker:get_pos()
|
||||
pos = {x = pos.x, y = pos.y + 0.2, z = pos.z}
|
||||
minetest.after(0.1, function()
|
||||
clicker:setpos(pos)
|
||||
clicker:set_pos(pos)
|
||||
end)
|
||||
elseif not self.driver then
|
||||
self.driver = clicker
|
||||
local attach = clicker:get_attach()
|
||||
if attach and attach:get_luaentity() then
|
||||
local luaentity = attach:get_luaentity()
|
||||
if luaentity.driver then
|
||||
luaentity.driver = nil
|
||||
end
|
||||
clicker:set_detach()
|
||||
end
|
||||
self.driver = name
|
||||
clicker:set_attach(self.object, "",
|
||||
{x = 0, y = 11, z = -3}, {x = 0, y = 0, z = 0})
|
||||
default.player_attached[name] = true
|
||||
{x = 0.5, y = 1, z = -3}, {x = 0, y = 0, z = 0})
|
||||
player_api.player_attached[name] = true
|
||||
minetest.after(0.2, function()
|
||||
default.player_set_animation(clicker, "sit" , 30)
|
||||
player_api.set_animation(clicker, "sit" , 30)
|
||||
end)
|
||||
self.object:setyaw(clicker:get_look_yaw() - math.pi / 2)
|
||||
clicker:set_look_horizontal(self.object:get_yaw())
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- If driver leaves server while driving boat
|
||||
function boat.on_detach_child(self, child)
|
||||
self.driver = nil
|
||||
self.auto = false
|
||||
end
|
||||
|
||||
|
||||
function boat.on_activate(self, staticdata, dtime_s)
|
||||
self.object:set_armor_groups({immortal = 1})
|
||||
if staticdata then
|
||||
@ -88,72 +109,91 @@ function boat.get_staticdata(self)
|
||||
end
|
||||
|
||||
|
||||
function boat.on_punch(self, puncher, time_from_last_punch,
|
||||
tool_capabilities, direction)
|
||||
function boat.on_punch(self, puncher)
|
||||
if not puncher or not puncher:is_player() or self.removed then
|
||||
return
|
||||
end
|
||||
if self.driver and puncher == self.driver then
|
||||
|
||||
local name = puncher:get_player_name()
|
||||
if self.driver and name == self.driver then
|
||||
self.driver = nil
|
||||
puncher:set_detach()
|
||||
default.player_attached[puncher:get_player_name()] = false
|
||||
player_api.player_attached[name] = false
|
||||
end
|
||||
if not self.driver then
|
||||
self.removed = true
|
||||
local inv = puncher:get_inventory()
|
||||
if not (creative and creative.is_enabled_for
|
||||
and creative.is_enabled_for(name))
|
||||
or not inv:contains_item("main", "boats:boat") then
|
||||
local leftover = inv:add_item("main", "boats:boat")
|
||||
-- if no room in inventory add a replacement boat to the world
|
||||
if not leftover:is_empty() then
|
||||
minetest.add_item(self.object:get_pos(), leftover)
|
||||
end
|
||||
end
|
||||
-- delay remove to ensure player is detached
|
||||
minetest.after(0.1, function()
|
||||
self.object:remove()
|
||||
end)
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
puncher:get_inventory():add_item("main", "boats:boat")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function boat.on_step(self, dtime)
|
||||
self.v = get_v(self.object:getvelocity()) * get_sign(self.v)
|
||||
self.v = get_v(self.object:get_velocity()) * get_sign(self.v)
|
||||
if self.driver then
|
||||
local ctrl = self.driver:get_player_control()
|
||||
local yaw = self.object:getyaw()
|
||||
if ctrl.up then
|
||||
self.v = self.v + 0.1
|
||||
elseif ctrl.down then
|
||||
self.v = self.v - 0.1
|
||||
end
|
||||
if ctrl.left then
|
||||
if self.v < 0 then
|
||||
self.object:setyaw(yaw - (1 + dtime) * 0.03)
|
||||
else
|
||||
self.object:setyaw(yaw + (1 + dtime) * 0.03)
|
||||
local driver_objref = minetest.get_player_by_name(self.driver)
|
||||
if driver_objref then
|
||||
local ctrl = driver_objref:get_player_control()
|
||||
if ctrl.up and ctrl.down then
|
||||
if not self.auto then
|
||||
self.auto = true
|
||||
minetest.chat_send_player(self.driver, "[boats] Cruise on")
|
||||
end
|
||||
elseif ctrl.down then
|
||||
self.v = self.v - dtime * 1.8
|
||||
if self.auto then
|
||||
self.auto = false
|
||||
minetest.chat_send_player(self.driver, "[boats] Cruise off")
|
||||
end
|
||||
elseif ctrl.up or self.auto then
|
||||
self.v = self.v + dtime * 1.8
|
||||
end
|
||||
elseif ctrl.right then
|
||||
if self.v < 0 then
|
||||
self.object:setyaw(yaw + (1 + dtime) * 0.03)
|
||||
else
|
||||
self.object:setyaw(yaw - (1 + dtime) * 0.03)
|
||||
if ctrl.left then
|
||||
if self.v < -0.001 then
|
||||
self.object:set_yaw(self.object:get_yaw() - dtime * 0.9)
|
||||
else
|
||||
self.object:set_yaw(self.object:get_yaw() + dtime * 0.9)
|
||||
end
|
||||
elseif ctrl.right then
|
||||
if self.v < -0.001 then
|
||||
self.object:set_yaw(self.object:get_yaw() + dtime * 0.9)
|
||||
else
|
||||
self.object:set_yaw(self.object:get_yaw() - dtime * 0.9)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local velo = self.object:getvelocity()
|
||||
local velo = self.object:get_velocity()
|
||||
if self.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
self.object:setpos(self.object:getpos())
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
return
|
||||
end
|
||||
local s = get_sign(self.v)
|
||||
self.v = self.v - 0.02 * s
|
||||
self.v = self.v - dtime * 0.6 * s
|
||||
if s ~= get_sign(self.v) then
|
||||
self.object:setvelocity({x = 0, y = 0, z = 0})
|
||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
||||
self.v = 0
|
||||
return
|
||||
end
|
||||
if math.abs(self.v) > 4.5 then
|
||||
self.v = 4.5 * get_sign(self.v)
|
||||
if math.abs(self.v) > 5 then
|
||||
self.v = 5 * get_sign(self.v)
|
||||
end
|
||||
|
||||
local p = self.object:getpos()
|
||||
local p = self.object:get_pos()
|
||||
p.y = p.y - 0.5
|
||||
local new_velo = {x = 0, y = 0, z = 0}
|
||||
local new_velo
|
||||
local new_acce = {x = 0, y = 0, z = 0}
|
||||
if not is_water(p) then
|
||||
local nodedef = minetest.registered_nodes[minetest.get_node(p).name]
|
||||
@ -163,38 +203,38 @@ function boat.on_step(self, dtime)
|
||||
else
|
||||
new_acce = {x = 0, y = -9.8, z = 0}
|
||||
end
|
||||
new_velo = get_velocity(self.v, self.object:getyaw(),
|
||||
self.object:getvelocity().y)
|
||||
self.object:setpos(self.object:getpos())
|
||||
new_velo = get_velocity(self.v, self.object:get_yaw(),
|
||||
self.object:get_velocity().y)
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
else
|
||||
p.y = p.y + 1
|
||||
if is_water(p) then
|
||||
local y = self.object:getvelocity().y
|
||||
if y >= 4.5 then
|
||||
y = 4.5
|
||||
local y = self.object:get_velocity().y
|
||||
if y >= 5 then
|
||||
y = 5
|
||||
elseif y < 0 then
|
||||
new_acce = {x = 0, y = 20, z = 0}
|
||||
else
|
||||
new_acce = {x = 0, y = 5, z = 0}
|
||||
end
|
||||
new_velo = get_velocity(self.v, self.object:getyaw(), y)
|
||||
self.object:setpos(self.object:getpos())
|
||||
new_velo = get_velocity(self.v, self.object:get_yaw(), y)
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
else
|
||||
new_acce = {x = 0, y = 0, z = 0}
|
||||
if math.abs(self.object:getvelocity().y) < 1 then
|
||||
local pos = self.object:getpos()
|
||||
if math.abs(self.object:get_velocity().y) < 1 then
|
||||
local pos = self.object:get_pos()
|
||||
pos.y = math.floor(pos.y) + 0.5
|
||||
self.object:setpos(pos)
|
||||
new_velo = get_velocity(self.v, self.object:getyaw(), 0)
|
||||
self.object:set_pos(pos)
|
||||
new_velo = get_velocity(self.v, self.object:get_yaw(), 0)
|
||||
else
|
||||
new_velo = get_velocity(self.v, self.object:getyaw(),
|
||||
self.object:getvelocity().y)
|
||||
self.object:setpos(self.object:getpos())
|
||||
new_velo = get_velocity(self.v, self.object:get_yaw(),
|
||||
self.object:get_velocity().y)
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
end
|
||||
end
|
||||
end
|
||||
self.object:setvelocity(new_velo)
|
||||
self.object:setacceleration(new_acce)
|
||||
self.object:set_velocity(new_velo)
|
||||
self.object:set_acceleration(new_acce)
|
||||
end
|
||||
|
||||
|
||||
@ -203,22 +243,40 @@ minetest.register_entity("boats:boat", boat)
|
||||
|
||||
minetest.register_craftitem("boats:boat", {
|
||||
description = "Boat",
|
||||
inventory_image = "boat_inventory.png",
|
||||
wield_image = "boat_wield.png",
|
||||
inventory_image = "boats_inventory.png",
|
||||
wield_image = "boats_wield.png",
|
||||
wield_scale = {x = 2, y = 2, z = 1},
|
||||
liquids_pointable = true,
|
||||
groups = {flammable = 2},
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = pointed_thing.under
|
||||
local node = minetest.get_node(under)
|
||||
local udef = minetest.registered_nodes[node.name]
|
||||
if udef and udef.on_rightclick and
|
||||
not (placer and placer:is_player() and
|
||||
placer:get_player_control().sneak) then
|
||||
return udef.on_rightclick(under, node, placer, itemstack,
|
||||
pointed_thing) or itemstack
|
||||
end
|
||||
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
return itemstack
|
||||
end
|
||||
if not is_water(pointed_thing.under) then
|
||||
return
|
||||
return itemstack
|
||||
end
|
||||
pointed_thing.under.y = pointed_thing.under.y + 0.5
|
||||
minetest.add_entity(pointed_thing.under, "boats:boat")
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
boat = minetest.add_entity(pointed_thing.under, "boats:boat")
|
||||
if boat then
|
||||
if placer then
|
||||
boat:set_yaw(placer:get_look_horizontal())
|
||||
end
|
||||
local player_name = placer and placer:get_player_name() or ""
|
||||
if not (creative and creative.is_enabled_for and
|
||||
creative.is_enabled_for(player_name)) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
@ -233,3 +291,9 @@ minetest.register_craft({
|
||||
{"group:wood", "group:wood", "group:wood"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "boats:boat",
|
||||
burntime = 20,
|
||||
})
|
||||
|
63
mods/boats/license.txt
Normal file
@ -0,0 +1,63 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (C) 2012-2016 PilzAdam
|
||||
Copyright (C) 2012-2016 Various Minetest developers and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
Licenses of media (textures and model)
|
||||
--------------------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2012-2016 Zeg9
|
||||
Copyright (C) 2012-2016 thetoon
|
||||
Copyright (C) 2012-2016 PavelS(SokolovPavel)
|
||||
Copyright (C) 2016 sofar (sofar@foo-projects.org)
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
358
mods/boats/models/boats_boat.obj
Normal file
@ -0,0 +1,358 @@
|
||||
# Blender v2.76 (sub 11) OBJ File: 'boat.blend'
|
||||
# www.blender.org
|
||||
mtllib boat.mtl
|
||||
o boats_boat
|
||||
v -6.786140 -3.033999 -9.415440
|
||||
v -6.786140 -1.967150 -9.415440
|
||||
v -6.786140 -1.967150 8.793510
|
||||
v -6.786140 -3.033999 8.793510
|
||||
v 5.732520 -1.967150 -9.415440
|
||||
v 5.732520 -3.033999 -9.415440
|
||||
v 5.732520 -3.033999 8.793510
|
||||
v 5.732520 -1.967150 8.793510
|
||||
v -2.233900 -3.033999 -9.415440
|
||||
v -2.233900 -1.967150 -9.415440
|
||||
v -2.233900 -1.967150 8.793510
|
||||
v -2.233900 -3.033999 8.793510
|
||||
v 2.318340 -3.033999 -9.415440
|
||||
v 2.318340 -1.967150 -9.415440
|
||||
v 2.318340 -1.967150 8.793510
|
||||
v 2.318340 -3.033999 8.793510
|
||||
v -3.371960 -3.033999 8.793510
|
||||
v -3.371960 -1.967150 8.793510
|
||||
v -3.371960 -1.967150 -9.415440
|
||||
v -3.371960 -3.033999 -9.415440
|
||||
v 2.318340 0.276645 8.793510
|
||||
v 1.180280 -1.967150 8.793510
|
||||
v 5.732520 0.276645 8.793510
|
||||
v 5.732520 1.039180 8.793510
|
||||
v 6.870580 0.276645 8.793510
|
||||
v 6.870580 -1.967150 8.793510
|
||||
v 2.318340 1.039180 8.793510
|
||||
v 1.180280 0.276645 8.793510
|
||||
v 1.180280 1.039180 8.793510
|
||||
v 1.180280 -3.033999 8.793510
|
||||
v -2.233900 0.276645 8.793510
|
||||
v -3.371960 0.276645 8.793510
|
||||
v -2.233900 1.039180 8.793510
|
||||
v -3.371960 1.039180 8.793510
|
||||
v -6.786140 0.276645 8.793510
|
||||
v -7.786200 0.276645 8.793510
|
||||
v -7.786200 -1.967150 8.793510
|
||||
v -6.786140 1.039180 8.793510
|
||||
v 1.180280 -1.967150 -9.415440
|
||||
v 1.180280 -3.033999 -9.415440
|
||||
v 2.318340 0.276645 -9.415440
|
||||
v 1.180280 0.276645 -9.415440
|
||||
v 2.318340 1.039180 -9.415440
|
||||
v 5.732520 0.276645 -9.415440
|
||||
v 6.870580 -1.967150 -9.415440
|
||||
v 5.732520 1.039180 -9.415440
|
||||
v 6.870580 0.276645 -9.415440
|
||||
v 0.042220 1.039180 -9.415440
|
||||
v 1.180280 1.039180 -9.415440
|
||||
v 0.042220 -1.967150 -9.415440
|
||||
v -1.095840 -1.967150 -9.415440
|
||||
v -2.233900 0.276645 -9.415440
|
||||
v -3.371960 0.276645 -9.415440
|
||||
v -2.233900 1.039180 -9.415440
|
||||
v -1.095840 1.039180 -9.415440
|
||||
v -3.371960 1.039180 -9.415440
|
||||
v -6.786140 0.276645 -9.415440
|
||||
v -6.786140 1.039180 -9.415440
|
||||
v -7.786200 -1.967150 -9.415440
|
||||
v -7.786200 0.276645 -9.415440
|
||||
v -1.095840 0.156645 -12.044100
|
||||
v -1.095840 -4.601110 -9.415440
|
||||
v -1.095840 1.039181 -10.802900
|
||||
v -1.095840 2.868579 -10.802900
|
||||
v -1.095840 2.868580 -7.883420
|
||||
v -1.095840 3.746069 -12.034100
|
||||
v -1.095840 3.746070 -7.883420
|
||||
v -1.095840 0.156645 -14.294900
|
||||
v -1.095840 -4.601110 -14.284900
|
||||
v 0.042220 -4.601110 -14.284900
|
||||
v 0.042220 -4.601110 -9.415440
|
||||
v 0.042220 1.039181 -10.802900
|
||||
v 0.042220 0.156645 -12.044100
|
||||
v 0.042220 2.868579 -10.802900
|
||||
v 0.042220 0.156645 -14.294900
|
||||
v 0.042220 3.746069 -12.034100
|
||||
v 0.042220 3.746070 -7.883420
|
||||
v 0.042220 2.868580 -7.883420
|
||||
v -1.096322 -3.033999 -9.415440
|
||||
v 0.044046 -3.035397 -9.415440
|
||||
vt 1.000000 0.187500
|
||||
vt -1.000000 0.312500
|
||||
vt 1.000000 0.312500
|
||||
vt 0.687500 1.000000
|
||||
vt 0.500000 0.875000
|
||||
vt 0.500000 0.625000
|
||||
vt -1.000000 0.062500
|
||||
vt 1.000000 0.062500
|
||||
vt 1.000000 -0.000000
|
||||
vt -1.000000 0.125000
|
||||
vt 1.000000 0.125000
|
||||
vt 0.437500 0.125000
|
||||
vt 0.312500 0.500000
|
||||
vt 0.312500 0.125000
|
||||
vt 1.000000 0.625000
|
||||
vt -1.000000 0.500000
|
||||
vt 1.000000 0.500000
|
||||
vt 0.187500 0.687500
|
||||
vt -0.187500 0.687500
|
||||
vt -0.187500 0.312500
|
||||
vt 1.000000 0.812500
|
||||
vt -1.000000 0.937500
|
||||
vt -1.000000 0.812500
|
||||
vt 0.812500 0.687500
|
||||
vt 1.187500 0.687500
|
||||
vt 0.812500 0.312500
|
||||
vt 1.000000 0.562500
|
||||
vt 0.312500 0.437500
|
||||
vt 1.000000 0.437500
|
||||
vt 1.000000 0.750000
|
||||
vt -1.000000 0.875000
|
||||
vt -1.000000 0.750000
|
||||
vt -1.000000 1.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.437500 0.625000
|
||||
vt 0.562500 0.437500
|
||||
vt 0.562500 0.625000
|
||||
vt -1.000000 0.437500
|
||||
vt -1.000000 0.000000
|
||||
vt 0.500000 0.062500
|
||||
vt 0.375000 0.750000
|
||||
vt 0.500000 0.750000
|
||||
vt -1.000000 0.250000
|
||||
vt -1.000000 0.687500
|
||||
vt 1.000000 0.687500
|
||||
vt 0.625000 0.375000
|
||||
vt 1.000000 0.375000
|
||||
vt 1.000000 0.250000
|
||||
vt 1.000000 0.937500
|
||||
vt 0.437500 0.812500
|
||||
vt 0.312500 0.312500
|
||||
vt 0.312500 0.812500
|
||||
vt 0.437500 0.312500
|
||||
vt 0.437500 0.437500
|
||||
vt 0.687500 0.812500
|
||||
vt 0.000000 0.687500
|
||||
vt 0.000000 0.812500
|
||||
vt -1.000000 0.562500
|
||||
vt 0.875000 0.812500
|
||||
vt 0.875000 0.687500
|
||||
vt 0.250000 0.312500
|
||||
vt 0.562500 0.187500
|
||||
vt 0.250000 0.187500
|
||||
vt -1.000000 0.187500
|
||||
vt 0.312500 0.625000
|
||||
vt 0.312500 0.187500
|
||||
vt 0.312500 -0.187500
|
||||
vt 1.000000 -0.187500
|
||||
vt 0.687500 0.500000
|
||||
vt -0.000000 1.000000
|
||||
vt 0.000000 0.875000
|
||||
vt 0.437500 0.500000
|
||||
vt -1.000000 0.625000
|
||||
vt 0.812500 0.187500
|
||||
vt 1.187500 0.187500
|
||||
vt 1.187500 0.312500
|
||||
vt 1.312500 0.312500
|
||||
vt 1.312500 0.687500
|
||||
vt 0.687500 0.187500
|
||||
vt 0.687500 0.312500
|
||||
vt 1.187500 0.812500
|
||||
vt 0.812500 0.812500
|
||||
vt 0.187500 0.312500
|
||||
vt 0.312500 0.687500
|
||||
vt 0.687500 0.687500
|
||||
vt -0.187500 0.187500
|
||||
vt 0.187500 0.187500
|
||||
vt -0.312500 0.687500
|
||||
vt -0.312500 0.312500
|
||||
vt 0.187500 0.812500
|
||||
vt -0.187500 0.812500
|
||||
vt 0.437500 0.687500
|
||||
vt 0.437500 0.187500
|
||||
vt 0.562500 0.812500
|
||||
vt 0.562500 0.687500
|
||||
vt 0.312500 0.562500
|
||||
vt 1.000000 0.875000
|
||||
vt 0.375000 0.062500
|
||||
vt -1.000000 0.375000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.875000 0.562500
|
||||
vt 0.937500 0.812500
|
||||
vt 0.937500 0.687500
|
||||
vt 0.875000 0.937500
|
||||
vt 0.562500 0.312500
|
||||
vn -1.000000 0.000000 0.000000
|
||||
vn 1.000000 0.000000 0.000000
|
||||
vn 0.000000 0.000000 1.000000
|
||||
vn 0.000000 0.000000 -1.000000
|
||||
vn 0.000000 -1.000000 0.000000
|
||||
vn 0.000000 1.000000 0.000000
|
||||
vn 0.000000 -0.002100 -1.000000
|
||||
vn 0.001200 -1.000000 0.000000
|
||||
vn 0.000000 0.002800 -1.000000
|
||||
vn -0.001200 -1.000000 0.000200
|
||||
g boats_boat_boats_boat_None
|
||||
usemtl None
|
||||
s off
|
||||
f 41/1/1 27/2/1 43/3/1
|
||||
f 76/4/2 74/5/2 72/6/2
|
||||
f 8/7/2 6/1/2 5/8/2
|
||||
f 15/9/1 13/10/1 16/11/1
|
||||
f 51/12/3 71/13/3 50/14/3
|
||||
f 56/15/2 32/16/2 53/17/2
|
||||
f 15/18/3 8/19/3 23/20/3
|
||||
f 22/21/2 40/22/2 39/23/2
|
||||
f 19/24/4 2/25/4 53/26/4
|
||||
f 70/27/5 62/28/5 69/29/5
|
||||
f 11/30/5 19/31/5 10/32/5
|
||||
f 4/15/5 20/33/5 17/34/5
|
||||
f 72/35/3 64/36/3 63/37/3
|
||||
f 13/8/5 7/38/5 16/7/5
|
||||
f 23/39/6 47/11/6 44/9/6
|
||||
f 68/40/7 70/41/7 69/42/7
|
||||
f 80/43/8 40/10/8 30/11/8
|
||||
f 3/15/1 1/32/1 4/30/1
|
||||
f 20/44/2 18/27/2 17/45/2
|
||||
f 74/17/5 65/46/5 64/47/5
|
||||
f 31/43/1 54/47/1 52/48/1
|
||||
f 22/47/5 14/43/5 15/48/5
|
||||
f 46/1/2 23/7/2 44/8/2
|
||||
f 57/21/1 38/22/1 58/49/1
|
||||
f 61/50/9 76/51/9 73/52/9
|
||||
f 37/45/5 2/23/5 3/21/5
|
||||
f 78/28/3 67/53/3 65/54/3
|
||||
f 64/5/1 66/4/1 63/6/1
|
||||
f 76/55/6 67/56/6 77/57/6
|
||||
f 47/17/2 26/10/2 45/11/2
|
||||
f 5/16/5 26/47/5 8/17/5
|
||||
f 33/58/6 48/59/6 55/60/6
|
||||
f 29/38/2 42/3/2 49/29/2
|
||||
f 32/44/6 52/21/6 53/45/6
|
||||
f 58/15/6 34/33/6 56/34/6
|
||||
f 27/7/6 46/29/6 43/8/6
|
||||
f 73/61/6 68/62/6 61/63/6
|
||||
f 21/58/6 42/29/6 28/38/6
|
||||
f 11/29/1 9/58/1 12/27/1
|
||||
f 59/45/1 36/2/1 60/3/1
|
||||
f 60/9/6 35/10/6 57/11/6
|
||||
f 41/1/1 21/64/1 27/2/1
|
||||
f 72/6/2 48/65/2 50/66/2
|
||||
f 50/66/2 71/67/2 70/68/2
|
||||
f 70/68/2 75/17/2 73/69/2
|
||||
f 76/4/2 77/70/2 74/5/2
|
||||
f 77/70/2 78/71/2 74/5/2
|
||||
f 50/66/2 70/68/2 73/69/2
|
||||
f 73/69/2 76/4/2 72/6/2
|
||||
f 72/6/2 50/66/2 73/69/2
|
||||
f 8/7/2 7/64/2 6/1/2
|
||||
f 15/9/1 14/39/1 13/10/1
|
||||
f 51/12/3 62/72/3 71/13/3
|
||||
f 56/15/2 34/73/2 32/16/2
|
||||
f 32/26/3 34/74/3 38/75/3
|
||||
f 35/76/3 36/77/3 37/78/3
|
||||
f 32/26/3 38/75/3 35/76/3
|
||||
f 29/66/3 33/79/3 31/80/3
|
||||
f 32/26/3 35/76/3 3/25/3
|
||||
f 28/51/3 29/66/3 31/80/3
|
||||
f 31/80/3 32/26/3 18/24/3
|
||||
f 3/25/3 4/81/3 17/82/3
|
||||
f 35/76/3 37/78/3 3/25/3
|
||||
f 21/83/3 28/51/3 22/84/3
|
||||
f 3/25/3 17/82/3 18/24/3
|
||||
f 11/85/3 12/55/3 30/52/3
|
||||
f 32/26/3 3/25/3 18/24/3
|
||||
f 11/85/3 30/52/3 22/84/3
|
||||
f 31/80/3 18/24/3 11/85/3
|
||||
f 24/86/3 27/87/3 21/83/3
|
||||
f 28/51/3 31/80/3 11/85/3
|
||||
f 11/85/3 22/84/3 28/51/3
|
||||
f 24/86/3 21/83/3 23/20/3
|
||||
f 26/88/3 25/89/3 23/20/3
|
||||
f 23/20/3 21/83/3 15/18/3
|
||||
f 15/18/3 16/90/3 7/91/3
|
||||
f 21/83/3 22/84/3 15/18/3
|
||||
f 8/19/3 26/88/3 23/20/3
|
||||
f 15/18/3 7/91/3 8/19/3
|
||||
f 22/21/2 30/49/2 40/22/2
|
||||
f 47/89/4 45/88/4 5/19/4
|
||||
f 5/19/4 6/91/4 13/90/4
|
||||
f 5/19/4 13/90/4 14/18/4
|
||||
f 44/20/4 47/89/4 5/19/4
|
||||
f 43/87/4 46/86/4 44/20/4
|
||||
f 41/83/4 43/87/4 44/20/4
|
||||
f 44/20/4 5/19/4 14/18/4
|
||||
f 39/84/4 40/52/4 80/50/4
|
||||
f 44/20/4 14/18/4 41/83/4
|
||||
f 42/51/4 41/83/4 39/84/4
|
||||
f 39/84/4 80/50/4 50/92/4
|
||||
f 41/83/4 14/18/4 39/84/4
|
||||
f 48/93/4 49/66/4 42/51/4
|
||||
f 50/92/4 48/93/4 42/51/4
|
||||
f 80/50/4 79/94/4 50/92/4
|
||||
f 50/92/4 42/51/4 39/84/4
|
||||
f 54/79/4 55/62/4 52/80/4
|
||||
f 50/92/4 79/94/4 51/95/4
|
||||
f 52/80/4 55/62/4 51/95/4
|
||||
f 51/95/4 79/94/4 10/85/4
|
||||
f 79/94/4 9/55/4 10/85/4
|
||||
f 53/26/4 52/80/4 10/85/4
|
||||
f 58/75/4 56/74/4 53/26/4
|
||||
f 59/78/4 60/77/4 57/76/4
|
||||
f 57/76/4 58/75/4 53/26/4
|
||||
f 52/80/4 51/95/4 10/85/4
|
||||
f 19/24/4 20/82/4 1/81/4
|
||||
f 53/26/4 10/85/4 19/24/4
|
||||
f 59/78/4 57/76/4 2/25/4
|
||||
f 19/24/4 1/81/4 2/25/4
|
||||
f 2/25/4 57/76/4 53/26/4
|
||||
f 70/27/5 71/96/5 62/28/5
|
||||
f 11/30/5 18/97/5 19/31/5
|
||||
f 4/15/5 1/73/5 20/33/5
|
||||
f 72/35/3 74/54/3 64/36/3
|
||||
f 13/8/5 6/29/5 7/38/5
|
||||
f 23/39/6 25/10/6 47/11/6
|
||||
f 68/40/7 75/98/7 70/41/7
|
||||
f 30/11/5 12/17/5 79/99/5
|
||||
f 79/99/10 80/43/10 30/11/10
|
||||
f 12/17/5 9/16/5 79/99/5
|
||||
f 3/15/1 2/73/1 1/32/1
|
||||
f 20/44/2 19/58/2 18/27/2
|
||||
f 74/17/5 78/100/5 65/46/5
|
||||
f 31/43/1 33/99/1 54/47/1
|
||||
f 22/47/5 39/99/5 14/43/5
|
||||
f 46/1/2 24/64/2 23/7/2
|
||||
f 57/21/1 35/23/1 38/22/1
|
||||
f 61/50/9 66/53/9 76/51/9
|
||||
f 37/45/5 59/44/5 2/23/5
|
||||
f 78/28/3 77/51/3 67/53/3
|
||||
f 62/67/1 51/66/1 69/68/1
|
||||
f 51/66/1 55/65/1 63/6/1
|
||||
f 68/17/1 69/68/1 61/69/1
|
||||
f 61/69/1 69/68/1 51/66/1
|
||||
f 61/69/1 51/66/1 63/6/1
|
||||
f 65/71/1 67/70/1 64/5/1
|
||||
f 61/69/1 63/6/1 66/4/1
|
||||
f 64/5/1 67/70/1 66/4/1
|
||||
f 76/55/6 66/85/6 67/56/6
|
||||
f 47/17/2 25/16/2 26/10/2
|
||||
f 5/16/5 45/99/5 26/47/5
|
||||
f 55/60/6 54/101/6 33/58/6
|
||||
f 33/58/6 29/22/6 48/59/6
|
||||
f 48/59/6 72/102/6 63/103/6
|
||||
f 29/22/6 49/104/6 48/59/6
|
||||
f 48/59/6 63/103/6 55/60/6
|
||||
f 29/38/2 28/2/2 42/3/2
|
||||
f 32/44/6 31/23/6 52/21/6
|
||||
f 58/15/6 38/73/6 34/33/6
|
||||
f 27/7/6 24/38/6 46/29/6
|
||||
f 73/61/6 75/105/6 68/62/6
|
||||
f 21/58/6 41/27/6 42/29/6
|
||||
f 11/29/1 10/38/1 9/58/1
|
||||
f 59/45/1 37/44/1 36/2/1
|
||||
f 60/9/6 36/39/6 35/10/6
|
Before Width: | Height: | Size: 851 B After Width: | Height: | Size: 851 B |
Before Width: | Height: | Size: 546 B After Width: | Height: | Size: 546 B |
@ -1,17 +1,12 @@
|
||||
Minetest 0.4 mod: bones
|
||||
=======================
|
||||
Minetest Game mod: bones
|
||||
========================
|
||||
See license.txt for license information.
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
Copyright (C) 2012 PilzAdam
|
||||
|
||||
WTFPL
|
||||
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
Authors of media files
|
||||
Authors of source code
|
||||
----------------------
|
||||
Bad_Command_
|
||||
Originally by PilzAdam (MIT)
|
||||
Various Minetest developers and contributors (MIT)
|
||||
|
||||
Authors of media (textures)
|
||||
---------------------------
|
||||
All textures: paramat (CC BY-SA 3.0)
|
||||
|
@ -5,29 +5,28 @@ bones = {}
|
||||
|
||||
local function is_owner(pos, name)
|
||||
local owner = minetest.get_meta(pos):get_string("owner")
|
||||
if owner == "" or owner == name then
|
||||
if owner == "" or owner == name or minetest.check_player_privs(name, "protection_bypass") then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
bones.bones_formspec =
|
||||
"size[8,9]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[current_name;main;0,0.3;8,4;]"..
|
||||
"list[current_player;main;0,4.85;8,1;]"..
|
||||
"list[current_player;main;0,6.08;8,3;8]"..
|
||||
local bones_formspec =
|
||||
"size[8,9]" ..
|
||||
"list[current_name;main;0,0.3;8,4;]" ..
|
||||
"list[current_player;main;0,4.85;8,1;]" ..
|
||||
"list[current_player;main;0,6.08;8,3;8]" ..
|
||||
"listring[current_name;main]" ..
|
||||
"listring[current_player;main]" ..
|
||||
default.get_hotbar_bg(0,4.85)
|
||||
|
||||
local share_bones_time = tonumber(minetest.setting_get("share_bones_time") or 1200)
|
||||
local share_bones_time_early = tonumber(minetest.setting_get("share_bones_time_early") or (share_bones_time/4))
|
||||
local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or 1200
|
||||
local share_bones_time_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4
|
||||
|
||||
minetest.register_node("bones:bones", {
|
||||
description = "Bones",
|
||||
tiles = {
|
||||
"bones_top.png",
|
||||
"bones_top.png^[transform2",
|
||||
"bones_bottom.png",
|
||||
"bones_side.png",
|
||||
"bones_side.png",
|
||||
@ -35,15 +34,16 @@ minetest.register_node("bones:bones", {
|
||||
"bones_front.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {dig_immediate=2},
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_gravel_footstep", gain=0.5},
|
||||
dug = {name="default_gravel_footstep", gain=1.0},
|
||||
}),
|
||||
groups = {dig_immediate = 2},
|
||||
sounds = default.node_sound_gravel_defaults(),
|
||||
|
||||
can_dig = function(pos, player)
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
return is_owner(pos, player:get_player_name()) and inv:is_empty("main")
|
||||
local name = ""
|
||||
if player then
|
||||
name = player:get_player_name()
|
||||
end
|
||||
return is_owner(pos, name) and inv:is_empty("main")
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
@ -67,12 +67,22 @@ minetest.register_node("bones:bones", {
|
||||
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta:get_inventory():is_empty("main") then
|
||||
local inv = player:get_inventory()
|
||||
if inv:room_for_item("main", {name = "bones:bones"}) then
|
||||
inv:add_item("main", {name = "bones:bones"})
|
||||
else
|
||||
minetest.add_item(pos, "bones:bones")
|
||||
end
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
end,
|
||||
|
||||
on_punch = function(pos, node, player)
|
||||
if(not is_owner(pos, player:get_player_name())) then
|
||||
if not is_owner(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.get_meta(pos):get_string("infotext") == "" then
|
||||
return
|
||||
end
|
||||
|
||||
@ -80,7 +90,7 @@ minetest.register_node("bones:bones", {
|
||||
local player_inv = player:get_inventory()
|
||||
local has_space = true
|
||||
|
||||
for i=1,inv:get_size("main") do
|
||||
for i = 1, inv:get_size("main") do
|
||||
local stk = inv:get_stack("main", i)
|
||||
if player_inv:room_for_item("main", stk) then
|
||||
inv:set_stack("main", i, nil)
|
||||
@ -93,6 +103,11 @@ minetest.register_node("bones:bones", {
|
||||
|
||||
-- remove bones if player emptied them
|
||||
if has_space then
|
||||
if player_inv:room_for_item("main", {name = "bones:bones"}) then
|
||||
player_inv:add_item("main", {name = "bones:bones"})
|
||||
else
|
||||
minetest.add_item(pos,"bones:bones")
|
||||
end
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
end,
|
||||
@ -101,26 +116,24 @@ minetest.register_node("bones:bones", {
|
||||
local meta = minetest.get_meta(pos)
|
||||
local time = meta:get_int("time") + elapsed
|
||||
if time >= share_bones_time then
|
||||
meta:set_string("infotext", meta:get_string("owner").."'s old bones")
|
||||
meta:set_string("infotext", meta:get_string("owner") .. "'s old bones")
|
||||
meta:set_string("owner", "")
|
||||
else
|
||||
meta:set_int("time", time)
|
||||
return true
|
||||
end
|
||||
end,
|
||||
on_blast = function(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
local function may_replace(pos, player)
|
||||
local node_name = minetest.get_node(pos).name
|
||||
local node_definition = minetest.registered_nodes[node_name]
|
||||
|
||||
-- if the node is unknown, we let the protection mod decide
|
||||
-- this is consistent with when a player could dig or not dig it
|
||||
-- unknown decoration would often be removed
|
||||
-- while unknown building materials in use would usually be left
|
||||
-- if the node is unknown, we return false
|
||||
if not node_definition then
|
||||
-- only replace nodes that are not protected
|
||||
return not minetest.is_protected(pos, player:get_player_name())
|
||||
return false
|
||||
end
|
||||
|
||||
-- allow replacing air and liquids
|
||||
@ -140,71 +153,120 @@ local function may_replace(pos, player)
|
||||
return node_definition.buildable_to and not minetest.is_protected(pos, player:get_player_name())
|
||||
end
|
||||
|
||||
local drop = function(pos, itemstack)
|
||||
local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count()))
|
||||
if obj then
|
||||
obj:set_velocity({
|
||||
x = math.random(-10, 10) / 9,
|
||||
y = 5,
|
||||
z = math.random(-10, 10) / 9,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local player_inventory_lists = { "main", "craft" }
|
||||
bones.player_inventory_lists = player_inventory_lists
|
||||
|
||||
local function is_all_empty(player_inv)
|
||||
for _, list_name in ipairs(player_inventory_lists) do
|
||||
if not player_inv:is_empty(list_name) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
if minetest.setting_getbool("creative_mode") then
|
||||
return
|
||||
|
||||
local bones_mode = minetest.settings:get("bones_mode") or "bones"
|
||||
if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then
|
||||
bones_mode = "bones"
|
||||
end
|
||||
|
||||
local player_inv = player:get_inventory()
|
||||
if player_inv:is_empty("main") and
|
||||
player_inv:is_empty("craft") then
|
||||
return
|
||||
end
|
||||
|
||||
local pos = player:getpos()
|
||||
pos.x = math.floor(pos.x+0.5)
|
||||
pos.y = math.floor(pos.y+0.5)
|
||||
pos.z = math.floor(pos.z+0.5)
|
||||
local param2 = minetest.dir_to_facedir(player:get_look_dir())
|
||||
local bones_position_message = minetest.settings:get_bool("bones_position_message") == true
|
||||
local player_name = player:get_player_name()
|
||||
local player_inv = player:get_inventory()
|
||||
local pos = vector.round(player:get_pos())
|
||||
local pos_string = minetest.pos_to_string(pos)
|
||||
|
||||
if (not may_replace(pos, player)) then
|
||||
if (may_replace({x=pos.x, y=pos.y+1, z=pos.z}, player)) then
|
||||
-- drop one node above if there's space
|
||||
-- this should solve most cases of protection related deaths in which players dig straight down
|
||||
-- yet keeps the bones reachable
|
||||
pos.y = pos.y+1
|
||||
-- return if keep inventory set or in creative mode
|
||||
if bones_mode == "keep" or (creative and creative.is_enabled_for
|
||||
and creative.is_enabled_for(player:get_player_name())) then
|
||||
minetest.log("action", player_name .. " dies at " .. pos_string ..
|
||||
". No bones placed")
|
||||
if bones_position_message then
|
||||
minetest.chat_send_player(player_name, player_name .. " died at " .. pos_string .. ".")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local player_inv = player:get_inventory()
|
||||
if is_all_empty(player_inv) then
|
||||
minetest.log("action", player_name .. " dies at " .. pos_string ..
|
||||
". No bones placed")
|
||||
if bones_position_message then
|
||||
minetest.chat_send_player(player_name, player_name .. " died at " .. pos_string .. ".")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- check if it's possible to place bones, if not find space near player
|
||||
if bones_mode == "bones" and not may_replace(pos, player) then
|
||||
local air = minetest.find_node_near(pos, 1, {"air"})
|
||||
if air and not minetest.is_protected(air, player_name) then
|
||||
pos = air
|
||||
else
|
||||
-- drop items instead of delete
|
||||
for i=1,player_inv:get_size("main") do
|
||||
minetest.add_item(pos, player_inv:get_stack("main", i))
|
||||
end
|
||||
for i=1,player_inv:get_size("craft") do
|
||||
minetest.add_item(pos, player_inv:get_stack("craft", i))
|
||||
end
|
||||
-- empty lists main and craft
|
||||
player_inv:set_list("main", {})
|
||||
player_inv:set_list("craft", {})
|
||||
return
|
||||
bones_mode = "drop"
|
||||
end
|
||||
end
|
||||
|
||||
minetest.set_node(pos, {name="bones:bones", param2=param2})
|
||||
if bones_mode == "drop" then
|
||||
for _, list_name in ipairs(player_inventory_lists) do
|
||||
for i = 1, player_inv:get_size(list_name) do
|
||||
drop(pos, player_inv:get_stack(list_name, i))
|
||||
end
|
||||
player_inv:set_list(list_name, {})
|
||||
end
|
||||
drop(pos, ItemStack("bones:bones"))
|
||||
minetest.log("action", player_name .. " dies at " .. pos_string ..
|
||||
". Inventory dropped")
|
||||
if bones_position_message then
|
||||
minetest.chat_send_player(player_name, player_name .. " died at " .. pos_string ..
|
||||
", and dropped their inventory.")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local param2 = minetest.dir_to_facedir(player:get_look_dir())
|
||||
minetest.set_node(pos, {name = "bones:bones", param2 = param2})
|
||||
|
||||
minetest.log("action", player_name .. " dies at " .. pos_string ..
|
||||
". Bones placed")
|
||||
if bones_position_message then
|
||||
minetest.chat_send_player(player_name, player_name .. " died at " .. pos_string ..
|
||||
", and bones were placed.")
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 8*4)
|
||||
inv:set_list("main", player_inv:get_list("main"))
|
||||
inv:set_size("main", 8 * 4)
|
||||
|
||||
for i=1,player_inv:get_size("craft") do
|
||||
local stack = player_inv:get_stack("craft", i)
|
||||
if inv:room_for_item("main", stack) then
|
||||
inv:add_item("main", stack)
|
||||
else
|
||||
--drop if no space left
|
||||
minetest.add_item(pos, stack)
|
||||
for _, list_name in ipairs(player_inventory_lists) do
|
||||
for i = 1, player_inv:get_size(list_name) do
|
||||
local stack = player_inv:get_stack(list_name, i)
|
||||
if inv:room_for_item("main", stack) then
|
||||
inv:add_item("main", stack)
|
||||
else -- no space left
|
||||
drop(pos, stack)
|
||||
end
|
||||
end
|
||||
player_inv:set_list(list_name, {})
|
||||
end
|
||||
|
||||
player_inv:set_list("main", {})
|
||||
player_inv:set_list("craft", {})
|
||||
|
||||
meta:set_string("formspec", bones.bones_formspec)
|
||||
meta:set_string("formspec", bones_formspec)
|
||||
meta:set_string("owner", player_name)
|
||||
|
||||
if share_bones_time ~= 0 then
|
||||
meta:set_string("infotext", player_name.."'s fresh bones")
|
||||
meta:set_string("infotext", player_name .. "'s fresh bones")
|
||||
|
||||
if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then
|
||||
meta:set_int("time", 0)
|
||||
|
58
mods/bones/license.txt
Normal file
@ -0,0 +1,58 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (C) 2012-2016 PilzAdam
|
||||
Copyright (C) 2012-2016 Various Minetest developers and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
Licenses of media (textures)
|
||||
----------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2016 paramat
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
Before Width: | Height: | Size: 181 B After Width: | Height: | Size: 740 B |
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 656 B |
Before Width: | Height: | Size: 187 B After Width: | Height: | Size: 637 B |
Before Width: | Height: | Size: 188 B After Width: | Height: | Size: 700 B |
Before Width: | Height: | Size: 182 B After Width: | Height: | Size: 662 B |
@ -1,26 +1,13 @@
|
||||
Minetest 0.4 mod: bucket
|
||||
Minetest Game mod: bucket
|
||||
=========================
|
||||
See license.txt for license information.
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
Copyright (C) 2011-2012 Kahrl <kahrl@gmx.net>
|
||||
Copyright (C) 2011-2012 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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
Authors of media files
|
||||
-----------------------
|
||||
Everything not listed in here:
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
Authors of source code
|
||||
----------------------
|
||||
Kahrl <kahrl@gmx.net> (LGPLv2.1+)
|
||||
celeron55, Perttu Ahola <celeron55@gmail.com> (LGPLv2.1+)
|
||||
Various Minetest developers and contributors (LGPLv2.1+)
|
||||
|
||||
Authors of media (textures)
|
||||
---------------------------
|
||||
ElementW (CC BY-SA 3.0)
|
||||
|
@ -36,12 +36,17 @@ end
|
||||
-- inventory_image = texture of the new bucket item (ignored if itemname == nil)
|
||||
-- name = text description of the bucket item
|
||||
-- groups = (optional) groups of the bucket item, for example {water_bucket = 1}
|
||||
-- force_renew = (optional) bool. Force the liquid source to renew if it has a
|
||||
-- source neighbour, even if defined as 'liquid_renewable = false'.
|
||||
-- Needed to avoid creating holes in sloping rivers.
|
||||
-- This function can be called from any mod (that depends on bucket).
|
||||
function bucket.register_liquid(source, flowing, itemname, inventory_image, name, groups)
|
||||
function bucket.register_liquid(source, flowing, itemname, inventory_image, name,
|
||||
groups, force_renew)
|
||||
bucket.liquids[source] = {
|
||||
source = source,
|
||||
flowing = flowing,
|
||||
itemname = itemname,
|
||||
force_renew = force_renew,
|
||||
}
|
||||
bucket.liquids[flowing] = bucket.liquids[source]
|
||||
|
||||
@ -52,6 +57,7 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name
|
||||
stack_max = 1,
|
||||
liquids_pointable = true,
|
||||
groups = groups,
|
||||
|
||||
on_place = function(itemstack, user, pointed_thing)
|
||||
-- Must be pointing to node
|
||||
if pointed_thing.type ~= "node" then
|
||||
@ -59,47 +65,46 @@ function bucket.register_liquid(source, flowing, itemname, inventory_image, name
|
||||
end
|
||||
|
||||
local node = minetest.get_node_or_nil(pointed_thing.under)
|
||||
local ndef
|
||||
if node then
|
||||
ndef = minetest.registered_nodes[node.name]
|
||||
end
|
||||
local ndef = node and minetest.registered_nodes[node.name]
|
||||
|
||||
-- Call on_rightclick if the pointed node defines it
|
||||
if ndef and ndef.on_rightclick and
|
||||
user and not user:get_player_control().sneak then
|
||||
not (user and user:is_player() and
|
||||
user:get_player_control().sneak) then
|
||||
return ndef.on_rightclick(
|
||||
pointed_thing.under,
|
||||
node, user,
|
||||
itemstack) or itemstack
|
||||
itemstack)
|
||||
end
|
||||
|
||||
local place_liquid = function(pos, node, source, flowing)
|
||||
if check_protection(pos,
|
||||
user and user:get_player_name() or "",
|
||||
"place "..source) then
|
||||
return
|
||||
end
|
||||
minetest.add_node(pos, {name=source})
|
||||
end
|
||||
local lpos
|
||||
|
||||
-- Check if pointing to a buildable node
|
||||
if ndef and ndef.buildable_to then
|
||||
-- buildable; replace the node
|
||||
place_liquid(pointed_thing.under, node,
|
||||
source, flowing)
|
||||
lpos = pointed_thing.under
|
||||
else
|
||||
-- not buildable to; place the liquid above
|
||||
-- check if the node above can be replaced
|
||||
local node = minetest.get_node_or_nil(pointed_thing.above)
|
||||
if node and minetest.registered_nodes[node.name].buildable_to then
|
||||
place_liquid(pointed_thing.above,
|
||||
node, source,
|
||||
flowing)
|
||||
else
|
||||
|
||||
lpos = pointed_thing.above
|
||||
node = minetest.get_node_or_nil(lpos)
|
||||
local above_ndef = node and minetest.registered_nodes[node.name]
|
||||
|
||||
if not above_ndef or not above_ndef.buildable_to then
|
||||
-- do not remove the bucket with the liquid
|
||||
return
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
return {name="bucket:bucket_empty"}
|
||||
|
||||
if check_protection(lpos, user
|
||||
and user:get_player_name()
|
||||
or "", "place "..source) then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.set_node(lpos, {name = source})
|
||||
return ItemStack("bucket:bucket_empty")
|
||||
end
|
||||
})
|
||||
end
|
||||
@ -111,8 +116,11 @@ minetest.register_craftitem("bucket:bucket_empty", {
|
||||
stack_max = 99,
|
||||
liquids_pointable = true,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
-- Must be pointing to node
|
||||
if pointed_thing.type ~= "node" then
|
||||
if pointed_thing.type == "object" then
|
||||
pointed_thing.ref:punch(user, 1.0, { full_punch_interval=1.0 }, nil)
|
||||
return user:get_wielded_item()
|
||||
elseif pointed_thing.type ~= "node" then
|
||||
-- do nothing if it's neither object nor node
|
||||
return
|
||||
end
|
||||
-- Check if pointing to a liquid source
|
||||
@ -140,9 +148,9 @@ minetest.register_craftitem("bucket:bucket_empty", {
|
||||
if inv:room_for_item("main", {name=liquiddef.itemname}) then
|
||||
inv:add_item("main", liquiddef.itemname)
|
||||
else
|
||||
local pos = user:getpos()
|
||||
local pos = user:get_pos()
|
||||
pos.y = math.floor(pos.y + 0.5)
|
||||
core.add_item(pos, liquiddef.itemname)
|
||||
minetest.add_item(pos, liquiddef.itemname)
|
||||
end
|
||||
|
||||
-- set to return empty buckets minus 1
|
||||
@ -150,9 +158,24 @@ minetest.register_craftitem("bucket:bucket_empty", {
|
||||
|
||||
end
|
||||
|
||||
minetest.add_node(pointed_thing.under, {name="air"})
|
||||
-- force_renew requires a source neighbour
|
||||
local source_neighbor = false
|
||||
if liquiddef.force_renew then
|
||||
source_neighbor =
|
||||
minetest.find_node_near(pointed_thing.under, 1, liquiddef.source)
|
||||
end
|
||||
if not (source_neighbor and liquiddef.force_renew) then
|
||||
minetest.add_node(pointed_thing.under, {name = "air"})
|
||||
end
|
||||
|
||||
return ItemStack(giving_back)
|
||||
else
|
||||
-- non-liquid nodes will have their on_punch triggered
|
||||
local node_def = minetest.registered_nodes[node.name]
|
||||
if node_def then
|
||||
node_def.on_punch(pointed_thing.under, node, user, pointed_thing)
|
||||
end
|
||||
return user:get_wielded_item()
|
||||
end
|
||||
end,
|
||||
})
|
||||
@ -166,13 +189,20 @@ bucket.register_liquid(
|
||||
{water_bucket = 1}
|
||||
)
|
||||
|
||||
-- River water source is 'liquid_renewable = false' to avoid horizontal spread
|
||||
-- of water sources in sloping rivers that can cause water to overflow
|
||||
-- riverbanks and cause floods.
|
||||
-- River water source is instead made renewable by the 'force renew' option
|
||||
-- used here.
|
||||
|
||||
bucket.register_liquid(
|
||||
"default:river_water_source",
|
||||
"default:river_water_flowing",
|
||||
"bucket:bucket_river_water",
|
||||
"bucket_river_water.png",
|
||||
"River Water Bucket",
|
||||
{water_bucket = 1}
|
||||
{water_bucket = 1},
|
||||
true
|
||||
)
|
||||
|
||||
bucket.register_liquid(
|
||||
|
51
mods/bucket/license.txt
Normal file
@ -0,0 +1,51 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
GNU Lesser General Public License, version 2.1
|
||||
Copyright (C) 2011-2016 Kahrl <kahrl@gmx.net>
|
||||
Copyright (C) 2011-2016 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
Copyright (C) 2011-2016 Various Minetest developers and contributors
|
||||
|
||||
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:
|
||||
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
|
||||
|
||||
|
||||
Licenses of media (textures)
|
||||
----------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2015-2016 ElementW
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
BIN
mods/bucket/textures/bucket.png
Normal file → Executable file
Before Width: | Height: | Size: 163 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 167 B After Width: | Height: | Size: 221 B |
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 221 B |
Before Width: | Height: | Size: 169 B After Width: | Height: | Size: 221 B |
14
mods/butterflies/README.txt
Normal file
@ -0,0 +1,14 @@
|
||||
Minetest Game mod: Butterflies
|
||||
==============================
|
||||
Adds butterflies to the world on mapgen, which can be caught in a net if the
|
||||
fireflies mod is also enabled.
|
||||
|
||||
Authors of source code
|
||||
----------------------
|
||||
Shara RedCat (MIT)
|
||||
|
||||
Authors of media (textures)
|
||||
---------------------------
|
||||
Shara RedCat (CC BY-SA 3.0):
|
||||
butterflies_butterfly_*.png
|
||||
butterflies_butterfly_*_animated.png
|
2
mods/butterflies/depends.txt
Normal file
@ -0,0 +1,2 @@
|
||||
default
|
||||
flowers
|
133
mods/butterflies/init.lua
Normal file
@ -0,0 +1,133 @@
|
||||
-- register butterflies
|
||||
local butter_list = {
|
||||
{"white", "White"},
|
||||
{"red", "Red"},
|
||||
{"violet", "Violet"}
|
||||
}
|
||||
|
||||
for i in ipairs (butter_list) do
|
||||
local name = butter_list[i][1]
|
||||
local desc = butter_list[i][2]
|
||||
|
||||
minetest.register_node("butterflies:butterfly_"..name, {
|
||||
description = desc.." Butterfly",
|
||||
drawtype = "plantlike",
|
||||
tiles = {{
|
||||
name = "butterflies_butterfly_"..name.."_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 3
|
||||
},
|
||||
}},
|
||||
inventory_image = "butterflies_butterfly_"..name..".png",
|
||||
wield_image = "butterflies_butterfly_"..name..".png",
|
||||
waving = 1,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
buildable_to = true,
|
||||
walkable = false,
|
||||
groups = {catchable = 1},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
|
||||
},
|
||||
floodable = true,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local player_name = placer:get_player_name()
|
||||
local pos = pointed_thing.above
|
||||
|
||||
if not minetest.is_protected(pos, player_name) and
|
||||
not minetest.is_protected(pointed_thing.under, player_name) and
|
||||
minetest.get_node(pos).name == "air" then
|
||||
minetest.set_node(pos, {name = "butterflies:butterfly_"..name})
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
if minetest.get_node_light(pos) < 11 then
|
||||
minetest.set_node(pos, {name = "butterflies:hidden_butterfly_"..name})
|
||||
end
|
||||
minetest.get_node_timer(pos):start(30)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("butterflies:hidden_butterfly_"..name, {
|
||||
description = "Hidden "..desc.." Butterfly",
|
||||
drawtype = "airlike",
|
||||
inventory_image = "insects_butterfly_"..name..".png",
|
||||
wield_image = "insects_butterfly_"..name..".png",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
drop = "",
|
||||
groups = {not_in_creative_inventory = 1},
|
||||
floodable = true,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local player_name = placer:get_player_name()
|
||||
local pos = pointed_thing.above
|
||||
|
||||
if not minetest.is_protected(pos, player_name) and
|
||||
not minetest.is_protected(pointed_thing.under, player_name) and
|
||||
minetest.get_node(pos).name == "air" then
|
||||
minetest.set_node(pos, {name = "butterflies:hidden_butterfly_"..name})
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
if minetest.get_node_light(pos) >= 11 then
|
||||
minetest.set_node(pos, {name = "butterflies:butterfly_"..name})
|
||||
end
|
||||
minetest.get_node_timer(pos):start(30)
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
-- register decoration
|
||||
minetest.register_decoration({
|
||||
name = "butterflies:butterfly",
|
||||
deco_type = "simple",
|
||||
place_on = {"default:dirt_with_grass"},
|
||||
place_offset_y = 2,
|
||||
sidelen = 80,
|
||||
fill_ratio = 0.005,
|
||||
biomes = {"grassland", "deciduous_forest", "floatland_grassland"},
|
||||
y_max = 31000,
|
||||
y_min = 1,
|
||||
decoration = {
|
||||
"butterflies:butterfly_white",
|
||||
"butterflies:butterfly_red",
|
||||
"butterflies:butterfly_violet"
|
||||
},
|
||||
spawn_by = "group:flower",
|
||||
num_spawn_by = 1
|
||||
})
|
||||
|
||||
-- get decoration ID
|
||||
local butterflies = minetest.get_decoration_id("butterflies:butterfly")
|
||||
minetest.set_gen_notify({decoration = true}, {butterflies})
|
||||
|
||||
-- start nodetimers
|
||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||
local gennotify = minetest.get_mapgen_object("gennotify")
|
||||
local poslist = {}
|
||||
|
||||
for _, pos in ipairs(gennotify["decoration#"..butterflies] or {}) do
|
||||
local deco_pos = {x = pos.x, y = pos.y + 3, z = pos.z}
|
||||
table.insert(poslist, deco_pos)
|
||||
end
|
||||
|
||||
if #poslist ~= 0 then
|
||||
for i = 1, #poslist do
|
||||
local pos = poslist[i]
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
end
|
||||
end
|
||||
end)
|
58
mods/butterflies/license.txt
Normal file
@ -0,0 +1,58 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (c) 2018 Shara RedCat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
Licenses of media (textures)
|
||||
----------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2018 Shara RedCat
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
BIN
mods/butterflies/textures/butterflies_butterfly_red.png
Normal file
After Width: | Height: | Size: 110 B |
BIN
mods/butterflies/textures/butterflies_butterfly_red_animated.png
Normal file
After Width: | Height: | Size: 125 B |
BIN
mods/butterflies/textures/butterflies_butterfly_violet.png
Normal file
After Width: | Height: | Size: 110 B |
After Width: | Height: | Size: 125 B |
BIN
mods/butterflies/textures/butterflies_butterfly_white.png
Normal file
After Width: | Height: | Size: 110 B |
After Width: | Height: | Size: 125 B |
23
mods/carts/README.txt
Normal file
@ -0,0 +1,23 @@
|
||||
Carts (formerly boost_cart)
|
||||
==========================
|
||||
|
||||
Carts, based almost entirely on the mod boost_cart [1], which
|
||||
itself is based on (and fully compatible with) the carts mod [2].
|
||||
|
||||
The model was originally designed by stujones11 [3] (CC-0).
|
||||
|
||||
Cart textures are based on original work from PixelBOX by Gambit (permissive
|
||||
license).
|
||||
|
||||
|
||||
[1] https://github.com/SmallJoker/boost_cart/
|
||||
[2] https://github.com/PilzAdam/carts/
|
||||
[3] https://github.com/stujones11/railcart/
|
||||
|
||||
|
||||
Features
|
||||
----------
|
||||
- A fast cart for your railway or roller coaster (up to 7 m/s!)
|
||||
- Boost and brake rails
|
||||
- Rail junction switching with the 'right-left' walking keys
|
||||
- Handbrake with the 'back' key
|
428
mods/carts/cart_entity.lua
Normal file
@ -0,0 +1,428 @@
|
||||
local cart_entity = {
|
||||
initial_properties = {
|
||||
physical = false, -- otherwise going uphill breaks
|
||||
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||
visual = "mesh",
|
||||
mesh = "carts_cart.b3d",
|
||||
visual_size = {x=1, y=1},
|
||||
textures = {"carts_cart.png"},
|
||||
},
|
||||
|
||||
driver = nil,
|
||||
punched = false, -- used to re-send velocity and position
|
||||
velocity = {x=0, y=0, z=0}, -- only used on punch
|
||||
old_dir = {x=1, y=0, z=0}, -- random value to start the cart on punch
|
||||
old_pos = nil,
|
||||
old_switch = 0,
|
||||
railtype = nil,
|
||||
attached_items = {}
|
||||
}
|
||||
|
||||
function cart_entity:on_rightclick(clicker)
|
||||
if not clicker or not clicker:is_player() then
|
||||
return
|
||||
end
|
||||
local player_name = clicker:get_player_name()
|
||||
if self.driver and player_name == self.driver then
|
||||
self.driver = nil
|
||||
carts:manage_attachment(clicker, nil)
|
||||
elseif not self.driver then
|
||||
self.driver = player_name
|
||||
carts:manage_attachment(clicker, self.object)
|
||||
|
||||
-- player_api does not update the animation
|
||||
-- when the player is attached, reset to default animation
|
||||
player_api.set_animation(clicker, "stand")
|
||||
end
|
||||
end
|
||||
|
||||
function cart_entity:on_activate(staticdata, dtime_s)
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
if string.sub(staticdata, 1, string.len("return")) ~= "return" then
|
||||
return
|
||||
end
|
||||
local data = minetest.deserialize(staticdata)
|
||||
if type(data) ~= "table" then
|
||||
return
|
||||
end
|
||||
self.railtype = data.railtype
|
||||
if data.old_dir then
|
||||
self.old_dir = data.old_dir
|
||||
end
|
||||
end
|
||||
|
||||
function cart_entity:get_staticdata()
|
||||
return minetest.serialize({
|
||||
railtype = self.railtype,
|
||||
old_dir = self.old_dir
|
||||
})
|
||||
end
|
||||
|
||||
-- 0.5.x and later: When the driver leaves
|
||||
function cart_entity:on_detach_child(child)
|
||||
if child and child:get_player_name() == self.driver then
|
||||
self.driver = nil
|
||||
end
|
||||
end
|
||||
|
||||
function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||
local pos = self.object:get_pos()
|
||||
local vel = self.object:get_velocity()
|
||||
if not self.railtype or vector.equals(vel, {x=0, y=0, z=0}) then
|
||||
local node = minetest.get_node(pos).name
|
||||
self.railtype = minetest.get_item_group(node, "connect_to_raillike")
|
||||
end
|
||||
-- Punched by non-player
|
||||
if not puncher or not puncher:is_player() then
|
||||
local cart_dir = carts:get_rail_direction(pos, self.old_dir, nil, nil, self.railtype)
|
||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||
return
|
||||
end
|
||||
self.velocity = vector.multiply(cart_dir, 2)
|
||||
self.punched = true
|
||||
return
|
||||
end
|
||||
-- Player digs cart by sneak-punch
|
||||
if puncher:get_player_control().sneak then
|
||||
if self.sound_handle then
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
end
|
||||
-- Detach driver and items
|
||||
if self.driver then
|
||||
if self.old_pos then
|
||||
self.object:set_pos(self.old_pos)
|
||||
end
|
||||
local player = minetest.get_player_by_name(self.driver)
|
||||
carts:manage_attachment(player, nil)
|
||||
end
|
||||
for _, obj_ in ipairs(self.attached_items) do
|
||||
if obj_ then
|
||||
obj_:set_detach()
|
||||
end
|
||||
end
|
||||
-- Pick up cart
|
||||
local inv = puncher:get_inventory()
|
||||
if not (creative and creative.is_enabled_for
|
||||
and creative.is_enabled_for(puncher:get_player_name()))
|
||||
or not inv:contains_item("main", "carts:cart") then
|
||||
local leftover = inv:add_item("main", "carts:cart")
|
||||
-- If no room in inventory add a replacement cart to the world
|
||||
if not leftover:is_empty() then
|
||||
minetest.add_item(self.object:get_pos(), leftover)
|
||||
end
|
||||
end
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
-- Player punches cart to alter velocity
|
||||
if puncher:get_player_name() == self.driver then
|
||||
if math.abs(vel.x + vel.z) > carts.punch_speed_max then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local punch_dir = carts:velocity_to_dir(puncher:get_look_dir())
|
||||
punch_dir.y = 0
|
||||
local cart_dir = carts:get_rail_direction(pos, punch_dir, nil, nil, self.railtype)
|
||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||
return
|
||||
end
|
||||
|
||||
local punch_interval = 1
|
||||
if tool_capabilities and tool_capabilities.full_punch_interval then
|
||||
punch_interval = tool_capabilities.full_punch_interval
|
||||
end
|
||||
time_from_last_punch = math.min(time_from_last_punch or punch_interval, punch_interval)
|
||||
local f = 2 * (time_from_last_punch / punch_interval)
|
||||
|
||||
self.velocity = vector.multiply(cart_dir, f)
|
||||
self.old_dir = cart_dir
|
||||
self.punched = true
|
||||
end
|
||||
|
||||
local function rail_on_step_event(handler, obj, dtime)
|
||||
if handler then
|
||||
handler(obj, dtime)
|
||||
end
|
||||
end
|
||||
|
||||
-- sound refresh interval = 1.0sec
|
||||
local function rail_sound(self, dtime)
|
||||
if not self.sound_ttl then
|
||||
self.sound_ttl = 1.0
|
||||
return
|
||||
elseif self.sound_ttl > 0 then
|
||||
self.sound_ttl = self.sound_ttl - dtime
|
||||
return
|
||||
end
|
||||
self.sound_ttl = 1.0
|
||||
if self.sound_handle then
|
||||
local handle = self.sound_handle
|
||||
self.sound_handle = nil
|
||||
minetest.after(0.2, minetest.sound_stop, handle)
|
||||
end
|
||||
local vel = self.object:get_velocity()
|
||||
local speed = vector.length(vel)
|
||||
if speed > 0 then
|
||||
self.sound_handle = minetest.sound_play(
|
||||
"carts_cart_moving", {
|
||||
object = self.object,
|
||||
gain = (speed / carts.speed_max) / 2,
|
||||
loop = true,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function get_railparams(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
return carts.railparams[node.name] or {}
|
||||
end
|
||||
|
||||
local v3_len = vector.length
|
||||
local function rail_on_step(self, dtime)
|
||||
local vel = self.object:get_velocity()
|
||||
if self.punched then
|
||||
vel = vector.add(vel, self.velocity)
|
||||
self.object:set_velocity(vel)
|
||||
self.old_dir.y = 0
|
||||
elseif vector.equals(vel, {x=0, y=0, z=0}) then
|
||||
return
|
||||
end
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
local cart_dir = carts:velocity_to_dir(vel)
|
||||
local same_dir = vector.equals(cart_dir, self.old_dir)
|
||||
local update = {}
|
||||
|
||||
if self.old_pos and not self.punched and same_dir then
|
||||
local flo_pos = vector.round(pos)
|
||||
local flo_old = vector.round(self.old_pos)
|
||||
if vector.equals(flo_pos, flo_old) then
|
||||
-- Do not check one node multiple times
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local ctrl, player
|
||||
|
||||
-- Get player controls
|
||||
if self.driver then
|
||||
player = minetest.get_player_by_name(self.driver)
|
||||
if player then
|
||||
ctrl = player:get_player_control()
|
||||
end
|
||||
end
|
||||
|
||||
local stop_wiggle = false
|
||||
if self.old_pos and same_dir then
|
||||
-- Detection for "skipping" nodes (perhaps use average dtime?)
|
||||
-- It's sophisticated enough to take the acceleration in account
|
||||
local acc = self.object:get_acceleration()
|
||||
local distance = dtime * (v3_len(vel) + 0.5 * dtime * v3_len(acc))
|
||||
|
||||
local new_pos, new_dir = carts:pathfinder(
|
||||
pos, self.old_pos, self.old_dir, distance, ctrl,
|
||||
self.old_switch, self.railtype
|
||||
)
|
||||
|
||||
if new_pos then
|
||||
-- No rail found: set to the expected position
|
||||
pos = new_pos
|
||||
update.pos = true
|
||||
cart_dir = new_dir
|
||||
end
|
||||
elseif self.old_pos and self.old_dir.y ~= 1 and not self.punched then
|
||||
-- Stop wiggle
|
||||
stop_wiggle = true
|
||||
end
|
||||
|
||||
local railparams
|
||||
|
||||
-- dir: New moving direction of the cart
|
||||
-- switch_keys: Currently pressed L/R key, used to ignore the key on the next rail node
|
||||
local dir, switch_keys = carts:get_rail_direction(
|
||||
pos, cart_dir, ctrl, self.old_switch, self.railtype
|
||||
)
|
||||
local dir_changed = not vector.equals(dir, self.old_dir)
|
||||
|
||||
local new_acc = {x=0, y=0, z=0}
|
||||
if stop_wiggle or vector.equals(dir, {x=0, y=0, z=0}) then
|
||||
vel = {x = 0, y = 0, z = 0}
|
||||
local pos_r = vector.round(pos)
|
||||
if not carts:is_rail(pos_r, self.railtype)
|
||||
and self.old_pos then
|
||||
pos = self.old_pos
|
||||
elseif not stop_wiggle then
|
||||
pos = pos_r
|
||||
else
|
||||
pos.y = math.floor(pos.y + 0.5)
|
||||
end
|
||||
update.pos = true
|
||||
update.vel = true
|
||||
else
|
||||
-- Direction change detected
|
||||
if dir_changed then
|
||||
vel = vector.multiply(dir, math.abs(vel.x + vel.z))
|
||||
update.vel = true
|
||||
if dir.y ~= self.old_dir.y then
|
||||
pos = vector.round(pos)
|
||||
update.pos = true
|
||||
end
|
||||
end
|
||||
-- Center on the rail
|
||||
if dir.z ~= 0 and math.floor(pos.x + 0.5) ~= pos.x then
|
||||
pos.x = math.floor(pos.x + 0.5)
|
||||
update.pos = true
|
||||
end
|
||||
if dir.x ~= 0 and math.floor(pos.z + 0.5) ~= pos.z then
|
||||
pos.z = math.floor(pos.z + 0.5)
|
||||
update.pos = true
|
||||
end
|
||||
|
||||
-- Slow down or speed up..
|
||||
local acc = dir.y * -4.0
|
||||
|
||||
-- Get rail for corrected position
|
||||
railparams = get_railparams(pos)
|
||||
|
||||
-- no need to check for railparams == nil since we always make it exist.
|
||||
local speed_mod = railparams.acceleration
|
||||
if speed_mod and speed_mod ~= 0 then
|
||||
-- Try to make it similar to the original carts mod
|
||||
acc = acc + speed_mod
|
||||
else
|
||||
-- Handbrake or coast
|
||||
if ctrl and ctrl.down then
|
||||
acc = acc - 3
|
||||
else
|
||||
acc = acc - 0.4
|
||||
end
|
||||
end
|
||||
|
||||
new_acc = vector.multiply(dir, acc)
|
||||
end
|
||||
|
||||
-- Limits
|
||||
local max_vel = carts.speed_max
|
||||
for _, v in pairs({"x","y","z"}) do
|
||||
if math.abs(vel[v]) > max_vel then
|
||||
vel[v] = carts:get_sign(vel[v]) * max_vel
|
||||
new_acc[v] = 0
|
||||
update.vel = true
|
||||
end
|
||||
end
|
||||
|
||||
self.object:set_acceleration(new_acc)
|
||||
self.old_pos = vector.round(pos)
|
||||
if not vector.equals(dir, {x=0, y=0, z=0}) and not stop_wiggle then
|
||||
self.old_dir = vector.new(dir)
|
||||
end
|
||||
self.old_switch = switch_keys
|
||||
|
||||
if self.punched then
|
||||
-- Collect dropped items
|
||||
for _, obj_ in pairs(minetest.get_objects_inside_radius(pos, 1)) do
|
||||
if not obj_:is_player() and
|
||||
obj_:get_luaentity() and
|
||||
not obj_:get_luaentity().physical_state and
|
||||
obj_:get_luaentity().name == "__builtin:item" then
|
||||
|
||||
obj_:set_attach(self.object, "", {x=0, y=0, z=0}, {x=0, y=0, z=0})
|
||||
self.attached_items[#self.attached_items + 1] = obj_
|
||||
end
|
||||
end
|
||||
self.punched = false
|
||||
update.vel = true
|
||||
end
|
||||
|
||||
railparams = railparams or get_railparams(pos)
|
||||
|
||||
if not (update.vel or update.pos) then
|
||||
rail_on_step_event(railparams.on_step, self, dtime)
|
||||
return
|
||||
end
|
||||
|
||||
local yaw = 0
|
||||
if self.old_dir.x < 0 then
|
||||
yaw = 0.5
|
||||
elseif self.old_dir.x > 0 then
|
||||
yaw = 1.5
|
||||
elseif self.old_dir.z < 0 then
|
||||
yaw = 1
|
||||
end
|
||||
self.object:set_yaw(yaw * math.pi)
|
||||
|
||||
local anim = {x=0, y=0}
|
||||
if dir.y == -1 then
|
||||
anim = {x=1, y=1}
|
||||
elseif dir.y == 1 then
|
||||
anim = {x=2, y=2}
|
||||
end
|
||||
self.object:set_animation(anim, 1, 0)
|
||||
|
||||
if update.vel then
|
||||
self.object:set_velocity(vel)
|
||||
end
|
||||
if update.pos then
|
||||
if dir_changed then
|
||||
self.object:set_pos(pos)
|
||||
else
|
||||
self.object:move_to(pos)
|
||||
end
|
||||
end
|
||||
|
||||
-- call event handler
|
||||
rail_on_step_event(railparams.on_step, self, dtime)
|
||||
end
|
||||
|
||||
function cart_entity:on_step(dtime)
|
||||
rail_on_step(self, dtime)
|
||||
rail_sound(self, dtime)
|
||||
end
|
||||
|
||||
minetest.register_entity("carts:cart", cart_entity)
|
||||
|
||||
minetest.register_craftitem("carts:cart", {
|
||||
description = "Cart (Sneak+Click to pick up)",
|
||||
inventory_image = minetest.inventorycube("carts_cart_top.png", "carts_cart_side.png", "carts_cart_side.png"),
|
||||
wield_image = "carts_cart_side.png",
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = pointed_thing.under
|
||||
local node = minetest.get_node(under)
|
||||
local udef = minetest.registered_nodes[node.name]
|
||||
if udef and udef.on_rightclick and
|
||||
not (placer and placer:is_player() and
|
||||
placer:get_player_control().sneak) then
|
||||
return udef.on_rightclick(under, node, placer, itemstack,
|
||||
pointed_thing) or itemstack
|
||||
end
|
||||
|
||||
if not pointed_thing.type == "node" then
|
||||
return
|
||||
end
|
||||
if carts:is_rail(pointed_thing.under) then
|
||||
minetest.add_entity(pointed_thing.under, "carts:cart")
|
||||
elseif carts:is_rail(pointed_thing.above) then
|
||||
minetest.add_entity(pointed_thing.above, "carts:cart")
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
minetest.sound_play({name = "default_place_node_metal", gain = 0.5},
|
||||
{pos = pointed_thing.above})
|
||||
|
||||
if not (creative and creative.is_enabled_for
|
||||
and creative.is_enabled_for(placer:get_player_name())) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "carts:cart",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
||||
},
|
||||
})
|
2
mods/carts/depends.txt
Normal file
@ -0,0 +1,2 @@
|
||||
default
|
||||
player_api
|
248
mods/carts/functions.lua
Normal file
@ -0,0 +1,248 @@
|
||||
function carts:get_sign(z)
|
||||
if z == 0 then
|
||||
return 0
|
||||
else
|
||||
return z / math.abs(z)
|
||||
end
|
||||
end
|
||||
|
||||
function carts:manage_attachment(player, obj)
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
local status = obj ~= nil
|
||||
local player_name = player:get_player_name()
|
||||
if player_api.player_attached[player_name] == status then
|
||||
return
|
||||
end
|
||||
player_api.player_attached[player_name] = status
|
||||
|
||||
if status then
|
||||
player:set_attach(obj, "", {x=0, y=-4.5, z=0}, {x=0, y=0, z=0})
|
||||
player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0})
|
||||
else
|
||||
player:set_detach()
|
||||
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
end
|
||||
end
|
||||
|
||||
function carts:velocity_to_dir(v)
|
||||
if math.abs(v.x) > math.abs(v.z) then
|
||||
return {x=carts:get_sign(v.x), y=carts:get_sign(v.y), z=0}
|
||||
else
|
||||
return {x=0, y=carts:get_sign(v.y), z=carts:get_sign(v.z)}
|
||||
end
|
||||
end
|
||||
|
||||
function carts:is_rail(pos, railtype)
|
||||
local node = minetest.get_node(pos).name
|
||||
if node == "ignore" then
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map(pos, pos)
|
||||
local area = VoxelArea:new{
|
||||
MinEdge = emin,
|
||||
MaxEdge = emax,
|
||||
}
|
||||
local data = vm:get_data()
|
||||
local vi = area:indexp(pos)
|
||||
node = minetest.get_name_from_content_id(data[vi])
|
||||
end
|
||||
if minetest.get_item_group(node, "rail") == 0 then
|
||||
return false
|
||||
end
|
||||
if not railtype then
|
||||
return true
|
||||
end
|
||||
return minetest.get_item_group(node, "connect_to_raillike") == railtype
|
||||
end
|
||||
|
||||
function carts:check_front_up_down(pos, dir_, check_up, railtype)
|
||||
local dir = vector.new(dir_)
|
||||
local cur
|
||||
|
||||
-- Front
|
||||
dir.y = 0
|
||||
cur = vector.add(pos, dir)
|
||||
if carts:is_rail(cur, railtype) then
|
||||
return dir
|
||||
end
|
||||
-- Up
|
||||
if check_up then
|
||||
dir.y = 1
|
||||
cur = vector.add(pos, dir)
|
||||
if carts:is_rail(cur, railtype) then
|
||||
return dir
|
||||
end
|
||||
end
|
||||
-- Down
|
||||
dir.y = -1
|
||||
cur = vector.add(pos, dir)
|
||||
if carts:is_rail(cur, railtype) then
|
||||
return dir
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
|
||||
local pos = vector.round(pos_)
|
||||
local cur
|
||||
local left_check, right_check = true, true
|
||||
|
||||
-- Check left and right
|
||||
local left = {x=0, y=0, z=0}
|
||||
local right = {x=0, y=0, z=0}
|
||||
if dir.z ~= 0 and dir.x == 0 then
|
||||
left.x = -dir.z
|
||||
right.x = dir.z
|
||||
elseif dir.x ~= 0 and dir.z == 0 then
|
||||
left.z = dir.x
|
||||
right.z = -dir.x
|
||||
end
|
||||
|
||||
local straight_priority = ctrl and dir.y ~= 0
|
||||
|
||||
-- Normal, to disallow rail switching up- & downhill
|
||||
if straight_priority then
|
||||
cur = self:check_front_up_down(pos, dir, true, railtype)
|
||||
if cur then
|
||||
return cur
|
||||
end
|
||||
end
|
||||
|
||||
if ctrl then
|
||||
if old_switch == 1 then
|
||||
left_check = false
|
||||
elseif old_switch == 2 then
|
||||
right_check = false
|
||||
end
|
||||
if ctrl.left and left_check then
|
||||
cur = self:check_front_up_down(pos, left, false, railtype)
|
||||
if cur then
|
||||
return cur, 1
|
||||
end
|
||||
left_check = false
|
||||
end
|
||||
if ctrl.right and right_check then
|
||||
cur = self:check_front_up_down(pos, right, false, railtype)
|
||||
if cur then
|
||||
return cur, 2
|
||||
end
|
||||
right_check = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Normal
|
||||
if not straight_priority then
|
||||
cur = self:check_front_up_down(pos, dir, true, railtype)
|
||||
if cur then
|
||||
return cur
|
||||
end
|
||||
end
|
||||
|
||||
-- Left, if not already checked
|
||||
if left_check then
|
||||
cur = carts:check_front_up_down(pos, left, false, railtype)
|
||||
if cur then
|
||||
return cur
|
||||
end
|
||||
end
|
||||
|
||||
-- Right, if not already checked
|
||||
if right_check then
|
||||
cur = carts:check_front_up_down(pos, right, false, railtype)
|
||||
if cur then
|
||||
return cur
|
||||
end
|
||||
end
|
||||
|
||||
-- Backwards
|
||||
if not old_switch then
|
||||
cur = carts:check_front_up_down(pos, {
|
||||
x = -dir.x,
|
||||
y = dir.y,
|
||||
z = -dir.z
|
||||
}, true, railtype)
|
||||
if cur then
|
||||
return cur
|
||||
end
|
||||
end
|
||||
|
||||
return {x=0, y=0, z=0}
|
||||
end
|
||||
|
||||
function carts:pathfinder(pos_, old_pos, old_dir, distance, ctrl,
|
||||
pf_switch, railtype)
|
||||
|
||||
local pos = vector.round(pos_)
|
||||
if vector.equals(old_pos, pos) then
|
||||
return
|
||||
end
|
||||
|
||||
local pf_pos = vector.round(old_pos)
|
||||
local pf_dir = vector.new(old_dir)
|
||||
distance = math.min(carts.path_distance_max,
|
||||
math.floor(distance + 1))
|
||||
|
||||
for i = 1, distance do
|
||||
pf_dir, pf_switch = self:get_rail_direction(
|
||||
pf_pos, pf_dir, ctrl, pf_switch or 0, railtype)
|
||||
|
||||
if vector.equals(pf_dir, {x=0, y=0, z=0}) then
|
||||
-- No way forwards
|
||||
return pf_pos, pf_dir
|
||||
end
|
||||
|
||||
pf_pos = vector.add(pf_pos, pf_dir)
|
||||
|
||||
if vector.equals(pf_pos, pos) then
|
||||
-- Success! Cart moved on correctly
|
||||
return
|
||||
end
|
||||
end
|
||||
-- Not found. Put cart to predicted position
|
||||
return pf_pos, pf_dir
|
||||
end
|
||||
|
||||
function carts:register_rail(name, def_overwrite, railparams)
|
||||
local def = {
|
||||
drawtype = "raillike",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
|
||||
},
|
||||
sounds = default.node_sound_metal_defaults()
|
||||
}
|
||||
for k, v in pairs(def_overwrite) do
|
||||
def[k] = v
|
||||
end
|
||||
if not def.inventory_image then
|
||||
def.wield_image = def.tiles[1]
|
||||
def.inventory_image = def.tiles[1]
|
||||
end
|
||||
|
||||
if railparams then
|
||||
carts.railparams[name] = table.copy(railparams)
|
||||
end
|
||||
|
||||
minetest.register_node(name, def)
|
||||
end
|
||||
|
||||
function carts:get_rail_groups(additional_groups)
|
||||
-- Get the default rail groups and add more when a table is given
|
||||
local groups = {
|
||||
dig_immediate = 2,
|
||||
attached_node = 1,
|
||||
rail = 1,
|
||||
connect_to_raillike = minetest.raillike_group("rail")
|
||||
}
|
||||
if type(additional_groups) == "table" then
|
||||
for k, v in pairs(additional_groups) do
|
||||
groups[k] = v
|
||||
end
|
||||
end
|
||||
return groups
|
||||
end
|
16
mods/carts/init.lua
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
carts = {}
|
||||
carts.modpath = minetest.get_modpath("carts")
|
||||
carts.railparams = {}
|
||||
|
||||
-- Maximal speed of the cart in m/s (min = -1)
|
||||
carts.speed_max = 7
|
||||
-- Set to -1 to disable punching the cart from inside (min = -1)
|
||||
carts.punch_speed_max = 5
|
||||
-- Maximal distance for the path correction (for dtime peaks)
|
||||
carts.path_distance_max = 3
|
||||
|
||||
|
||||
dofile(carts.modpath.."/functions.lua")
|
||||
dofile(carts.modpath.."/rails.lua")
|
||||
dofile(carts.modpath.."/cart_entity.lua")
|
54
mods/carts/license.txt
Normal file
@ -0,0 +1,54 @@
|
||||
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (C) 2012-2016 PilzAdam
|
||||
Copyright (C) 2014-2016 SmallJoker
|
||||
Copyright (C) 2012-2016 Various Minetest developers and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
Licenses of media
|
||||
-----------------
|
||||
|
||||
CC-0, see: https://creativecommons.org/share-your-work/public-domain/cc0/, except
|
||||
if other license is mentioned.
|
||||
|
||||
|
||||
Authors
|
||||
---------
|
||||
Originally from PixelBOX (Gambit):
|
||||
carts_cart_side.png
|
||||
carts_cart_top.png
|
||||
carts_cart_front.png*
|
||||
carts_cart.png*
|
||||
|
||||
sofar + stujones11:
|
||||
carts_cart.b3d and carts_cart.blend
|
||||
|
||||
hexafraction, modified by sofar
|
||||
carts_rail_*.png
|
||||
|
||||
http://www.freesound.org/people/YleArkisto/sounds/253159/ - YleArkisto - CC-BY-3.0
|
||||
carts_cart_moving.*.ogg
|
BIN
mods/carts/models/carts_cart.b3d
Normal file
BIN
mods/carts/models/carts_cart.blend
Normal file
59
mods/carts/rails.lua
Normal file
@ -0,0 +1,59 @@
|
||||
carts:register_rail("carts:rail", {
|
||||
description = "Rail",
|
||||
tiles = {
|
||||
"carts_rail_straight.png", "carts_rail_curved.png",
|
||||
"carts_rail_t_junction.png", "carts_rail_crossing.png"
|
||||
},
|
||||
inventory_image = "carts_rail_straight.png",
|
||||
wield_image = "carts_rail_straight.png",
|
||||
groups = carts:get_rail_groups(),
|
||||
}, {})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "carts:rail 18",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_alias("default:rail", "carts:rail")
|
||||
|
||||
|
||||
carts:register_rail("carts:powerrail", {
|
||||
description = "Powered Rail",
|
||||
tiles = {
|
||||
"carts_rail_straight_pwr.png", "carts_rail_curved_pwr.png",
|
||||
"carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"
|
||||
},
|
||||
groups = carts:get_rail_groups(),
|
||||
}, {acceleration = 5})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "carts:powerrail 18",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
carts:register_rail("carts:brakerail", {
|
||||
description = "Brake Rail",
|
||||
tiles = {
|
||||
"carts_rail_straight_brk.png", "carts_rail_curved_brk.png",
|
||||
"carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png"
|
||||
},
|
||||
groups = carts:get_rail_groups(),
|
||||
}, {acceleration = -3})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "carts:brakerail 18",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:coal_lump", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
|
||||
}
|
||||
})
|
BIN
mods/carts/sounds/carts_cart_moving.1.ogg
Normal file
BIN
mods/carts/sounds/carts_cart_moving.2.ogg
Normal file
BIN
mods/carts/sounds/carts_cart_moving.3.ogg
Normal file
BIN
mods/carts/textures/carts_cart.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
mods/carts/textures/carts_cart_front.png
Normal file
After Width: | Height: | Size: 459 B |
BIN
mods/carts/textures/carts_cart_side.png
Normal file
After Width: | Height: | Size: 486 B |
BIN
mods/carts/textures/carts_cart_top.png
Normal file
After Width: | Height: | Size: 522 B |
BIN
mods/carts/textures/carts_rail_crossing.png
Normal file
After Width: | Height: | Size: 612 B |
BIN
mods/carts/textures/carts_rail_crossing_brk.png
Normal file
After Width: | Height: | Size: 684 B |
BIN
mods/carts/textures/carts_rail_crossing_pwr.png
Normal file
After Width: | Height: | Size: 676 B |
BIN
mods/carts/textures/carts_rail_curved.png
Normal file
After Width: | Height: | Size: 580 B |
BIN
mods/carts/textures/carts_rail_curved_brk.png
Normal file
After Width: | Height: | Size: 618 B |
BIN
mods/carts/textures/carts_rail_curved_pwr.png
Normal file
After Width: | Height: | Size: 614 B |
BIN
mods/carts/textures/carts_rail_straight.png
Normal file
After Width: | Height: | Size: 602 B |
BIN
mods/carts/textures/carts_rail_straight_brk.png
Normal file
After Width: | Height: | Size: 660 B |
BIN
mods/carts/textures/carts_rail_straight_pwr.png
Normal file
After Width: | Height: | Size: 661 B |
BIN
mods/carts/textures/carts_rail_t_junction.png
Normal file
After Width: | Height: | Size: 707 B |
BIN
mods/carts/textures/carts_rail_t_junction_brk.png
Normal file
After Width: | Height: | Size: 698 B |
BIN
mods/carts/textures/carts_rail_t_junction_pwr.png
Normal file
After Width: | Height: | Size: 697 B |
@ -1,22 +1,17 @@
|
||||
Minetest 0.4 mod: creative
|
||||
==========================
|
||||
Minetest Game mod: creative
|
||||
===========================
|
||||
See license.txt for license information.
|
||||
|
||||
Implements creative mode.
|
||||
|
||||
Switch on by using the "creative_mode" setting.
|
||||
|
||||
Registered items that
|
||||
- have a description, and
|
||||
- do not have the group not_in_creative_inventory
|
||||
are added to the creative inventory.
|
||||
|
||||
License of source code and media files:
|
||||
---------------------------------------
|
||||
Copyright (C) 2012 Perttu Ahola (celeron55) <celeron55@gmail.com>
|
||||
|
||||
This program is free software. It comes without any warranty, to
|
||||
the extent permitted by applicable law. You can redistribute it
|
||||
and/or modify it under the terms of the Do What The Fuck You Want
|
||||
To Public License, Version 2, as published by Sam Hocevar. See
|
||||
http://sam.zoy.org/wtfpl/COPYING for more details.
|
||||
Authors of source code
|
||||
----------------------
|
||||
Originally by Perttu Ahola (celeron55) <celeron55@gmail.com> (MIT)
|
||||
Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com> (MIT)
|
||||
|
||||
Author of media (textures)
|
||||
--------------------------
|
||||
paramat (CC BY-SA 3.0):
|
||||
* creative_prev_icon.png
|
||||
* creative_next_icon.png
|
||||
* creative_search_icon.png
|
||||
* creative_clear_icon.png
|
||||
* creative_trash_icon.png derived from a texture by kilbith (CC BY-SA 3.0)
|
||||
|
@ -1 +1,2 @@
|
||||
default
|
||||
sfinv
|
||||
|
@ -1,177 +1,85 @@
|
||||
-- minetest/creative/init.lua
|
||||
creative = {}
|
||||
|
||||
creative_inventory = {}
|
||||
creative_inventory.creative_inventory_size = 0
|
||||
|
||||
-- Create detached creative inventory after loading all mods
|
||||
minetest.after(0, function()
|
||||
local inv = minetest.create_detached_inventory("creative", {
|
||||
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
if minetest.setting_getbool("creative_mode") then
|
||||
return count
|
||||
local function update_sfinv(name)
|
||||
minetest.after(0, function()
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
if sfinv.get_page(player):sub(1, 9) == "creative:" then
|
||||
sfinv.set_page(player, sfinv.get_homepage_name(player))
|
||||
else
|
||||
return 0
|
||||
sfinv.set_player_inventory_formspec(player)
|
||||
end
|
||||
end,
|
||||
allow_put = function(inv, listname, index, stack, player)
|
||||
return 0
|
||||
end,
|
||||
allow_take = function(inv, listname, index, stack, player)
|
||||
if minetest.setting_getbool("creative_mode") then
|
||||
return -1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
end,
|
||||
on_put = function(inv, listname, index, stack, player)
|
||||
end,
|
||||
on_take = function(inv, listname, index, stack, player)
|
||||
--print(player:get_player_name().." takes item from creative inventory; listname="..dump(listname)..", index="..dump(index)..", stack="..dump(stack))
|
||||
if stack then
|
||||
minetest.log("action", player:get_player_name().." takes "..dump(stack:get_name()).." from creative inventory")
|
||||
--print("stack:get_name()="..dump(stack:get_name())..", stack:get_count()="..dump(stack:get_count()))
|
||||
end
|
||||
end,
|
||||
})
|
||||
local creative_list = {}
|
||||
for name,def in pairs(minetest.registered_items) do
|
||||
if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0)
|
||||
and def.description and def.description ~= "" then
|
||||
table.insert(creative_list, name)
|
||||
end
|
||||
end
|
||||
table.sort(creative_list)
|
||||
inv:set_size("main", #creative_list)
|
||||
for _,itemstring in ipairs(creative_list) do
|
||||
inv:add_item("main", ItemStack(itemstring))
|
||||
end
|
||||
creative_inventory.creative_inventory_size = #creative_list
|
||||
--print("creative inventory size: "..dump(creative_inventory.creative_inventory_size))
|
||||
end)
|
||||
|
||||
-- Create the trash field
|
||||
local trash = minetest.create_detached_inventory("creative_trash", {
|
||||
-- Allow the stack to be placed and remove it in on_put()
|
||||
-- This allows the creative inventory to restore the stack
|
||||
allow_put = function(inv, listname, index, stack, player)
|
||||
if minetest.setting_getbool("creative_mode") then
|
||||
return stack:get_count()
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end,
|
||||
on_put = function(inv, listname, index, stack, player)
|
||||
inv:set_stack(listname, index, "")
|
||||
end,
|
||||
})
|
||||
trash:set_size("main", 1)
|
||||
|
||||
|
||||
creative_inventory.set_creative_formspec = function(player, start_i, pagenum)
|
||||
pagenum = math.floor(pagenum)
|
||||
local pagemax = math.floor((creative_inventory.creative_inventory_size-1) / (6*4) + 1)
|
||||
player:set_inventory_formspec(
|
||||
"size[13,7.5]"..
|
||||
--"image[6,0.6;1,2;player.png]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[current_player;main;5,3.5;8,1;]"..
|
||||
"list[current_player;main;5,4.75;8,3;8]"..
|
||||
"list[current_player;craft;8,0;3,3;]"..
|
||||
"list[current_player;craftpreview;12,1;1,1;]"..
|
||||
"image[11,1;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
|
||||
"list[detached:creative;main;0.3,0.5;4,6;"..tostring(start_i).."]"..
|
||||
"label[2.0,6.55;"..tostring(pagenum).."/"..tostring(pagemax).."]"..
|
||||
"button[0.3,6.5;1.6,1;creative_prev;<<]"..
|
||||
"button[2.7,6.5;1.6,1;creative_next;>>]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[current_player;craft]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[detached:creative;main]"..
|
||||
"label[5,1.5;Trash:]"..
|
||||
"list[detached:creative_trash;main;5,2;1,1;]"..
|
||||
default.get_hotbar_bg(5,3.5)
|
||||
)
|
||||
end)
|
||||
end
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
-- If in creative mode, modify player's inventory forms
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
return
|
||||
end
|
||||
creative_inventory.set_creative_formspec(player, 0, 1)
|
||||
end)
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
return
|
||||
end
|
||||
-- Figure out current page from formspec
|
||||
local current_page = 0
|
||||
local formspec = player:get_inventory_formspec()
|
||||
local start_i = string.match(formspec, "list%[detached:creative;main;[%d.]+,[%d.]+;[%d.]+,[%d.]+;(%d+)%]")
|
||||
start_i = tonumber(start_i) or 0
|
||||
|
||||
if fields.creative_prev then
|
||||
start_i = start_i - 4*6
|
||||
end
|
||||
if fields.creative_next then
|
||||
start_i = start_i + 4*6
|
||||
end
|
||||
minetest.register_privilege("creative", {
|
||||
description = "Allow player to use creative inventory",
|
||||
give_to_singleplayer = false,
|
||||
give_to_admin = false,
|
||||
on_grant = update_sfinv,
|
||||
on_revoke = update_sfinv,
|
||||
})
|
||||
|
||||
if start_i < 0 then
|
||||
start_i = start_i + 4*6
|
||||
end
|
||||
if start_i >= creative_inventory.creative_inventory_size then
|
||||
start_i = start_i - 4*6
|
||||
end
|
||||
local creative_mode_cache = minetest.settings:get_bool("creative_mode")
|
||||
|
||||
if start_i < 0 or start_i >= creative_inventory.creative_inventory_size then
|
||||
start_i = 0
|
||||
end
|
||||
function creative.is_enabled_for(name)
|
||||
return creative_mode_cache or
|
||||
minetest.check_player_privs(name, {creative = true})
|
||||
end
|
||||
|
||||
creative_inventory.set_creative_formspec(player, start_i, start_i / (6*4) + 1)
|
||||
end)
|
||||
dofile(minetest.get_modpath("creative") .. "/inventory.lua")
|
||||
|
||||
if creative_mode_cache then
|
||||
-- Dig time is modified according to difference (leveldiff) between tool
|
||||
-- 'maxlevel' and node 'level'. Digtime is divided by the larger of
|
||||
-- leveldiff and 1.
|
||||
-- To speed up digging in creative, hand 'maxlevel' and 'digtime' have been
|
||||
-- increased such that nodes of differing levels have an insignificant
|
||||
-- effect on digtime.
|
||||
local digtime = 42
|
||||
local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256}
|
||||
|
||||
if minetest.setting_getbool("creative_mode") then
|
||||
local digtime = 0.5
|
||||
minetest.register_item(":", {
|
||||
type = "none",
|
||||
wield_image = "wieldhand.png",
|
||||
wield_scale = {x=1,y=1,z=2.5},
|
||||
wield_scale = {x = 1, y = 1, z = 2.5},
|
||||
range = 10,
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.5,
|
||||
max_drop_level = 3,
|
||||
groupcaps = {
|
||||
crumbly = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3},
|
||||
cracky = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3},
|
||||
snappy = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3},
|
||||
choppy = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3},
|
||||
oddly_breakable_by_hand = {times={[1]=digtime, [2]=digtime, [3]=digtime}, uses=0, maxlevel=3},
|
||||
crumbly = caps,
|
||||
cracky = caps,
|
||||
snappy = caps,
|
||||
choppy = caps,
|
||||
oddly_breakable_by_hand = caps,
|
||||
},
|
||||
damage_groups = {fleshy = 10},
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
|
||||
return true
|
||||
end)
|
||||
-- Unlimited node placement
|
||||
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
|
||||
if placer and placer:is_player() then
|
||||
return creative.is_enabled_for(placer:get_player_name())
|
||||
end
|
||||
end)
|
||||
|
||||
function minetest.handle_node_drops(pos, drops, digger)
|
||||
if not digger or not digger:is_player() then
|
||||
return
|
||||
end
|
||||
local inv = digger:get_inventory()
|
||||
if inv then
|
||||
for _,item in ipairs(drops) do
|
||||
item = ItemStack(item):get_name()
|
||||
if not inv:contains_item("main", item) then
|
||||
inv:add_item("main", item)
|
||||
end
|
||||
-- Don't pick up if the item is already in the inventory
|
||||
local old_handle_node_drops = minetest.handle_node_drops
|
||||
function minetest.handle_node_drops(pos, drops, digger)
|
||||
if not digger or not digger:is_player() or
|
||||
not creative.is_enabled_for(digger:get_player_name()) then
|
||||
return old_handle_node_drops(pos, drops, digger)
|
||||
end
|
||||
local inv = digger:get_inventory()
|
||||
if inv then
|
||||
for _, item in ipairs(drops) do
|
||||
if not inv:contains_item("main", item, true) then
|
||||
inv:add_item("main", item)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
191
mods/creative/inventory.lua
Normal file
@ -0,0 +1,191 @@
|
||||
local player_inventory = {}
|
||||
local inventory_cache = {}
|
||||
|
||||
local function init_creative_cache(items)
|
||||
inventory_cache[items] = {}
|
||||
local i_cache = inventory_cache[items]
|
||||
|
||||
for name, def in pairs(items) do
|
||||
if def.groups.not_in_creative_inventory ~= 1 and
|
||||
def.description and def.description ~= "" then
|
||||
i_cache[name] = def
|
||||
end
|
||||
end
|
||||
table.sort(i_cache)
|
||||
return i_cache
|
||||
end
|
||||
|
||||
function creative.init_creative_inventory(player)
|
||||
local player_name = player:get_player_name()
|
||||
player_inventory[player_name] = {
|
||||
size = 0,
|
||||
filter = "",
|
||||
start_i = 0
|
||||
}
|
||||
|
||||
minetest.create_detached_inventory("creative_" .. player_name, {
|
||||
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
|
||||
local name = player2 and player2:get_player_name() or ""
|
||||
if not creative.is_enabled_for(name) or
|
||||
to_list == "main" then
|
||||
return 0
|
||||
end
|
||||
return count
|
||||
end,
|
||||
allow_put = function(inv, listname, index, stack, player2)
|
||||
return 0
|
||||
end,
|
||||
allow_take = function(inv, listname, index, stack, player2)
|
||||
local name = player2 and player2:get_player_name() or ""
|
||||
if not creative.is_enabled_for(name) then
|
||||
return 0
|
||||
end
|
||||
return -1
|
||||
end,
|
||||
on_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
|
||||
end,
|
||||
on_take = function(inv, listname, index, stack, player2)
|
||||
if stack and stack:get_count() > 0 then
|
||||
minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory")
|
||||
end
|
||||
end,
|
||||
}, player_name)
|
||||
|
||||
return player_inventory[player_name]
|
||||
end
|
||||
|
||||
function creative.update_creative_inventory(player_name, tab_content)
|
||||
local creative_list = {}
|
||||
local inv = player_inventory[player_name] or
|
||||
creative.init_creative_inventory(minetest.get_player_by_name(player_name))
|
||||
local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name})
|
||||
|
||||
local items = inventory_cache[tab_content] or init_creative_cache(tab_content)
|
||||
|
||||
for name, def in pairs(items) do
|
||||
if def.name:find(inv.filter, 1, true) or
|
||||
def.description:lower():find(inv.filter, 1, true) then
|
||||
creative_list[#creative_list+1] = name
|
||||
end
|
||||
end
|
||||
|
||||
table.sort(creative_list)
|
||||
player_inv:set_size("main", #creative_list)
|
||||
player_inv:set_list("main", creative_list)
|
||||
inv.size = #creative_list
|
||||
end
|
||||
|
||||
-- Create the trash field
|
||||
local trash = minetest.create_detached_inventory("creative_trash", {
|
||||
-- Allow the stack to be placed and remove it in on_put()
|
||||
-- This allows the creative inventory to restore the stack
|
||||
allow_put = function(inv, listname, index, stack, player)
|
||||
return stack:get_count()
|
||||
end,
|
||||
on_put = function(inv, listname)
|
||||
inv:set_list(listname, {})
|
||||
end,
|
||||
})
|
||||
trash:set_size("main", 1)
|
||||
|
||||
creative.formspec_add = ""
|
||||
|
||||
function creative.register_tab(name, title, items)
|
||||
sfinv.register_page("creative:" .. name, {
|
||||
title = title,
|
||||
is_in_nav = function(self, player, context)
|
||||
return creative.is_enabled_for(player:get_player_name())
|
||||
end,
|
||||
get = function(self, player, context)
|
||||
local player_name = player:get_player_name()
|
||||
creative.update_creative_inventory(player_name, items)
|
||||
local inv = player_inventory[player_name]
|
||||
local start_i = inv.start_i or 0
|
||||
local pagenum = math.floor(start_i / (3*8) + 1)
|
||||
local pagemax = math.ceil(inv.size / (3*8))
|
||||
return sfinv.make_formspec(player, context,
|
||||
"label[6.2,3.35;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" ..
|
||||
[[
|
||||
image[4.06,3.4;0.8,0.8;creative_trash_icon.png]
|
||||
listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]
|
||||
list[current_player;main;0,4.7;8,1;]
|
||||
list[current_player;main;0,5.85;8,3;8]
|
||||
list[detached:creative_trash;main;4,3.3;1,1;]
|
||||
listring[]
|
||||
image_button[5.4,3.25;0.8,0.8;creative_prev_icon.png;creative_prev;]
|
||||
image_button[7.2,3.25;0.8,0.8;creative_next_icon.png;creative_next;]
|
||||
image_button[2.1,3.25;0.8,0.8;creative_search_icon.png;creative_search;]
|
||||
image_button[2.75,3.25;0.8,0.8;creative_clear_icon.png;creative_clear;]
|
||||
tooltip[creative_search;Search]
|
||||
tooltip[creative_clear;Reset]
|
||||
tooltip[creative_prev;Previous page]
|
||||
tooltip[creative_next;Next page]
|
||||
listring[current_player;main]
|
||||
field_close_on_enter[creative_filter;false]
|
||||
]] ..
|
||||
"field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" ..
|
||||
"listring[detached:creative_" .. player_name .. ";main]" ..
|
||||
"list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" ..
|
||||
default.get_hotbar_bg(0,4.7) .. creative.formspec_add, false)
|
||||
end,
|
||||
on_enter = function(self, player, context)
|
||||
local player_name = player:get_player_name()
|
||||
local inv = player_inventory[player_name]
|
||||
if inv then
|
||||
inv.start_i = 0
|
||||
end
|
||||
end,
|
||||
on_player_receive_fields = function(self, player, context, fields)
|
||||
local player_name = player:get_player_name()
|
||||
local inv = player_inventory[player_name]
|
||||
assert(inv)
|
||||
|
||||
if fields.creative_clear then
|
||||
inv.start_i = 0
|
||||
inv.filter = ""
|
||||
creative.update_creative_inventory(player_name, items)
|
||||
sfinv.set_player_inventory_formspec(player, context)
|
||||
elseif fields.creative_search or
|
||||
fields.key_enter_field == "creative_filter" then
|
||||
inv.start_i = 0
|
||||
inv.filter = fields.creative_filter:lower()
|
||||
creative.update_creative_inventory(player_name, items)
|
||||
sfinv.set_player_inventory_formspec(player, context)
|
||||
elseif not fields.quit then
|
||||
local start_i = inv.start_i or 0
|
||||
|
||||
if fields.creative_prev then
|
||||
start_i = start_i - 3*8
|
||||
if start_i < 0 then
|
||||
start_i = inv.size - (inv.size % (3*8))
|
||||
if inv.size == start_i then
|
||||
start_i = math.max(0, inv.size - (3*8))
|
||||
end
|
||||
end
|
||||
elseif fields.creative_next then
|
||||
start_i = start_i + 3*8
|
||||
if start_i >= inv.size then
|
||||
start_i = 0
|
||||
end
|
||||
end
|
||||
|
||||
inv.start_i = start_i
|
||||
sfinv.set_player_inventory_formspec(player, context)
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
creative.register_tab("all", "All", minetest.registered_items)
|
||||
creative.register_tab("nodes", "Nodes", minetest.registered_nodes)
|
||||
creative.register_tab("tools", "Tools", minetest.registered_tools)
|
||||
creative.register_tab("craftitems", "Items", minetest.registered_craftitems)
|
||||
|
||||
local old_homepage_name = sfinv.get_homepage_name
|
||||
function sfinv.get_homepage_name(player)
|
||||
if creative.is_enabled_for(player:get_player_name()) then
|
||||
return "creative:all"
|
||||
else
|
||||
return old_homepage_name(player)
|
||||
end
|
||||
end
|
61
mods/creative/license.txt
Normal file
@ -0,0 +1,61 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (C) 2012-2016 Perttu Ahola (celeron55) <celeron55@gmail.com>
|
||||
Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
Licenses of media (textures)
|
||||
----------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2016 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com>
|
||||
Copyright (C) 2018 paramat
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
BIN
mods/creative/textures/creative_clear_icon.png
Normal file
After Width: | Height: | Size: 708 B |
BIN
mods/creative/textures/creative_next_icon.png
Normal file
After Width: | Height: | Size: 727 B |
BIN
mods/creative/textures/creative_prev_icon.png
Normal file
After Width: | Height: | Size: 728 B |
BIN
mods/creative/textures/creative_search_icon.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
mods/creative/textures/creative_trash_icon.png
Normal file
After Width: | Height: | Size: 712 B |
@ -1,139 +1,143 @@
|
||||
Minetest 0.4 mod: default
|
||||
Minetest Game mod: default
|
||||
==========================
|
||||
See license.txt for license information.
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
Copyright (C) 2011-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
Authors of source code
|
||||
----------------------
|
||||
Originally by celeron55, Perttu Ahola <celeron55@gmail.com> (LGPLv2.1+)
|
||||
Various Minetest developers and contributors (LGPLv2.1+)
|
||||
|
||||
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.
|
||||
The torch code was derived by sofar from the 'torches' mod by
|
||||
BlockMen (LGPLv2.1+)
|
||||
|
||||
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
Authors of media files
|
||||
-----------------------
|
||||
Authors of media (textures, sounds, models and schematics)
|
||||
----------------------------------------------------------
|
||||
Everything not listed in here:
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
celeron55, Perttu Ahola <celeron55@gmail.com> (CC BY-SA 3.0)
|
||||
|
||||
Cisoun's WTFPL texture pack:
|
||||
|
||||
Textures
|
||||
--------
|
||||
Cisoun's texture pack (CC BY-SA 3.0):
|
||||
default_jungletree.png
|
||||
default_lava.png
|
||||
default_leaves.png
|
||||
default_sapling.png
|
||||
default_sign_wall.png
|
||||
default_bush_sapling.png
|
||||
default_stone.png
|
||||
default_tree.png
|
||||
default_tree_top.png
|
||||
default_water.png
|
||||
|
||||
Cisoun's conifers mod (WTFPL):
|
||||
default_pine_needles.png
|
||||
RealBadAngel's animated water (CC BY-SA 3.0):
|
||||
default_water_source_animated.png
|
||||
default_water_flowing_animated.png
|
||||
|
||||
Originating from G4JC's Almost MC Texture Pack:
|
||||
default_torch.png
|
||||
default_torch_on_ceiling.png
|
||||
default_torch_on_floor.png
|
||||
|
||||
VanessaE's animated torches (WTFPL):
|
||||
VanessaE (CC BY-SA 3.0):
|
||||
default_torch_animated.png
|
||||
default_torch_on_ceiling_animated.png
|
||||
default_torch_on_floor_animated.png
|
||||
default_torch_on_floor.png
|
||||
|
||||
RealBadAngel's animated water (WTFPL):
|
||||
default_water_source_animated.png
|
||||
default_water_flowing_animated.png
|
||||
|
||||
VanessaE (WTFPL):
|
||||
default_nc_back.png
|
||||
default_nc_front.png
|
||||
default_nc_rb.png
|
||||
default_nc_side.png
|
||||
default_desert_sand.png
|
||||
default_desert_stone.png
|
||||
default_sand.png
|
||||
default_jungletree_top.png
|
||||
default_mese_crystal.png
|
||||
default_mese_crystal_fragment.png
|
||||
|
||||
Calinou (CC BY-SA):
|
||||
Calinou (CC BY-SA 3.0):
|
||||
default_brick.png
|
||||
default_papyrus.png
|
||||
default_mineral_copper.png
|
||||
default_glass_detail.png
|
||||
|
||||
MirceaKitsune (WTFPL):
|
||||
character.x
|
||||
|
||||
Jordach (CC BY-SA 3.0):
|
||||
character.png
|
||||
|
||||
PilzAdam (WTFPL):
|
||||
PilzAdam (CC BY-SA 3.0):
|
||||
default_jungleleaves.png
|
||||
default_junglesapling.png
|
||||
default_obsidian_glass.png
|
||||
default_obsidian_shard.png
|
||||
default_mineral_gold.png
|
||||
default_snowball.png
|
||||
|
||||
jojoa1997 (WTFPL):
|
||||
jojoa1997 (CC BY-SA 3.0):
|
||||
default_obsidian.png
|
||||
|
||||
InfinityProject (WTFPL):
|
||||
InfinityProject (CC BY-SA 3.0):
|
||||
default_mineral_diamond.png
|
||||
|
||||
Splizard (CC BY-SA 3.0):
|
||||
default_snow.png
|
||||
default_snow_side.png
|
||||
default_pine_sapling.png
|
||||
default_pine_needles.png
|
||||
|
||||
Zeg9 (CC BY-SA 3.0):
|
||||
default_coal_block.png
|
||||
default_steel_block.png
|
||||
default_copper_block.png
|
||||
default_bronze_block.png
|
||||
default_gold_block.png
|
||||
|
||||
paramat (CC BY-SA 3.0):
|
||||
wieldhand.png, derived from character.png by Jordach (CC BY-SA 3.0)
|
||||
wieldhand.png -- Copied from character.png by Jordach (CC BY-SA 3.0)
|
||||
default_pinetree.png
|
||||
default_pinetree_top.png
|
||||
default_pinewood.png
|
||||
default_sandstone_brick.png
|
||||
default_obsidian_brick.png
|
||||
default_river_water.png
|
||||
default_river_water_source_animated.png
|
||||
default_river_water_flowing_animated.png
|
||||
default_acacia_leaves.png
|
||||
default_acacia_leaves_simple.png
|
||||
default_acacia_sapling.png
|
||||
default_acacia_bush_sapling.png
|
||||
default_pine_bush_sapling.png
|
||||
default_acacia_tree.png
|
||||
default_acacia_tree_top.png
|
||||
default_acacia_wood.png
|
||||
default_acacia_bush_stem.png
|
||||
default_bush_stem.png
|
||||
default_pine_bush_stem.png
|
||||
default_junglewood.png
|
||||
default_jungletree_top.png
|
||||
default_sandstone_brick.png
|
||||
default_obsidian_brick.png
|
||||
default_stone_brick.png
|
||||
default_desert_stone_brick.png
|
||||
default_sandstone_block.png
|
||||
default_obsidian_block.png
|
||||
default_stone_block.png
|
||||
default_desert_stone_block.png
|
||||
default_river_water.png
|
||||
default_river_water_source_animated.png
|
||||
default_river_water_flowing_animated.png
|
||||
default_dry_grass.png
|
||||
default_dry_grass_side.png
|
||||
default_dry_grass_*.png
|
||||
default_junglewood.png, derived from a texture by BlockMen (CC BY-SA 3.0)
|
||||
default_grass.png, derived from a texture by Philipbenr (CC BY-SA 3.0)
|
||||
default_grass_side.png, derived from a texture by Philipbenr (CC BY-SA 3.0)
|
||||
default_stone_brick.png, derived from a texture by Cisoun (WTFPL)
|
||||
default_desert_stone_brick.png, derived from a texture by VanessaE (WTFPL)
|
||||
default_grass.png
|
||||
default_grass_side.png
|
||||
default_mese_block.png
|
||||
default_silver_sand.png
|
||||
default_mese_post_light_side.png
|
||||
default_mese_post_light_side_dark.png
|
||||
default_mese_post_light_top.png
|
||||
default_silver_sandstone.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0)
|
||||
default_silver_sandstone_brick.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0)
|
||||
default_silver_sandstone_block.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0)
|
||||
default_bookshelf_slot.png -- Derived from a texture by Gambit (CC-BY-SA 3.0)
|
||||
default_marram_grass_*.png -- Derived from textures by TumeniNodes (CC-BY-SA 3.0)
|
||||
default_emergent_jungle_sapling.png
|
||||
default_permafrost.png -- Derived from a texture by Neuromancer (CC BY-SA 3.0)
|
||||
default_stones.png -- Derived from a texture by sofar (CC0 1.0)
|
||||
default_stones_side.png -- Derived from a texture by sofar (CC0 1.0)
|
||||
default_moss.png
|
||||
default_moss_side.png
|
||||
default_fence_rail_acacia_wood
|
||||
default_fence_rail_aspen_wood -- Derived from a texture by sofar (CC BY-SA 3.0)
|
||||
default_fence_rail_junglewood
|
||||
default_fence_rail_pine_wood
|
||||
default_fence_rail_wood -- Derived from a texture by BlockMen (CC BY-SA 3.0)
|
||||
|
||||
brunob.santos (CC BY-SA 4.0):
|
||||
default_desert_cobble.png
|
||||
TumeniNodes (CC BY-SA 3.0):
|
||||
default_desert_cobble.png -- Derived from a texture by brunob.santos (CC BY-SA 3.0)
|
||||
default_coniferous_litter.png
|
||||
default_coniferous_litter_side.png
|
||||
|
||||
BlockMen (CC BY-SA 3.0):
|
||||
default_aspen_leaves.png -- Derived from Sofar's texture
|
||||
default_wood.png
|
||||
default_clay_brick.png
|
||||
default_iron_ingot.png
|
||||
default_gold_ingot.png
|
||||
default_tool_steelsword.png
|
||||
default_diamond.png
|
||||
default_book.png
|
||||
default_tool_*.png
|
||||
default_lava_source_animated.png
|
||||
default_lava_flowing_animated.png
|
||||
@ -145,17 +149,24 @@ BlockMen (CC BY-SA 3.0):
|
||||
default_mineral_mese.png
|
||||
default_meselamp.png
|
||||
bubble.png
|
||||
heart.png
|
||||
gui_*.png
|
||||
|
||||
Neuromancer (CC BY-SA 2.0):
|
||||
sofar (CC BY-SA 3.0):
|
||||
default_aspen_sapling
|
||||
default_aspen_tree
|
||||
default_aspen_tree_top, derived from default_pine_tree_top (by paramat)
|
||||
default_aspen_wood, derived from default_pine_wood (by paramat)
|
||||
default_chest_inside
|
||||
|
||||
sofar (CC0 1.0):
|
||||
default_gravel.png -- Derived from Gambit's PixelBOX texture pack light gravel
|
||||
|
||||
Neuromancer (CC BY-SA 3.0):
|
||||
default_cobble.png, based on texture by Brane praefect
|
||||
default_mossycobble.png, based on texture by Brane praefect
|
||||
Neuromancer (CC BY-SA 3.0):
|
||||
default_dirt.png
|
||||
default_furnace_*.png
|
||||
|
||||
Gambit (WTFPL):
|
||||
Gambit (CC BY-SA 3.0):
|
||||
default_bronze_ingot.png
|
||||
default_copper_ingot.png
|
||||
default_copper_lump.png
|
||||
@ -166,16 +177,86 @@ Gambit (WTFPL):
|
||||
default_grass_*.png
|
||||
default_paper.png
|
||||
default_diamond_block.png
|
||||
default_ladder_steel.png
|
||||
default_sign_wall_wood.png
|
||||
default_flint.png
|
||||
default_snow.png
|
||||
default_snow_side.png
|
||||
default_snowball.png
|
||||
default_key.png
|
||||
default_key_skeleton.png
|
||||
default_book.png
|
||||
|
||||
asl97 (WTFPL):
|
||||
asl97 (CC BY-SA 3.0):
|
||||
default_ice.png
|
||||
|
||||
KevDoy (CC BY-SA 3.0):
|
||||
heart.png
|
||||
|
||||
Pithydon (CC BY-SA 3.0)
|
||||
default_coral_brown.png
|
||||
default_coral_orange.png
|
||||
default_coral_skeleton.png
|
||||
|
||||
Ferk (CC0 1.0):
|
||||
default_item_smoke.png
|
||||
|
||||
npx (CC BY-SA 3.0):
|
||||
default_rainforest_litter.png
|
||||
default_rainforest_litter_side.png
|
||||
|
||||
kaeza (CC-BY-SA 3.0):
|
||||
default_desert_sandstone.png
|
||||
default_desert_sandstone_brick.png
|
||||
default_desert_sandstone_block.png
|
||||
|
||||
kilbith (CC BY-SA 3.0):
|
||||
default_steel_block.png
|
||||
default_copper_block.png
|
||||
default_bronze_block.png
|
||||
default_gold_block.png
|
||||
default_tin_block.png
|
||||
default_mineral_tin.png
|
||||
default_tin_ingot.png
|
||||
default_tin_lump.png
|
||||
|
||||
tobyplowy (CC BY-SA 3.0):
|
||||
default_kelp.png
|
||||
|
||||
CloudyProton (CC BY-SA 3.0):
|
||||
default_book_written.png, based on default_book.png by Gambit
|
||||
|
||||
Mossmanikin (CC BY-SA 3.0):
|
||||
default_fern_*.png
|
||||
|
||||
random-geek (CC BY-SA 3.0):
|
||||
default_blueberries.png
|
||||
default_blueberry_overlay.png
|
||||
default_blueberry_bush_leaves.png, derived from default_bush_leaves (by paramat)
|
||||
default_blueberry_bush_sapling.png
|
||||
default_dirt.png -- Derived from a texture by Neuromancer (CC BY-SA 3.0)
|
||||
|
||||
Krock (CC0 1.0):
|
||||
default_glass.png
|
||||
default_glass_detail.png
|
||||
|
||||
Topywo (CC BY-SA 3.0)
|
||||
default_coral_cyan.png
|
||||
default_coral_green.png
|
||||
default_coral_pink.png
|
||||
|
||||
Extex101 (CC BY-SA 3.0)
|
||||
default_large_cactus_seedling.png
|
||||
|
||||
|
||||
Sounds
|
||||
------
|
||||
Glass breaking sounds (CC BY 3.0):
|
||||
1: http://www.freesound.org/people/cmusounddesign/sounds/71947/
|
||||
2: http://www.freesound.org/people/Tomlija/sounds/97669/
|
||||
3: http://www.freesound.org/people/lsprice/sounds/88808/
|
||||
|
||||
Mito551 (sounds) (CC BY-SA):
|
||||
Mito551 (sounds) (CC BY-SA 3.0):
|
||||
default_dig_choppy.ogg
|
||||
default_dig_cracky.ogg
|
||||
default_dig_crumbly.1.ogg
|
||||
@ -197,8 +278,6 @@ Mito551 (sounds) (CC BY-SA):
|
||||
default_place_node.3.ogg
|
||||
default_place_node_hard.1.ogg
|
||||
default_place_node_hard.2.ogg
|
||||
default_snow_footstep.1.ogg
|
||||
default_snow_footstep.2.ogg
|
||||
default_hard_footstep.1.ogg
|
||||
default_hard_footstep.2.ogg
|
||||
default_hard_footstep.3.ogg
|
||||
@ -209,3 +288,90 @@ Mito551 (sounds) (CC BY-SA):
|
||||
default_dirt_footstep.1.ogg
|
||||
default_dirt_footstep.2.ogg
|
||||
default_glass_footstep.ogg
|
||||
|
||||
Metal sounds:
|
||||
default_dig_metal.ogg - yadronoff - CC-BY-3.0
|
||||
- https://www.freesound.org/people/yadronoff/sounds/320397/
|
||||
default_dug_metal.*.ogg - Iwan Gabovitch - qubodup - CC0
|
||||
- http://opengameart.org/users/qubodup
|
||||
default_metal_footstep.*.ogg - Ottomaani138 - CC0
|
||||
- https://www.freesound.org/people/Ottomaani138/sounds/232692/
|
||||
default_place_node_metal.*.ogg - Ogrebane - CC0
|
||||
- http://opengameart.org/content/wood-and-metal-sound-effects-volume-2
|
||||
|
||||
Tool breaking sounds added by sofar: CC-BY-3.0
|
||||
default_tool_breaks.* - http://www.freesound.org/people/HerbertBoland/sounds/33206/
|
||||
|
||||
AGFX (CC BY 3.0):
|
||||
https://www.freesound.org/people/AGFX/packs/1253/
|
||||
default_water_footstep.1.ogg
|
||||
default_water_footstep.2.ogg
|
||||
default_water_footstep.3.ogg
|
||||
(default_water_footstep.4.ogg is silent)
|
||||
|
||||
blukotek (CC0 1.0):
|
||||
https://www.freesound.org/people/blukotek/sounds/251660/
|
||||
default_dig_snappy.ogg
|
||||
|
||||
Chests sounds added by sofar, derived of several files mixed together:
|
||||
default_chest_open.ogg
|
||||
default_chest_close.ogg
|
||||
- http://www.freesound.org/people/Sevin7/sounds/269722/ CC0
|
||||
- http://www.freesound.org/people/Percy%20Duke/sounds/23448/ CC-BY-3.0
|
||||
- http://www.freesound.org/people/kingsamas/sounds/135576/ CC-BY-3.0
|
||||
- http://www.freesound.org/people/bulbastre/sounds/126887/ CC-BY-3.0
|
||||
- http://www.freesound.org/people/Yoyodaman234/sounds/183541/ CC0
|
||||
|
||||
Ryding (CC0 1.0):
|
||||
http://freesound.org/people/Ryding/sounds/94337/
|
||||
default_snow_footstep.*.ogg
|
||||
|
||||
Ferk (CC0 1.0):
|
||||
default_item_smoke.ogg, based on a sound by http://opengameart.org/users/bart
|
||||
|
||||
|
||||
Models
|
||||
------
|
||||
sofar (CC BY-SA 3.0):
|
||||
chest_open.obj
|
||||
torch_ceiling.obj
|
||||
torch_floor.obj
|
||||
torch_wall.obj
|
||||
|
||||
|
||||
Schematics
|
||||
----------
|
||||
paramat (CC BY-SA 3.0):
|
||||
acacia_bush.mts
|
||||
acacia_tree.mts
|
||||
acacia_tree_from_sapling.mts
|
||||
apple_tree.mts
|
||||
apple_tree_from_sapling.mts
|
||||
aspen_tree.mts
|
||||
aspen_tree_from_sapling.mts
|
||||
bush.mts
|
||||
emergent_jungle_tree.mts
|
||||
emergent_jungle_tree_from_sapling.mts
|
||||
jungle_tree.mts
|
||||
jungle_tree_from_sapling.mts
|
||||
large_cactus.mts
|
||||
papyrus.mts
|
||||
pine_tree.mts
|
||||
pine_tree_from_sapling.mts
|
||||
snowy_pine_tree_from_sapling.mts
|
||||
small_pine_tree.mts
|
||||
small_pine_tree_from_sapling.mts
|
||||
snowy_small_pine_tree_from_sapling.mts
|
||||
|
||||
Shara RedCat (CC BY-SA 3.0):
|
||||
acacia_log.mts
|
||||
apple_log.mts
|
||||
aspen_log.mts
|
||||
jungle_log.mts
|
||||
pine_log.mts
|
||||
|
||||
TumeniNodes (CC BY-SA 3.0):
|
||||
pine_bush.mts
|
||||
|
||||
random-geek (CC BY-SA 3.0):
|
||||
blueberry_bush.mts
|
||||
|
@ -22,8 +22,8 @@ minetest.register_alias("papyrus", "default:papyrus")
|
||||
minetest.register_alias("bookshelf", "default:bookshelf")
|
||||
minetest.register_alias("glass", "default:glass")
|
||||
minetest.register_alias("wooden_fence", "default:fence_wood")
|
||||
minetest.register_alias("rail", "default:rail")
|
||||
minetest.register_alias("ladder", "default:ladder")
|
||||
minetest.register_alias("rail", "carts:rail")
|
||||
minetest.register_alias("ladder", "default:ladder_wood")
|
||||
minetest.register_alias("wood", "default:wood")
|
||||
minetest.register_alias("mese", "default:mese")
|
||||
minetest.register_alias("cloud", "default:cloud")
|
||||
@ -32,15 +32,13 @@ minetest.register_alias("water_source", "default:water_source")
|
||||
minetest.register_alias("lava_flowing", "default:lava_flowing")
|
||||
minetest.register_alias("lava_source", "default:lava_source")
|
||||
minetest.register_alias("torch", "default:torch")
|
||||
minetest.register_alias("sign_wall", "default:sign_wall")
|
||||
minetest.register_alias("sign_wall", "default:sign_wall_wood")
|
||||
minetest.register_alias("furnace", "default:furnace")
|
||||
minetest.register_alias("chest", "default:chest")
|
||||
minetest.register_alias("locked_chest", "default:chest_locked")
|
||||
minetest.register_alias("cobble", "default:cobble")
|
||||
minetest.register_alias("mossycobble", "default:mossycobble")
|
||||
minetest.register_alias("steelblock", "default:steelblock")
|
||||
minetest.register_alias("nyancat", "default:nyancat")
|
||||
minetest.register_alias("nyancat_rainbow", "default:nyancat_rainbow")
|
||||
minetest.register_alias("sapling", "default:sapling")
|
||||
minetest.register_alias("apple", "default:apple")
|
||||
|
||||
@ -74,3 +72,6 @@ minetest.register_alias("default:mese_block", "default:mese")
|
||||
-- Aliases for corrected pine node names
|
||||
minetest.register_alias("default:pinetree", "default:pine_tree")
|
||||
minetest.register_alias("default:pinewood", "default:pine_wood")
|
||||
|
||||
minetest.register_alias("default:ladder", "default:ladder_wood")
|
||||
minetest.register_alias("default:sign_wall", "default:sign_wall_wood")
|
||||
|
318
mods/default/chests.lua
Normal file
@ -0,0 +1,318 @@
|
||||
default.chest = {}
|
||||
|
||||
function default.chest.get_chest_formspec(pos)
|
||||
local spos = pos.x .. "," .. pos.y .. "," .. pos.z
|
||||
local formspec =
|
||||
"size[8,9]" ..
|
||||
"list[nodemeta:" .. spos .. ";main;0,0.3;8,4;]" ..
|
||||
"list[current_player;main;0,4.85;8,1;]" ..
|
||||
"list[current_player;main;0,6.08;8,3;8]" ..
|
||||
"listring[nodemeta:" .. spos .. ";main]" ..
|
||||
"listring[current_player;main]" ..
|
||||
default.get_hotbar_bg(0,4.85)
|
||||
return formspec
|
||||
end
|
||||
|
||||
function default.chest.chest_lid_obstructed(pos)
|
||||
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local def = minetest.registered_nodes[minetest.get_node(above).name]
|
||||
-- allow ladders, signs, wallmounted things and torches to not obstruct
|
||||
if def and
|
||||
(def.drawtype == "airlike" or
|
||||
def.drawtype == "signlike" or
|
||||
def.drawtype == "torchlike" or
|
||||
(def.drawtype == "nodebox" and def.paramtype2 == "wallmounted")) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function default.chest.chest_lid_close(pn)
|
||||
local chest_open_info = default.chest.open_chests[pn]
|
||||
local pos = chest_open_info.pos
|
||||
local sound = chest_open_info.sound
|
||||
local swap = chest_open_info.swap
|
||||
|
||||
default.chest.open_chests[pn] = nil
|
||||
for k, v in pairs(default.chest.open_chests) do
|
||||
if v.pos.x == pos.x and v.pos.y == pos.y and v.pos.z == pos.z then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local node = minetest.get_node(pos)
|
||||
minetest.after(0.2, minetest.swap_node, pos, { name = "default:" .. swap,
|
||||
param2 = node.param2 })
|
||||
minetest.sound_play(sound, {gain = 0.3, pos = pos, max_hear_distance = 10})
|
||||
end
|
||||
|
||||
default.chest.open_chests = {}
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "default:chest" then
|
||||
return
|
||||
end
|
||||
if not player or not fields.quit then
|
||||
return
|
||||
end
|
||||
local pn = player:get_player_name()
|
||||
|
||||
if not default.chest.open_chests[pn] then
|
||||
return
|
||||
end
|
||||
|
||||
default.chest.chest_lid_close(pn)
|
||||
return true
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local pn = player:get_player_name()
|
||||
if default.chest.open_chests[pn] then
|
||||
default.chest.chest_lid_close(pn)
|
||||
end
|
||||
end)
|
||||
|
||||
function default.chest.register_chest(name, d)
|
||||
local def = table.copy(d)
|
||||
def.drawtype = "mesh"
|
||||
def.visual = "mesh"
|
||||
def.paramtype = "light"
|
||||
def.paramtype2 = "facedir"
|
||||
def.legacy_facedir_simple = true
|
||||
def.is_ground_content = false
|
||||
|
||||
if def.protected then
|
||||
def.on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Locked Chest")
|
||||
meta:set_string("owner", "")
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 8*4)
|
||||
end
|
||||
def.after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("owner", placer:get_player_name() or "")
|
||||
meta:set_string("infotext", "Locked Chest (owned by " ..
|
||||
meta:get_string("owner") .. ")")
|
||||
end
|
||||
def.can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("main") and
|
||||
default.can_interact_with_node(player, pos)
|
||||
end
|
||||
def.allow_metadata_inventory_move = function(pos, from_list, from_index,
|
||||
to_list, to_index, count, player)
|
||||
if not default.can_interact_with_node(player, pos) then
|
||||
return 0
|
||||
end
|
||||
return count
|
||||
end
|
||||
def.allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
if not default.can_interact_with_node(player, pos) then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end
|
||||
def.allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
if not default.can_interact_with_node(player, pos) then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end
|
||||
def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
if not default.can_interact_with_node(clicker, pos) then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
minetest.sound_play(def.sound_open, {gain = 0.3,
|
||||
pos = pos, max_hear_distance = 10})
|
||||
if not default.chest.chest_lid_obstructed(pos) then
|
||||
minetest.swap_node(pos,
|
||||
{ name = "default:" .. name .. "_open",
|
||||
param2 = node.param2 })
|
||||
end
|
||||
minetest.after(0.2, minetest.show_formspec,
|
||||
clicker:get_player_name(),
|
||||
"default:chest", default.chest.get_chest_formspec(pos))
|
||||
default.chest.open_chests[clicker:get_player_name()] = { pos = pos,
|
||||
sound = def.sound_close, swap = name }
|
||||
end
|
||||
def.on_blast = function() end
|
||||
def.on_key_use = function(pos, player)
|
||||
local secret = minetest.get_meta(pos):get_string("key_lock_secret")
|
||||
local itemstack = player:get_wielded_item()
|
||||
local key_meta = itemstack:get_meta()
|
||||
|
||||
if itemstack:get_metadata() == "" then
|
||||
return
|
||||
end
|
||||
|
||||
if key_meta:get_string("secret") == "" then
|
||||
key_meta:set_string("secret", minetest.parse_json(itemstack:get_metadata()).secret)
|
||||
itemstack:set_metadata("")
|
||||
end
|
||||
|
||||
if secret ~= key_meta:get_string("secret") then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.show_formspec(
|
||||
player:get_player_name(),
|
||||
"default:chest_locked",
|
||||
default.chest.get_chest_formspec(pos)
|
||||
)
|
||||
end
|
||||
def.on_skeleton_key_use = function(pos, player, newsecret)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local owner = meta:get_string("owner")
|
||||
local pn = player:get_player_name()
|
||||
|
||||
-- verify placer is owner of lockable chest
|
||||
if owner ~= pn then
|
||||
minetest.record_protection_violation(pos, pn)
|
||||
minetest.chat_send_player(pn, "You do not own this chest.")
|
||||
return nil
|
||||
end
|
||||
|
||||
local secret = meta:get_string("key_lock_secret")
|
||||
if secret == "" then
|
||||
secret = newsecret
|
||||
meta:set_string("key_lock_secret", secret)
|
||||
end
|
||||
|
||||
return secret, "a locked chest", owner
|
||||
end
|
||||
else
|
||||
def.on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Chest")
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 8*4)
|
||||
end
|
||||
def.can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("main")
|
||||
end
|
||||
def.on_rightclick = function(pos, node, clicker)
|
||||
minetest.sound_play(def.sound_open, {gain = 0.3, pos = pos,
|
||||
max_hear_distance = 10})
|
||||
if not default.chest.chest_lid_obstructed(pos) then
|
||||
minetest.swap_node(pos, {
|
||||
name = "default:" .. name .. "_open",
|
||||
param2 = node.param2 })
|
||||
end
|
||||
minetest.after(0.2, minetest.show_formspec,
|
||||
clicker:get_player_name(),
|
||||
"default:chest", default.chest.get_chest_formspec(pos))
|
||||
default.chest.open_chests[clicker:get_player_name()] = { pos = pos,
|
||||
sound = def.sound_close, swap = name }
|
||||
end
|
||||
def.on_blast = function(pos)
|
||||
local drops = {}
|
||||
default.get_inventory_drops(pos, "main", drops)
|
||||
drops[#drops+1] = "default:" .. name
|
||||
minetest.remove_node(pos)
|
||||
return drops
|
||||
end
|
||||
end
|
||||
|
||||
def.on_metadata_inventory_move = function(pos, from_list, from_index,
|
||||
to_list, to_index, count, player)
|
||||
minetest.log("action", player:get_player_name() ..
|
||||
" moves stuff in chest at " .. minetest.pos_to_string(pos))
|
||||
end
|
||||
def.on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
minetest.log("action", player:get_player_name() ..
|
||||
" moves " .. stack:get_name() ..
|
||||
" to chest at " .. minetest.pos_to_string(pos))
|
||||
end
|
||||
def.on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
minetest.log("action", player:get_player_name() ..
|
||||
" takes " .. stack:get_name() ..
|
||||
" from chest at " .. minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
local def_opened = table.copy(def)
|
||||
local def_closed = table.copy(def)
|
||||
|
||||
def_opened.mesh = "chest_open.obj"
|
||||
for i = 1, #def_opened.tiles do
|
||||
if type(def_opened.tiles[i]) == "string" then
|
||||
def_opened.tiles[i] = {name = def_opened.tiles[i], backface_culling = true}
|
||||
elseif def_opened.tiles[i].backface_culling == nil then
|
||||
def_opened.tiles[i].backface_culling = true
|
||||
end
|
||||
end
|
||||
def_opened.drop = "default:" .. name
|
||||
def_opened.groups.not_in_creative_inventory = 1
|
||||
def_opened.selection_box = {
|
||||
type = "fixed",
|
||||
fixed = { -1/2, -1/2, -1/2, 1/2, 3/16, 1/2 },
|
||||
}
|
||||
def_opened.can_dig = function()
|
||||
return false
|
||||
end
|
||||
def_opened.on_blast = function() end
|
||||
|
||||
def_closed.mesh = nil
|
||||
def_closed.drawtype = nil
|
||||
def_closed.tiles[6] = def.tiles[5] -- swap textures around for "normal"
|
||||
def_closed.tiles[5] = def.tiles[3] -- drawtype to make them match the mesh
|
||||
def_closed.tiles[3] = def.tiles[3].."^[transformFX"
|
||||
|
||||
minetest.register_node("default:" .. name, def_closed)
|
||||
minetest.register_node("default:" .. name .. "_open", def_opened)
|
||||
|
||||
-- convert old chests to this new variant
|
||||
minetest.register_lbm({
|
||||
label = "update chests to opening chests",
|
||||
name = "default:upgrade_" .. name .. "_v2",
|
||||
nodenames = {"default:" .. name},
|
||||
action = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", nil)
|
||||
local inv = meta:get_inventory()
|
||||
local list = inv:get_list("default:chest")
|
||||
if list then
|
||||
inv:set_size("main", 8*4)
|
||||
inv:set_list("main", list)
|
||||
inv:set_list("default:chest", nil)
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
default.chest.register_chest("chest", {
|
||||
description = "Chest",
|
||||
tiles = {
|
||||
"default_chest_top.png",
|
||||
"default_chest_top.png",
|
||||
"default_chest_side.png",
|
||||
"default_chest_side.png",
|
||||
"default_chest_front.png",
|
||||
"default_chest_inside.png"
|
||||
},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
sound_open = "default_chest_open",
|
||||
sound_close = "default_chest_close",
|
||||
groups = {choppy = 2, oddly_breakable_by_hand = 2},
|
||||
})
|
||||
|
||||
default.chest.register_chest("chest_locked", {
|
||||
description = "Locked Chest",
|
||||
tiles = {
|
||||
"default_chest_top.png",
|
||||
"default_chest_top.png",
|
||||
"default_chest_side.png",
|
||||
"default_chest_side.png",
|
||||
"default_chest_lock.png",
|
||||
"default_chest_inside.png"
|
||||
},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
sound_open = "default_chest_open",
|
||||
sound_close = "default_chest_close",
|
||||
groups = {choppy = 2, oddly_breakable_by_hand = 2},
|
||||
protected = true,
|
||||
})
|
@ -28,6 +28,34 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:aspen_wood 4',
|
||||
recipe = {
|
||||
{'default:aspen_tree'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:wood',
|
||||
recipe = {
|
||||
{'default:bush_stem'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:acacia_wood',
|
||||
recipe = {
|
||||
{'default:acacia_bush_stem'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:pine_wood",
|
||||
recipe = {
|
||||
{"default:pine_bush_stem"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:stick 4',
|
||||
recipe = {
|
||||
@ -36,15 +64,16 @@ minetest.register_craft({
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:fence_wood 2',
|
||||
output = 'default:sign_wall_steel 3',
|
||||
recipe = {
|
||||
{'group:stick', 'group:stick', 'group:stick'},
|
||||
{'group:stick', 'group:stick', 'group:stick'},
|
||||
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
|
||||
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
|
||||
{'', 'group:stick', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:sign_wall',
|
||||
output = 'default:sign_wall_wood 3',
|
||||
recipe = {
|
||||
{'group:wood', 'group:wood', 'group:wood'},
|
||||
{'group:wood', 'group:wood', 'group:wood'},
|
||||
@ -168,6 +197,9 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
-- Axes
|
||||
-- Recipes face left to match appearence in textures and inventory
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:axe_wood',
|
||||
recipe = {
|
||||
@ -222,60 +254,6 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:axe_wood',
|
||||
recipe = {
|
||||
{'group:wood', 'group:wood'},
|
||||
{'group:stick', 'group:wood'},
|
||||
{'group:stick',''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:axe_stone',
|
||||
recipe = {
|
||||
{'group:stone', 'group:stone'},
|
||||
{'group:stick', 'group:stone'},
|
||||
{'group:stick', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:axe_steel',
|
||||
recipe = {
|
||||
{'default:steel_ingot', 'default:steel_ingot'},
|
||||
{'group:stick', 'default:steel_ingot'},
|
||||
{'group:stick', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:axe_bronze',
|
||||
recipe = {
|
||||
{'default:bronze_ingot', 'default:bronze_ingot'},
|
||||
{'group:stick', 'default:bronze_ingot'},
|
||||
{'group:stick', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:axe_mese',
|
||||
recipe = {
|
||||
{'default:mese_crystal', 'default:mese_crystal'},
|
||||
{'group:stick', 'default:mese_crystal'},
|
||||
{'group:stick', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:axe_diamond',
|
||||
recipe = {
|
||||
{'default:diamond', 'default:diamond'},
|
||||
{'group:stick', 'default:diamond'},
|
||||
{'group:stick', ''},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:sword_wood',
|
||||
recipe = {
|
||||
@ -331,11 +309,9 @@ minetest.register_craft({
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:rail 24',
|
||||
output = 'default:skeleton_key',
|
||||
recipe = {
|
||||
{'default:steel_ingot', '', 'default:steel_ingot'},
|
||||
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
|
||||
{'default:steel_ingot', '', 'default:steel_ingot'},
|
||||
{'default:gold_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
@ -357,6 +333,12 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft( {
|
||||
type = "shapeless",
|
||||
output = "default:chest_locked",
|
||||
recipe = {"default:chest", "default:steel_ingot"},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:furnace',
|
||||
recipe = {
|
||||
@ -366,12 +348,6 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "default:bronze_ingot",
|
||||
recipe = {"default:steel_ingot", "default:copper_ingot"},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:coalblock',
|
||||
recipe = {
|
||||
@ -420,6 +396,31 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:tinblock",
|
||||
recipe = {
|
||||
{"default:tin_ingot", "default:tin_ingot", "default:tin_ingot"},
|
||||
{"default:tin_ingot", "default:tin_ingot", "default:tin_ingot"},
|
||||
{"default:tin_ingot", "default:tin_ingot", "default:tin_ingot"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:tin_ingot 9",
|
||||
recipe = {
|
||||
{"default:tinblock"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:bronze_ingot 9",
|
||||
recipe = {
|
||||
{"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"},
|
||||
{"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"},
|
||||
{"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:bronzeblock',
|
||||
recipe = {
|
||||
@ -469,25 +470,98 @@ minetest.register_craft({
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:sandstone',
|
||||
output = "default:sandstone",
|
||||
recipe = {
|
||||
{'group:sand', 'group:sand'},
|
||||
{'group:sand', 'group:sand'},
|
||||
{"default:sand", "default:sand"},
|
||||
{"default:sand", "default:sand"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:sand 4',
|
||||
output = "default:sand 4",
|
||||
recipe = {
|
||||
{'default:sandstone'},
|
||||
{"default:sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:sandstonebrick 4',
|
||||
output = "default:sandstonebrick 4",
|
||||
recipe = {
|
||||
{'default:sandstone', 'default:sandstone'},
|
||||
{'default:sandstone', 'default:sandstone'},
|
||||
{"default:sandstone", "default:sandstone"},
|
||||
{"default:sandstone", "default:sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:sandstone_block 9",
|
||||
recipe = {
|
||||
{"default:sandstone", "default:sandstone", "default:sandstone"},
|
||||
{"default:sandstone", "default:sandstone", "default:sandstone"},
|
||||
{"default:sandstone", "default:sandstone", "default:sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:desert_sandstone",
|
||||
recipe = {
|
||||
{"default:desert_sand", "default:desert_sand"},
|
||||
{"default:desert_sand", "default:desert_sand"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:desert_sand 4",
|
||||
recipe = {
|
||||
{"default:desert_sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:desert_sandstone_brick 4",
|
||||
recipe = {
|
||||
{"default:desert_sandstone", "default:desert_sandstone"},
|
||||
{"default:desert_sandstone", "default:desert_sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:desert_sandstone_block 9",
|
||||
recipe = {
|
||||
{"default:desert_sandstone", "default:desert_sandstone", "default:desert_sandstone"},
|
||||
{"default:desert_sandstone", "default:desert_sandstone", "default:desert_sandstone"},
|
||||
{"default:desert_sandstone", "default:desert_sandstone", "default:desert_sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:silver_sandstone",
|
||||
recipe = {
|
||||
{"default:silver_sand", "default:silver_sand"},
|
||||
{"default:silver_sand", "default:silver_sand"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:silver_sand 4",
|
||||
recipe = {
|
||||
{"default:silver_sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:silver_sandstone_brick 4",
|
||||
recipe = {
|
||||
{"default:silver_sandstone", "default:silver_sandstone"},
|
||||
{"default:silver_sandstone", "default:silver_sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:silver_sandstone_block 9",
|
||||
recipe = {
|
||||
{"default:silver_sandstone", "default:silver_sandstone", "default:silver_sandstone"},
|
||||
{"default:silver_sandstone", "default:silver_sandstone", "default:silver_sandstone"},
|
||||
{"default:silver_sandstone", "default:silver_sandstone", "default:silver_sandstone"},
|
||||
}
|
||||
})
|
||||
|
||||
@ -499,6 +573,13 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:clay_lump 4',
|
||||
recipe = {
|
||||
{'default:clay'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:brick',
|
||||
recipe = {
|
||||
@ -540,11 +621,20 @@ minetest.register_craft({
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:ladder',
|
||||
output = "default:ladder_wood 5",
|
||||
recipe = {
|
||||
{'group:stick', '', 'group:stick'},
|
||||
{'group:stick', 'group:stick', 'group:stick'},
|
||||
{'group:stick', '', 'group:stick'},
|
||||
{"group:stick", "", "group:stick"},
|
||||
{"group:stick", "group:stick", "group:stick"},
|
||||
{"group:stick", "", "group:stick"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:ladder_steel 15',
|
||||
recipe = {
|
||||
{'default:steel_ingot', '', 'default:steel_ingot'},
|
||||
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
|
||||
{'default:steel_ingot', '', 'default:steel_ingot'},
|
||||
}
|
||||
})
|
||||
|
||||
@ -572,10 +662,28 @@ minetest.register_craft({
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:meselamp 1',
|
||||
output = "default:mese_crystal",
|
||||
recipe = {
|
||||
{'', 'default:mese_crystal',''},
|
||||
{'default:mese_crystal', 'default:glass', 'default:mese_crystal'},
|
||||
{"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"},
|
||||
{"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"},
|
||||
{"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:meselamp',
|
||||
recipe = {
|
||||
{'default:glass'},
|
||||
{'default:mese_crystal'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:mese_post_light 3",
|
||||
recipe = {
|
||||
{"", "default:glass", ""},
|
||||
{"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"},
|
||||
{"", "group:wood", ""},
|
||||
}
|
||||
})
|
||||
|
||||
@ -603,6 +711,15 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:obsidian_block 9',
|
||||
recipe = {
|
||||
{'default:obsidian', 'default:obsidian', 'default:obsidian'},
|
||||
{'default:obsidian', 'default:obsidian', 'default:obsidian'},
|
||||
{'default:obsidian', 'default:obsidian', 'default:obsidian'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:stonebrick 4',
|
||||
recipe = {
|
||||
@ -611,6 +728,15 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:stone_block 9',
|
||||
recipe = {
|
||||
{'default:stone', 'default:stone', 'default:stone'},
|
||||
{'default:stone', 'default:stone', 'default:stone'},
|
||||
{'default:stone', 'default:stone', 'default:stone'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:desert_stonebrick 4',
|
||||
recipe = {
|
||||
@ -619,6 +745,15 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:desert_stone_block 9',
|
||||
recipe = {
|
||||
{'default:desert_stone', 'default:desert_stone', 'default:desert_stone'},
|
||||
{'default:desert_stone', 'default:desert_stone', 'default:desert_stone'},
|
||||
{'default:desert_stone', 'default:desert_stone', 'default:desert_stone'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'default:snowblock',
|
||||
recipe = {
|
||||
@ -635,14 +770,35 @@ minetest.register_craft({
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:emergent_jungle_sapling",
|
||||
recipe = {
|
||||
{"default:junglesapling", "default:junglesapling", "default:junglesapling"},
|
||||
{"default:junglesapling", "default:junglesapling", "default:junglesapling"},
|
||||
{"default:junglesapling", "default:junglesapling", "default:junglesapling"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:large_cactus_seedling",
|
||||
recipe = {
|
||||
{"", "default:cactus", ""},
|
||||
{"default:cactus", "default:cactus", "default:cactus"},
|
||||
{"", "default:cactus", ""},
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
--
|
||||
-- Crafting (tool repair)
|
||||
--
|
||||
|
||||
minetest.register_craft({
|
||||
type = "toolrepair",
|
||||
additional_wear = -0.02,
|
||||
})
|
||||
|
||||
|
||||
--
|
||||
-- Cooking recipes
|
||||
--
|
||||
@ -689,6 +845,12 @@ minetest.register_craft({
|
||||
recipe = "default:copper_lump",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "default:tin_ingot",
|
||||
recipe = "default:tin_lump",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "default:gold_ingot",
|
||||
@ -701,26 +863,239 @@ minetest.register_craft({
|
||||
recipe = "default:clay_lump",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = 'cooking',
|
||||
output = 'default:gold_ingot',
|
||||
recipe = 'default:skeleton_key',
|
||||
cooktime = 5,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = 'cooking',
|
||||
output = 'default:gold_ingot',
|
||||
recipe = 'default:key',
|
||||
cooktime = 5,
|
||||
})
|
||||
|
||||
|
||||
--
|
||||
-- Fuels
|
||||
--
|
||||
|
||||
-- Support use of group:tree, includes default:tree which has the same burn time
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:tree",
|
||||
burntime = 30,
|
||||
})
|
||||
|
||||
-- Burn time for all woods are in order of wood density,
|
||||
-- which is also the order of wood colour darkness:
|
||||
-- aspen, pine, apple, acacia, jungle
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:junglegrass",
|
||||
recipe = "default:aspen_tree",
|
||||
burntime = 22,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:pine_tree",
|
||||
burntime = 26,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:acacia_tree",
|
||||
burntime = 34,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:jungletree",
|
||||
burntime = 38,
|
||||
})
|
||||
|
||||
|
||||
-- Support use of group:wood, includes default:wood which has the same burn time
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:wood",
|
||||
burntime = 7,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:aspen_wood",
|
||||
burntime = 5,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:pine_wood",
|
||||
burntime = 6,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:acacia_wood",
|
||||
burntime = 8,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:junglewood",
|
||||
burntime = 9,
|
||||
})
|
||||
|
||||
|
||||
-- Support use of group:sapling, includes default:sapling which has the same burn time
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:sapling",
|
||||
burntime = 5,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:bush_sapling",
|
||||
burntime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:acacia_bush_sapling",
|
||||
burntime = 4,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:pine_bush_sapling",
|
||||
burntime = 2,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:aspen_sapling",
|
||||
burntime = 4,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:pine_sapling",
|
||||
burntime = 5,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:acacia_sapling",
|
||||
burntime = 6,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:junglesapling",
|
||||
burntime = 6,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:emergent_jungle_sapling",
|
||||
burntime = 7,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_aspen_wood",
|
||||
burntime = 5,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_pine_wood",
|
||||
burntime = 6,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_wood",
|
||||
burntime = 7,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_acacia_wood",
|
||||
burntime = 8,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_junglewood",
|
||||
burntime = 9,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_rail_aspen_wood",
|
||||
burntime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_rail_pine_wood",
|
||||
burntime = 4,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_rail_wood",
|
||||
burntime = 5,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_rail_acacia_wood",
|
||||
burntime = 6,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_rail_junglewood",
|
||||
burntime = 7,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:bush_stem",
|
||||
burntime = 7,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:acacia_bush_stem",
|
||||
burntime = 8,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:pine_bush_stem",
|
||||
burntime = 6,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:junglegrass",
|
||||
burntime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:leaves",
|
||||
burntime = 1,
|
||||
burntime = 4,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
@ -729,10 +1104,16 @@ minetest.register_craft({
|
||||
burntime = 15,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:large_cactus_seedling",
|
||||
burntime = 5,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:papyrus",
|
||||
burntime = 1,
|
||||
burntime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
@ -743,19 +1124,7 @@ minetest.register_craft({
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fence_wood",
|
||||
burntime = 15,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:ladder",
|
||||
burntime = 5,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:wood",
|
||||
recipe = "default:ladder_wood",
|
||||
burntime = 7,
|
||||
})
|
||||
|
||||
@ -773,7 +1142,7 @@ minetest.register_craft({
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:sign_wall",
|
||||
recipe = "default:sign_wall_wood",
|
||||
burntime = 10,
|
||||
})
|
||||
|
||||
@ -789,30 +1158,6 @@ minetest.register_craft({
|
||||
burntime = 30,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:nyancat",
|
||||
burntime = 1,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:nyancat_rainbow",
|
||||
burntime = 1,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:sapling",
|
||||
burntime = 10,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:apple",
|
||||
burntime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:coal_lump",
|
||||
@ -837,3 +1182,69 @@ minetest.register_craft({
|
||||
burntime = 2,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:fern_1",
|
||||
burntime = 2,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:marram_grass_1",
|
||||
burntime = 2,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:paper",
|
||||
burntime = 1,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:book",
|
||||
burntime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:book_written",
|
||||
burntime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:dry_shrub",
|
||||
burntime = 2,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:stick",
|
||||
burntime = 1,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:pick_wood",
|
||||
burntime = 6,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:shovel_wood",
|
||||
burntime = 4,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:axe_wood",
|
||||
burntime = 6,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "default:sword_wood",
|
||||
burntime = 5,
|
||||
})
|
||||
|
@ -3,94 +3,261 @@
|
||||
minetest.register_craftitem("default:stick", {
|
||||
description = "Stick",
|
||||
inventory_image = "default_stick.png",
|
||||
groups = {stick=1},
|
||||
groups = {stick = 1, flammable = 2},
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:paper", {
|
||||
description = "Paper",
|
||||
inventory_image = "default_paper.png",
|
||||
groups = {flammable = 3},
|
||||
})
|
||||
|
||||
local function book_on_use(itemstack, user, pointed_thing)
|
||||
|
||||
local lpp = 14 -- Lines per book's page
|
||||
local function book_on_use(itemstack, user)
|
||||
local player_name = user:get_player_name()
|
||||
local data = minetest.deserialize(itemstack:get_metadata())
|
||||
local meta = itemstack:get_meta()
|
||||
local title, text, owner = "", "", player_name
|
||||
if data then
|
||||
title, text, owner = data.title, data.text, data.owner
|
||||
local page, page_max, lines, string = 1, 1, {}, ""
|
||||
|
||||
-- Backwards compatibility
|
||||
local old_data = minetest.deserialize(itemstack:get_metadata())
|
||||
if old_data then
|
||||
meta:from_table({ fields = old_data })
|
||||
end
|
||||
|
||||
local data = meta:to_table().fields
|
||||
|
||||
if data.owner then
|
||||
title = data.title
|
||||
text = data.text
|
||||
owner = data.owner
|
||||
|
||||
for str in (text .. "\n"):gmatch("([^\n]*)[\n]") do
|
||||
lines[#lines+1] = str
|
||||
end
|
||||
|
||||
if data.page then
|
||||
page = data.page
|
||||
page_max = data.page_max
|
||||
|
||||
for i = ((lpp * page) - lpp) + 1, lpp * page do
|
||||
if not lines[i] then break end
|
||||
string = string .. lines[i] .. "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local formspec
|
||||
if owner == player_name then
|
||||
formspec = "size[8,8]"..default.gui_bg..
|
||||
"field[0.5,1;7.5,0;title;Title:;"..
|
||||
minetest.formspec_escape(title).."]"..
|
||||
"textarea[0.5,1.5;7.5,7;text;Contents:;"..
|
||||
minetest.formspec_escape(text).."]"..
|
||||
formspec = "size[8,8]" ..
|
||||
"field[0.5,1;7.5,0;title;Title:;" ..
|
||||
minetest.formspec_escape(title) .. "]" ..
|
||||
"textarea[0.5,1.5;7.5,7;text;Contents:;" ..
|
||||
minetest.formspec_escape(text) .. "]" ..
|
||||
"button_exit[2.5,7.5;3,1;save;Save]"
|
||||
else
|
||||
formspec = "size[8,8]"..default.gui_bg..
|
||||
"label[0.5,0.5;by "..owner.."]"..
|
||||
"label[0.5,0;"..minetest.formspec_escape(title).."]"..
|
||||
"textarea[0.5,1.5;7.5,7;;"..minetest.formspec_escape(text)..";]"
|
||||
formspec = "size[8,8]" ..
|
||||
"label[0.5,0.5;by " .. owner .. "]" ..
|
||||
"tablecolumns[color;text]" ..
|
||||
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
|
||||
"table[0.4,0;7,0.5;title;#FFFF00," .. minetest.formspec_escape(title) .. "]" ..
|
||||
"textarea[0.5,1.5;7.5,7;;" ..
|
||||
minetest.formspec_escape(string ~= "" and string or text) .. ";]" ..
|
||||
"button[2.4,7.6;0.8,0.8;book_prev;<]" ..
|
||||
"label[3.2,7.7;Page " .. page .. " of " .. page_max .. "]" ..
|
||||
"button[4.9,7.6;0.8,0.8;book_next;>]"
|
||||
end
|
||||
minetest.show_formspec(user:get_player_name(), "default:book", formspec)
|
||||
|
||||
minetest.show_formspec(player_name, "default:book", formspec)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, form_name, fields)
|
||||
if form_name ~= "default:book" or not fields.save or
|
||||
fields.title == "" or fields.text == "" then
|
||||
return
|
||||
end
|
||||
local max_text_size = 10000
|
||||
local max_title_size = 80
|
||||
local short_title_size = 35
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "default:book" then return end
|
||||
local inv = player:get_inventory()
|
||||
local stack = player:get_wielded_item()
|
||||
local new_stack, data
|
||||
if stack:get_name() ~= "default:book_written" then
|
||||
local count = stack:get_count()
|
||||
if count == 1 then
|
||||
stack:set_name("default:book_written")
|
||||
|
||||
if fields.save and fields.title and fields.text
|
||||
and fields.title ~= "" and fields.text ~= "" then
|
||||
local new_stack, data
|
||||
if stack:get_name() ~= "default:book_written" then
|
||||
local count = stack:get_count()
|
||||
if count == 1 then
|
||||
stack:set_name("default:book_written")
|
||||
else
|
||||
stack:set_count(count - 1)
|
||||
new_stack = ItemStack("default:book_written")
|
||||
end
|
||||
else
|
||||
stack:set_count(count - 1)
|
||||
new_stack = ItemStack("default:book_written")
|
||||
data = stack:get_meta():to_table().fields
|
||||
end
|
||||
else
|
||||
data = minetest.deserialize(stack:get_metadata())
|
||||
end
|
||||
if not data then data = {} end
|
||||
data.title = fields.title
|
||||
data.text = fields.text
|
||||
data.owner = player:get_player_name()
|
||||
local data_str = minetest.serialize(data)
|
||||
if new_stack then
|
||||
new_stack:set_metadata(data_str)
|
||||
if inv:room_for_item("main", new_stack) then
|
||||
inv:add_item("main", new_stack)
|
||||
|
||||
if data and data.owner and data.owner ~= player:get_player_name() then
|
||||
return
|
||||
end
|
||||
|
||||
if not data then data = {} end
|
||||
data.title = fields.title:sub(1, max_title_size)
|
||||
data.owner = player:get_player_name()
|
||||
local short_title = data.title
|
||||
-- Don't bother triming the title if the trailing dots would make it longer
|
||||
if #short_title > short_title_size + 3 then
|
||||
short_title = short_title:sub(1, short_title_size) .. "..."
|
||||
end
|
||||
data.description = "\""..short_title.."\" by "..data.owner
|
||||
data.text = fields.text:sub(1, max_text_size)
|
||||
data.text = data.text:gsub("\r\n", "\n"):gsub("\r", "\n")
|
||||
data.page = 1
|
||||
data.page_max = math.ceil((#data.text:gsub("[^\n]", "") + 1) / lpp)
|
||||
|
||||
if new_stack then
|
||||
new_stack:get_meta():from_table({ fields = data })
|
||||
if inv:room_for_item("main", new_stack) then
|
||||
inv:add_item("main", new_stack)
|
||||
else
|
||||
minetest.add_item(player:get_pos(), new_stack)
|
||||
end
|
||||
else
|
||||
minetest.add_item(player:getpos(), new_stack)
|
||||
stack:get_meta():from_table({ fields = data })
|
||||
end
|
||||
else
|
||||
stack:set_metadata(data_str)
|
||||
|
||||
elseif fields.book_next or fields.book_prev then
|
||||
local data = stack:get_meta():to_table().fields
|
||||
if not data or not data.page then
|
||||
return
|
||||
end
|
||||
|
||||
data.page = tonumber(data.page)
|
||||
data.page_max = tonumber(data.page_max)
|
||||
|
||||
if fields.book_next then
|
||||
data.page = data.page + 1
|
||||
if data.page > data.page_max then
|
||||
data.page = 1
|
||||
end
|
||||
else
|
||||
data.page = data.page - 1
|
||||
if data.page == 0 then
|
||||
data.page = data.page_max
|
||||
end
|
||||
end
|
||||
|
||||
stack:get_meta():from_table({fields = data})
|
||||
stack = book_on_use(stack, player)
|
||||
end
|
||||
|
||||
-- Update stack
|
||||
player:set_wielded_item(stack)
|
||||
end)
|
||||
|
||||
minetest.register_craftitem("default:book", {
|
||||
description = "Book",
|
||||
inventory_image = "default_book.png",
|
||||
groups = {book=1},
|
||||
groups = {book = 1, flammable = 3},
|
||||
on_use = book_on_use,
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:book_written", {
|
||||
description = "Book With Text",
|
||||
inventory_image = "default_book.png",
|
||||
groups = {book=1, not_in_creative_inventory=1},
|
||||
inventory_image = "default_book_written.png",
|
||||
groups = {book = 1, not_in_creative_inventory = 1, flammable = 3},
|
||||
stack_max = 1,
|
||||
on_use = book_on_use,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "default:book_written",
|
||||
recipe = {"default:book", "default:book_written"}
|
||||
})
|
||||
|
||||
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
|
||||
if itemstack:get_name() ~= "default:book_written" then
|
||||
return
|
||||
end
|
||||
|
||||
local original
|
||||
local index
|
||||
for i = 1, player:get_inventory():get_size("craft") do
|
||||
if old_craft_grid[i]:get_name() == "default:book_written" then
|
||||
original = old_craft_grid[i]
|
||||
index = i
|
||||
end
|
||||
end
|
||||
if not original then
|
||||
return
|
||||
end
|
||||
local copymeta = original:get_meta():to_table()
|
||||
-- copy of the book held by player's mouse cursor
|
||||
itemstack:get_meta():from_table(copymeta)
|
||||
-- put the book with metadata back in the craft grid
|
||||
craft_inv:set_stack("craft", index, original)
|
||||
end)
|
||||
|
||||
minetest.register_craftitem("default:skeleton_key", {
|
||||
description = "Skeleton Key",
|
||||
inventory_image = "default_key_skeleton.png",
|
||||
groups = {key = 1},
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local pos = pointed_thing.under
|
||||
local node = minetest.get_node(pos)
|
||||
|
||||
if not node then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local on_skeleton_key_use = minetest.registered_nodes[node.name].on_skeleton_key_use
|
||||
if not on_skeleton_key_use then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- make a new key secret in case the node callback needs it
|
||||
local random = math.random
|
||||
local newsecret = string.format(
|
||||
"%04x%04x%04x%04x",
|
||||
random(2^16) - 1, random(2^16) - 1,
|
||||
random(2^16) - 1, random(2^16) - 1)
|
||||
|
||||
local secret, _, _ = on_skeleton_key_use(pos, user, newsecret)
|
||||
|
||||
if secret then
|
||||
local inv = minetest.get_inventory({type="player", name=user:get_player_name()})
|
||||
|
||||
-- update original itemstack
|
||||
itemstack:take_item()
|
||||
|
||||
-- finish and return the new key
|
||||
local new_stack = ItemStack("default:key")
|
||||
local meta = new_stack:get_meta()
|
||||
meta:set_string("secret", secret)
|
||||
meta:set_string("description", "Key to "..user:get_player_name().."'s "
|
||||
..minetest.registered_nodes[node.name].description)
|
||||
|
||||
if itemstack:get_count() == 0 then
|
||||
itemstack = new_stack
|
||||
else
|
||||
if inv:add_item("main", new_stack):get_count() > 0 then
|
||||
minetest.add_item(user:get_pos(), new_stack)
|
||||
end -- else: added to inventory successfully
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:coal_lump", {
|
||||
description = "Coal Lump",
|
||||
inventory_image = "default_coal_lump.png",
|
||||
groups = {coal = 1}
|
||||
groups = {coal = 1, flammable = 1}
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:iron_lump", {
|
||||
@ -103,6 +270,11 @@ minetest.register_craftitem("default:copper_lump", {
|
||||
inventory_image = "default_copper_lump.png",
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:tin_lump", {
|
||||
description = "Tin Lump",
|
||||
inventory_image = "default_tin_lump.png",
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:mese_crystal", {
|
||||
description = "Mese Crystal",
|
||||
inventory_image = "default_mese_crystal.png",
|
||||
@ -133,6 +305,11 @@ minetest.register_craftitem("default:copper_ingot", {
|
||||
inventory_image = "default_copper_ingot.png",
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:tin_ingot", {
|
||||
description = "Tin Ingot",
|
||||
inventory_image = "default_tin_ingot.png",
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:bronze_ingot", {
|
||||
description = "Bronze Ingot",
|
||||
inventory_image = "default_bronze_ingot.png",
|
||||
@ -157,3 +334,14 @@ minetest.register_craftitem("default:obsidian_shard", {
|
||||
description = "Obsidian Shard",
|
||||
inventory_image = "default_obsidian_shard.png",
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:flint", {
|
||||
description = "Flint",
|
||||
inventory_image = "default_flint.png"
|
||||
})
|
||||
|
||||
minetest.register_craftitem("default:blueberries", {
|
||||
description = "Blueberries",
|
||||
inventory_image = "default_blueberries.png",
|
||||
on_use = minetest.item_eat(2),
|
||||
})
|
||||
|
1
mods/default/depends.txt
Normal file
@ -0,0 +1 @@
|
||||
player_api?
|