mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-09 11:16:57 +00:00
Compare commits
785 Commits
Alpha_1.4d
...
Alpha_1.4d
Author | SHA1 | Date | |
---|---|---|---|
c7f578f297 | |||
19c030281f | |||
ca9fe1b89a | |||
9fd6a695f6 | |||
c07b0ff35b | |||
6796fca2b6 | |||
5657cce3db | |||
05ac256cc3 | |||
49977c5410 | |||
ca40bb678c | |||
2068cc9cdf | |||
ea4617cedd | |||
1a5544f68c | |||
0128a7aeb2 | |||
fd954ce708 | |||
d63a82de0a | |||
92143d523c | |||
1818e64c8e | |||
7e1095e28d | |||
f1519e6d13 | |||
3b9a9bcd5d | |||
263bff01c8 | |||
987d647b76 | |||
522b75645c | |||
9eed0a579c | |||
064976d32b | |||
2abb577178 | |||
127855c220 | |||
93c7a3c170 | |||
31903a764a | |||
79bc1d6c85 | |||
cc7f12739d | |||
32dae93ef9 | |||
8fd6582e74 | |||
a5369b3570 | |||
abbd33210a | |||
6b6222c09c | |||
a8c997d88a | |||
6993718a83 | |||
86afecec89 | |||
29d1fd1fc8 | |||
af4eb2ab1e | |||
f7baf46a54 | |||
75c0d8324c | |||
da4334f06b | |||
413bd3c0df | |||
1a0428654b | |||
2803a38fd1 | |||
95a5ca7889 | |||
240f14c425 | |||
cb9b6ab1d1 | |||
8a87280566 | |||
4d97827d44 | |||
f8f1e0e9df | |||
bf596ebf05 | |||
90777014b6 | |||
4a78ffd2dd | |||
7c361a52d2 | |||
13fc0df92c | |||
d5012f6fcf | |||
4569a73f3d | |||
66acb5cdd7 | |||
8601405a88 | |||
ae06681b60 | |||
01ffb14e39 | |||
ce989876af | |||
f8d6ebabf3 | |||
094b600a0c | |||
82cfe6ea9c | |||
4fba6d7c86 | |||
f72d7284b9 | |||
8f0527832f | |||
f66944368d | |||
7ab3c57b00 | |||
673b867ee8 | |||
2424c8a76c | |||
92eb5cb0b8 | |||
fd46c71120 | |||
6a4259bf24 | |||
9a65279c6a | |||
09a01be709 | |||
57d1847c50 | |||
6e8e2a79dd | |||
d8f9def7f4 | |||
8cb9dd9a14 | |||
c4c374e3fa | |||
d57e37896d | |||
022a978ffb | |||
00b282d40c | |||
8a768cea33 | |||
289bc56b4b | |||
6f64af3066 | |||
72c09045d5 | |||
5e55c3a8f0 | |||
afaa2cf722 | |||
50cfeaa393 | |||
dda8b03349 | |||
56e848488a | |||
7e4f862634 | |||
577a7a1c3d | |||
78f8d0280d | |||
0680b98380 | |||
cbe0fe5e46 | |||
7eed92e8fb | |||
f772391866 | |||
8c4faa8622 | |||
b6f7ee20fc | |||
0fce83c671 | |||
8080643cc9 | |||
5bf2174cad | |||
34ae760def | |||
a5b85c549a | |||
b9f1812f61 | |||
350cee3d41 | |||
144a871c07 | |||
69492474e4 | |||
4299ebebcc | |||
119b429ab8 | |||
8f1eb41ca5 | |||
ca92d2a0d3 | |||
db82f76c11 | |||
3f5b129cf5 | |||
f6aac8728b | |||
809fc44813 | |||
64f1ff066d | |||
a5a3f4801a | |||
23d1532ff9 | |||
ecbbcc2e8e | |||
7abf52e615 | |||
9e01e2ef49 | |||
df81b365e5 | |||
db8ac0b9cb | |||
ee4f416d93 | |||
8feea721e3 | |||
8e7077ff4b | |||
4f4a6e7446 | |||
1fc066fc37 | |||
b565844062 | |||
be948f99cc | |||
5cb428e5cc | |||
d2f4a14d66 | |||
516bb37a50 | |||
580ade9092 | |||
8f7dfe0b71 | |||
5310ba3ae6 | |||
ef97efcd96 | |||
30c3718ea8 | |||
5437567e95 | |||
e3e97a4205 | |||
fec387d2ec | |||
481e2b08ee | |||
15de0eece7 | |||
2f8267aa1e | |||
f2b573c32f | |||
34946faf94 | |||
3b47513439 | |||
7d9a98ec6b | |||
92facc94b9 | |||
d3327f450c | |||
570cab9c66 | |||
582ba100b0 | |||
4c0daa462d | |||
2e6366868d | |||
245e9b4f18 | |||
68e73d4e3a | |||
684617d370 | |||
a879104a6f | |||
05f71691fc | |||
1c03c3afcf | |||
94e9485be9 | |||
9cb27e26ef | |||
7760559be1 | |||
163a37ee23 | |||
c73a3e53be | |||
8637b7f5a3 | |||
747fdab389 | |||
204915450f | |||
500a690cd0 | |||
d473ce13ee | |||
1adf53a81e | |||
ed942100ec | |||
8abe95309c | |||
5dc5aba42c | |||
bda6f03e15 | |||
69d132401e | |||
e3a9db5d8f | |||
b71a4701d9 | |||
9b85abd75e | |||
7b7b91ea0d | |||
18f6bad48d | |||
fbe548c611 | |||
4e793199fa | |||
43a97c407d | |||
07dcbdb9b0 | |||
60ca24fe0e | |||
6e8144d5d9 | |||
464afb949e | |||
823dc933b8 | |||
883f93cc8c | |||
b26ee09f76 | |||
1eec333501 | |||
5448a48f67 | |||
a10ad42a13 | |||
da23cf685d | |||
79e4b3e3a9 | |||
8472349caf | |||
96b61fbb92 | |||
6246ad19c4 | |||
9b69cc4288 | |||
114153ae97 | |||
ebb844fa52 | |||
bf89ea1cf6 | |||
4076fb4657 | |||
312f377483 | |||
0af3dfedd5 | |||
6f1f201c41 | |||
48f591e5ce | |||
7f85e37540 | |||
341717c89d | |||
afdf7bc2b9 | |||
24c76acf30 | |||
baf06dc363 | |||
645c00b2f7 | |||
0dd46c835c | |||
0dba14074a | |||
8b585fd9f7 | |||
9ede8177df | |||
13ec046f0d | |||
5c4e7b6ee0 | |||
6424934df6 | |||
b2ac959083 | |||
c67d4dae7b | |||
22ad75c5a0 | |||
b45ef8928c | |||
eccf7b08d2 | |||
94eb9e35e2 | |||
79bf1f12f2 | |||
10b33546ef | |||
c52dc58d6f | |||
62af784d37 | |||
aa010b7dea | |||
4a3163b4c8 | |||
c750a204e6 | |||
3313981d54 | |||
57f7d57c76 | |||
64bf293c69 | |||
7b09edf048 | |||
4346773e25 | |||
b0c314526d | |||
dd140ce018 | |||
08aa7808cf | |||
582c165479 | |||
5fb205493a | |||
e346d245e2 | |||
4fece32ca8 | |||
0b79d74a2f | |||
b83c6fbfa3 | |||
dda9c598f1 | |||
8769d2bcd1 | |||
3b7ece3363 | |||
b6025e3f2b | |||
35de331b74 | |||
de11cce154 | |||
d53ba52d32 | |||
9db2fe40eb | |||
57bb8f14fa | |||
761cd59514 | |||
4c2a1c8684 | |||
31bb6d1a68 | |||
cd65179aef | |||
9abd2c63f4 | |||
376e359577 | |||
571e2f8895 | |||
7106ea87e6 | |||
6b65b68ebc | |||
d4c75ce68a | |||
fae330d499 | |||
5e03e157ad | |||
b0c40dc1ab | |||
6840589f4e | |||
19e4aaa16a | |||
e0a7944faa | |||
eeda22d0ba | |||
769f1effb0 | |||
42c7322273 | |||
c8cf6b715e | |||
41f94f7385 | |||
602bdf27a5 | |||
539fa232f8 | |||
f8378c09ba | |||
69fb7ae525 | |||
ee8ad6f92a | |||
f888acbd7c | |||
215691f1c4 | |||
1252dd65a9 | |||
762c27affe | |||
706e1099a1 | |||
9cd66dc969 | |||
5b6b789ab3 | |||
85ff696ae5 | |||
25f8e8318b | |||
61d84c73d0 | |||
f5822c6de8 | |||
b0bd927545 | |||
fde61b7d21 | |||
886ad8442c | |||
7b5869bea8 | |||
3063863c65 | |||
0dfaa19380 | |||
7fea29e874 | |||
2ded2013bf | |||
aa27c28e65 | |||
05a81bebf4 | |||
ce91f2943a | |||
1d8562fb8c | |||
1dfb17b932 | |||
16384c2b20 | |||
48041b2f19 | |||
529bf743db | |||
48bc919a33 | |||
474091c013 | |||
666e5553c2 | |||
ae6f532b1d | |||
b231eba803 | |||
82d903733d | |||
8e2903da86 | |||
d720113ac9 | |||
5db45222c6 | |||
2975509d0f | |||
7e49d073fa | |||
ef3674a296 | |||
6cb7e36f8a | |||
b88f19bb74 | |||
8c3fcf0798 | |||
6b312a7826 | |||
9907e84eee | |||
01f299a7f1 | |||
91f20f6789 | |||
4c1edc3f7e | |||
5fd1e271c5 | |||
593b0497b0 | |||
0907aedcef | |||
0a29e66b62 | |||
3cc4afbcd6 | |||
b3ae6eae04 | |||
3b56b536b6 | |||
9258281546 | |||
e7897be7cd | |||
5ff01de413 | |||
f191ada405 | |||
addd74d09e | |||
4e9d2d0a7f | |||
d04e994d1b | |||
3d870629f2 | |||
8dbe834dc3 | |||
36d8100e17 | |||
b880bf13f8 | |||
1ac08ce404 | |||
689b2ea877 | |||
d1f22ee395 | |||
056ed4802f | |||
bcb65e9a48 | |||
5404ba77d0 | |||
ae54426836 | |||
ee7d84dfbd | |||
3e1ea23036 | |||
d312d2a143 | |||
8c627bd0af | |||
6fb7170556 | |||
50f5c6d8ed | |||
f9d5c5bd37 | |||
45dbb3f828 | |||
8a8a95480e | |||
34139c7efe | |||
f0e7713dce | |||
3ba099b309 | |||
c4a0c759dc | |||
e9a2f88847 | |||
e608acbd1c | |||
42033da08b | |||
69ab0d433b | |||
44a30b7fac | |||
50b2f55583 | |||
da084d6908 | |||
7d51bc0004 | |||
87dbc18452 | |||
5b8d4bba11 | |||
bb4c54106a | |||
1617b2509e | |||
ec293ebd9e | |||
9f9422f0ed | |||
da715e48e2 | |||
702b2e539c | |||
63fc229c12 | |||
c71689a919 | |||
09428bc8c7 | |||
6c7e16d9d4 | |||
315ea2ea3c | |||
83eb9f778a | |||
7923c40b33 | |||
d298adabad | |||
cfcf515f62 | |||
b5deae7ba0 | |||
d991c32435 | |||
dbd1f3f96e | |||
0bd7ab9def | |||
665c275bb7 | |||
7ef2708fca | |||
78b4223795 | |||
0328b4c5f5 | |||
4624dfb472 | |||
fba12c6ddf | |||
60011a5ecf | |||
f4ae58dda2 | |||
8c939feed9 | |||
02ca227085 | |||
1174b0c45c | |||
8940360df4 | |||
bb34e06754 | |||
e06092cb99 | |||
57373b8c5e | |||
317c6788a6 | |||
0a4e0e3228 | |||
d8c492de4a | |||
05d59d587b | |||
7d387fe6aa | |||
4f7a6a06be | |||
344c84cfa6 | |||
bd721a13a3 | |||
92b0b4d43c | |||
d0b0fbf992 | |||
ab334e6962 | |||
1ad6438e60 | |||
4ecec42c9d | |||
84e62598ce | |||
ad7acb93b6 | |||
ac4b4b08fd | |||
d3c308c5a8 | |||
98e0583f34 | |||
020351e20f | |||
f140fef52d | |||
9980a0780a | |||
352497d88c | |||
ba08bfaa45 | |||
dea4513c34 | |||
0eac084aa7 | |||
e17ecf5795 | |||
e94ddcabe0 | |||
acf7eb1ce9 | |||
dcfb7a7ac4 | |||
97c87aa8fa | |||
11f684d803 | |||
ff48eb3d4d | |||
e047b6a870 | |||
c5626bae34 | |||
3eac08f5ba | |||
cc2555bb88 | |||
705e4da789 | |||
9b7a94b5ee | |||
bcdb6d8c2e | |||
eff63a661e | |||
5a756d215d | |||
422262d585 | |||
b761a97660 | |||
7579cd763a | |||
6bc5f60011 | |||
3eb8ca0d13 | |||
a23352be88 | |||
fa5f00a1ff | |||
d3a05adede | |||
f9182bd0f8 | |||
edad52c6ea | |||
cd5e16f017 | |||
310a7d6c04 | |||
ccea26c978 | |||
cf542ac73a | |||
3bf39df255 | |||
910e5e6181 | |||
a396b8c220 | |||
ec1fe6a083 | |||
706c97b9b1 | |||
a04516a879 | |||
0f6dfd39b8 | |||
36ee6d9966 | |||
23793e0fc4 | |||
3409d332e7 | |||
ca1b67a675 | |||
f5eed4f12b | |||
7a10f91330 | |||
6477f4f077 | |||
3731e74696 | |||
c774e4c203 | |||
d4907a2688 | |||
793520926b | |||
bf839e821c | |||
7aeacf2705 | |||
fc62c91c90 | |||
98dd7f8c15 | |||
7a1d25617f | |||
69b3ef326b | |||
fadff2cc5b | |||
43a0ef433e | |||
9a1e7ca83c | |||
b9111b6f52 | |||
be70121f3a | |||
e2986992c7 | |||
9fb46d8fe8 | |||
eab86f5f90 | |||
2f2afe2336 | |||
f7de1ede3f | |||
812ae09a06 | |||
e473cd5e67 | |||
9e5e4fb362 | |||
afa98866e0 | |||
90fa40de34 | |||
e6234c4c4d | |||
8f66d03d99 | |||
8e9da9c84e | |||
759d7e2545 | |||
f4b92bcdfc | |||
f7e2d31f0a | |||
e0fc3784ad | |||
bf5630dc0d | |||
472431752b | |||
c40f9f65a5 | |||
f74af12914 | |||
d169734781 | |||
35b86af2af | |||
706bc8e8db | |||
b542c5b9bd | |||
69800c6d79 | |||
ea9fc3c72e | |||
8b90281355 | |||
92cabced97 | |||
cb645fa288 | |||
bda597a71e | |||
d6a0e284e3 | |||
1795c8c5e3 | |||
c3b1b59118 | |||
a0df0a8fff | |||
049103ab7a | |||
84c63c48ca | |||
20e11bd408 | |||
456760b334 | |||
46e502430e | |||
87b800ebb9 | |||
9fdafb87b4 | |||
1fcfef20b0 | |||
6109505786 | |||
764937dda4 | |||
8bf36315ae | |||
1ea0531ec7 | |||
c47e359262 | |||
f0f9bccb4b | |||
214dcef1ea | |||
4edadd764c | |||
01ebe74974 | |||
84ce5f1c73 | |||
93a2bd36e0 | |||
fdd59e4506 | |||
9b86b1d45b | |||
1a38003bc4 | |||
60ea4d0e96 | |||
6077190a62 | |||
57299b9a29 | |||
bb08da701b | |||
ee593fe5e4 | |||
e8b1b0fab6 | |||
4858c7d82e | |||
ecc9e1d223 | |||
a3cc676ac6 | |||
db7222976e | |||
e1ef86074e | |||
9f4582349d | |||
5dc3fe4fe9 | |||
8446bd2ba5 | |||
9f34d22013 | |||
973d6b5869 | |||
40d2f8a373 | |||
b66f49dc5e | |||
5c150f696c | |||
0246648a2c | |||
532b12c6c0 | |||
34711dc346 | |||
3c231118a6 | |||
a816234ee8 | |||
baa34a7cca | |||
daf1a8266d | |||
4e6ff81674 | |||
84a1b319c8 | |||
16774e66e6 | |||
67b97ade8b | |||
0f04f4bc8a | |||
4c7b172cbe | |||
e91781cbf2 | |||
cf0dc95a76 | |||
9fa7b9b5ea | |||
badbe75d58 | |||
5eee4f9771 | |||
52d28795fa | |||
c675605014 | |||
758a6af678 | |||
6f30cd8a22 | |||
8455e89784 | |||
eee0eb5458 | |||
7e4a191593 | |||
8725ad522f | |||
a610a86579 | |||
24134a06b8 | |||
de6f5309dc | |||
a2e231101e | |||
918024e466 | |||
9e74169d74 | |||
ec93ed3e3d | |||
a7b44e3892 | |||
31b92b392e | |||
2f9494ed52 | |||
7a5c583407 | |||
f60e2860e8 | |||
9c95441402 | |||
1f902d814e | |||
0ab3da88be | |||
e6edace944 | |||
3ee61d5ebb | |||
19d391b9b2 | |||
e462a89189 | |||
d616e73242 | |||
5ec6ccefda | |||
58d7599d6f | |||
0c5f920dfd | |||
67f6482c76 | |||
7b141b0b73 | |||
b17ce16262 | |||
fee7f5060b | |||
76cd164aa4 | |||
582f1540a7 | |||
4d7c953572 | |||
06c01f14c6 | |||
c43431c921 | |||
4e1805ae02 | |||
ac34b9eda0 | |||
3495c79c0c | |||
77799d8f3d | |||
dfdf9ddb45 | |||
86d423ae4d | |||
eff454d103 | |||
51120fdd4f | |||
5242e87026 | |||
269a10fadd | |||
232bf5ebe4 | |||
2904aa06ef | |||
e10c70e776 | |||
2cead226db | |||
2784925a5e | |||
d2a14e8303 | |||
071033ad5c | |||
1e3ed8640c | |||
60a576e541 | |||
eee7e659e9 | |||
7ddfd4394d | |||
f0f2eb9a01 | |||
839f6621eb | |||
7fcaa78de4 | |||
915443b508 | |||
e17a7005a1 | |||
c1846e3bcf | |||
81feff6d0d | |||
9b84d8c248 | |||
26ec562fbf | |||
d10274ca7c | |||
7c68e42a86 | |||
171de939cd | |||
58bded4988 | |||
cb4a970631 | |||
95b5979351 | |||
18d13fdc32 | |||
1a442b793c | |||
765d4f30c7 | |||
2eced89e6f | |||
293102d8c4 | |||
25f5d409f1 | |||
4128b22e85 | |||
487ce00542 | |||
a9cd03da2e | |||
f5fee4c909 | |||
016b08ecf2 | |||
3515a037c5 | |||
d6e413e8ca | |||
f991efd5bc | |||
913c116e7b | |||
8fafb85784 | |||
b0aad89e7a | |||
ce018fd7c8 | |||
afe44e6c6f | |||
e9311f5ceb | |||
b2978133f7 | |||
6b331535c6 | |||
3370052fac | |||
7d8a961374 | |||
e97139919a | |||
81faddafb0 | |||
d0936329aa | |||
9124513584 | |||
e860c339e2 | |||
10c67a57a7 | |||
b10e63b951 | |||
409eeda6ee | |||
bf09c48d62 | |||
aac646d343 | |||
ed90d58e32 | |||
e219f4784c | |||
b5a1c23c50 | |||
14817df2c7 | |||
cc87064915 | |||
aded24e6c6 | |||
a95f8b45f1 | |||
7a3703d8b1 | |||
ca59546ace | |||
2330f363bd | |||
042861b51f | |||
98f42a936e | |||
6d77b0883e | |||
f53d513894 | |||
e6e15ceffa | |||
9d75baf212 | |||
7b45df680e | |||
f93d5339bc | |||
677071e7cb | |||
4fa6fb0546 | |||
0ca614a2c3 | |||
bdfa6c0bc5 | |||
ccb7e86cf1 | |||
03a970e91f | |||
b3e9bb8fec | |||
48b99486b0 | |||
6921e6f2aa | |||
987f54ba08 | |||
09ef1f1721 | |||
3eae7a1875 | |||
21587ae3eb | |||
e5337d8949 | |||
c92a1ba7fe | |||
2066e92f84 | |||
cd943f52a1 | |||
c3424beda9 | |||
b6506d1db8 | |||
4cec3e7e37 | |||
2f3a011ed3 | |||
da9dfabae4 | |||
4c83e9bb56 | |||
090d159766 | |||
14d86339fc | |||
ccf34a9db8 | |||
97af1b6008 | |||
16d33b01f4 | |||
fa318ce706 | |||
accea03d52 | |||
adcdf650a3 | |||
e8e825322b | |||
1b36b10520 | |||
0d37e96678 | |||
2448405e3a | |||
2e773a32ff | |||
d8cba4f045 | |||
07c1ed1c36 | |||
d6711125a9 | |||
b8802edd6d | |||
71bf984e9e | |||
9c9d786194 | |||
bd2cb4b851 | |||
6e77901453 | |||
ebe8a902e5 | |||
304524f6d8 | |||
cb879977d2 | |||
096e238242 | |||
f2d5daffc0 | |||
12275125d2 | |||
3d3b6826e4 | |||
3a8adfe2b8 | |||
14116b6730 | |||
241d3d72af | |||
79e864f4f1 | |||
7812a3c4fc | |||
dbe5e9b4e9 | |||
d743888b8d |
6
.gitignore
vendored
6
.gitignore
vendored
@ -20,4 +20,8 @@ Desktop.ini
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
/nbproject/private/
|
||||
/nbproject/private/
|
||||
|
||||
# Sphinx-doc
|
||||
/docs/build/
|
||||
!/docs/requirements.txt
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -6,3 +6,6 @@
|
||||
path = src/raklib
|
||||
url = https://github.com/PocketMine/RakLib.git
|
||||
branch = master
|
||||
[submodule "src/spl"]
|
||||
path = src/spl
|
||||
url = https://github.com/PocketMine/PocketMine-SPL.git
|
||||
|
5
.mailmap
Normal file
5
.mailmap
Normal file
@ -0,0 +1,5 @@
|
||||
Shoghi Cervantes <shoghicp@gmail.com>
|
||||
Shoghi Cervantes <shoghicp@gmail.com> Shoghi Cervantes <shoghicp@pocketmine.net>
|
||||
Brandon V <brandon15811@gmail.com>
|
||||
Michael Yoo <sekjun9878@gmail.com> Michael Yoo <michael@yoo.id.au>
|
||||
Michael Yoo <sekjun9878@gmail.com> Michael Yoo <sekjun9878@sekjun9878.info>
|
16
.travis.yml
16
.travis.yml
@ -1,23 +1,21 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
|
||||
branches:
|
||||
except:
|
||||
- Core-Rewrite
|
||||
- master
|
||||
- 0.9.0
|
||||
- master
|
||||
|
||||
before_script:
|
||||
- pecl install channel://pecl.php.net/pthreads-2.0.4
|
||||
- mkdir plugins
|
||||
- wget -O plugins/DevTools.phar https://github.com/PocketMine/DevTools/releases/download/v1.9.0/DevTools_v1.9.0.phar
|
||||
- pecl install channel://pecl.php.net/pthreads-2.0.10
|
||||
- pecl install channel://pecl.php.net/weakref-0.2.6
|
||||
- echo | pecl install channel://pecl.php.net/yaml-1.1.1
|
||||
|
||||
script:
|
||||
- php src/tests/ServerSuiteTest.php --no-wizard
|
||||
- php tests/TravisTest.php
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0
|
||||
#webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0
|
||||
|
103
CONTRIBUTING.md
103
CONTRIBUTING.md
@ -2,36 +2,37 @@
|
||||
|
||||
# PocketMine-MP Contribution Guidelines
|
||||
|
||||
Before contributing to PocketMine-MP, please read this. Also, take a look if your contribution fits the PocketMine-MP goals below.
|
||||
|
||||
You must follow these guidelines if you wish to contribute to the PocketMine-MP code base, or participate in issue tracking.
|
||||
|
||||
## I have a question
|
||||
* For questions, please refer to the _#pocketmine_ or _#mcpedevs_ IRC channel on Freenode. There is a [WebIRC](http://webchat.freenode.net?channels=pocketmine,mcpedevs&uio=d4) if you want.
|
||||
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter, but don't expect an inmediate reply.
|
||||
* You can ask directly to _[@PocketMine](https://twitter.com/PocketMine)_ in Twitter, but don't expect an immediate reply.
|
||||
* You may use our [Forum](http://forums.pocketmine.net) to ask questions.
|
||||
* We do not accept questions or support requests in our issue tracker.
|
||||
|
||||
## I want to create an issue
|
||||
* First, use the [Issue Search](https://github.com/PocketMine/PocketMine-MP/search?ref=cmdform&type=Issues) to check if anyone has reported it.
|
||||
* Is your issue related to a Plugin? If so, please contact their original author instead of reporting it here.
|
||||
* And no, we won't update a Plugin because you need it.
|
||||
* When reporting, give as much info as you can, and if the Issue is a crash, give the Crash Dump.
|
||||
* Issues should be written in English.
|
||||
## Creating an Issue
|
||||
- First, use the [Issue Search](https://github.com/PocketMine/PocketMine-MP/search?ref=cmdform&type=Issues) to check if anyone has reported it.
|
||||
- If your issue is related to a plugin, you must contact their original author instead of reporting it here.
|
||||
- If your issue is related to a PocketMine official plugin, or our Android application, you must create an issue on that specific repository.
|
||||
- **Support requests are not bugs.** Issues such as "How do I do this" are not bugs and are closed as soon as a collaborator spots it. They are referred to our Forum to seek assistance.
|
||||
- **No generic titles** such as "Question", "Help", "Crash Report" etc. If an issue has a generic title they will either be closed on the spot, or a collaborator will edit it to describe the actual symptom.
|
||||
- Information must be provided in the issue body, not in the title. No tags are allowed in the title, and do not change the title if the issue has been solved.
|
||||
- Similarly, no generic issue reports. It is the issue submitter's responsibility to provide us an issue that is **trackable, debuggable, reproducible, reported professionally and is an actual bug**. If you do not provide us with a summary or instructions on how to reproduce the issue, it is a support request until the actual bug has been found and therefore the issue is closed.
|
||||
|
||||
## I want a new feature / I want to contribute code
|
||||
## Contributing Code
|
||||
* Use the [Pull Request](https://github.com/PocketMine/PocketMine-MP/pull/new) system, your request will be checked and discussed.
|
||||
* __Create a single branch for that pull request__
|
||||
* If you want to be part of PocketMine-MP, we will ask you to.
|
||||
* Code using the syntax as in PocketMine-MP. See below for an example.
|
||||
* The code must be clear and written in English, comments included.
|
||||
* Use descriptive commit titles
|
||||
* __No merge commits are allowed, or multiple features per pull request__
|
||||
|
||||
**Thanks for contributing to PocketMine-MP!**
|
||||
|
||||
__Thanks for contributing to PocketMine-MP!__
|
||||
|
||||
|
||||
|
||||
### Code syntax
|
||||
### Code Syntax
|
||||
|
||||
It is mainly [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) with a few exceptions.
|
||||
* Opening braces MUST go on the same line.
|
||||
* Opening braces MUST go on the same line, and MUST NOT have spaces before.
|
||||
* `else if` MUST be written as `elseif`. _(It is in PSR-2, but using a SHOULD)_
|
||||
* Control structure keywords or opening braces MUST NOT have one space after them.
|
||||
* Code MUST use tabs for indenting.
|
||||
@ -45,7 +46,7 @@ It is mainly [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accept
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace pocketmine\Example;
|
||||
namespace pocketmine\example;
|
||||
|
||||
class ExampleClass{
|
||||
const EXAMPLE_CLASS_CONSTANT = 1;
|
||||
@ -71,3 +72,69 @@ class ExampleClass{
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### RFC and Voting
|
||||
* These are big Pull Requests or contributions that change important behavior.
|
||||
* RFCs will be tagged with the *PR: RFC* label
|
||||
* A vote will be held once the RFC is ready. All users can vote commenting on the Pull Request
|
||||
* Comments MUST use "Yes" or "No" on the FIRST sentence to signify the vote, except when they don't want it to be counted.
|
||||
* If your comment is a voting comment, specify the reason of your vote or it won't be counted.
|
||||
* After voting has been closed, no further votes will be counted.
|
||||
* An RFC will be rejected if less than 50% + 1 (simple majority) has voted Yes.
|
||||
* If the RFC is approved, Team Members have the final word on its implementation or rejection.
|
||||
* RFCs with complex voting options will specify the vote percentage or other details.
|
||||
|
||||
|
||||
## Bug Tracking for Collaborators
|
||||
|
||||
### Labels
|
||||
To provide a concise bug tracking environment, prevent the issue tracker from over flowing and to keep support requests out of the bug tracker, PocketMine-MP uses a label scheme a bit different from the default GitHub Issues labels.
|
||||
|
||||
PocketMine-MP uses GitHub Issues Labels. There are a total of 12 labels.
|
||||
|
||||
Note: For future reference, labels must not be longer than 15 letters.
|
||||
|
||||
#### Categories
|
||||
Category labels are prefixed by `C:`. Multiple category labels may be applied to a single issue(but try to keep this to a minimum and do not overuse category labels).
|
||||
- C: Core - This label is applied when the bug results in a fatal crash, or is related to neither Gameplay nor Plugin API.
|
||||
- C: Gameplay - This label is applied when the bug effects the gameplay.
|
||||
- C: API - This label is applied when the bug effects the Plugin API.
|
||||
|
||||
#### Pull Requests
|
||||
Pull Requests are prefixed by `PR:`. Only one label may be applied for a Pull Request.
|
||||
- PR: Bug Fix - This label is applied when the Pull Request fixes a bug.
|
||||
- PR: Contribution - This label is applied when the Pull Request contributes code to PocketMine-MP such as a new feature or an improvement.
|
||||
- PR: RFC - Request for Comments
|
||||
|
||||
#### Status
|
||||
Status labels show the status of the issue. Multiple status labels may be applied.
|
||||
- Reproduced - This label is applied when the bug has been reproduced, or multiple people are reporting the same issue and symptoms in which case it is automatically assumed that the bug has been reproduced in different environments.
|
||||
- Debugged - This label is applied when the cause of the bug has been found.
|
||||
- Priority - This label is applied when the bug is easy to fix, or if the scale of the bug is global.
|
||||
- Won't Fix - This label is applied if the bug has been decided not be fixed for some reason. e.g. when the bug benefits gameplay. *This label may only be applied to a closed issue.*
|
||||
|
||||
#### Miscellaneous
|
||||
Miscellaneous labels are labels that show status not related to debugging that bug. The To-Do label and the Mojang label may not be applied to a single issue at the same time.
|
||||
- To-Do - This label is applied when the issue is not a bug, but a feature request or a list of features to be implemented that count towards a milestone.
|
||||
- Mojang - This label is applied when the issue is suspected of being caused by the Minecraft: Pocket Edition client, but has not been confirmed.
|
||||
- Invalid - This label is applied when the issue is reporting a false bug that works as intended, a support request, etc. *This label may only be applied to a closed issue.*
|
||||
|
||||
### Closing Issues
|
||||
To keep the bug tracker clear of non-related issues and to prevent it from overflowing, **issues must be closed as soon as possible** (This may sound unethical, but it is MUCH better than having the BUG TRACKER filled with SUPPORT REQUESTS and "I NEED HELP").
|
||||
|
||||
If an issue does not conform to the "Creating an Issue" guidelines above, the issue should be closed.
|
||||
|
||||
### Milestones
|
||||
PocketMine-MP uses GitHub Milestones to set a goal for a new release. A milestone is set on the following occasions.
|
||||
|
||||
- A new Beta release
|
||||
- A new Stable release
|
||||
|
||||
A milestone must use the following format:
|
||||
```
|
||||
Alpha_<version_number> [release_title][release_version]
|
||||
```
|
||||
For example:
|
||||
```
|
||||
Alpha_1.4 beta2
|
||||
```
|
||||
|
@ -21,6 +21,8 @@ __PocketMine-MP is a free, open-source software that creates Minecraft: Pocket E
|
||||
|
||||
### [Forums](http://forums.pocketmine.net/)
|
||||
|
||||
### [Documentation](http://pocketmine-mp.readthedocs.org/)
|
||||
|
||||
### [Plugin Repository](http://plugins.pocketmine.net/)
|
||||
|
||||
<!--## [FAQ: Frequently Asked Questions](https://github.com/PocketMine/PocketMine-MP/wiki/Frequently-Asked-Questions)-->
|
||||
|
@ -30,78 +30,78 @@ abstract class Achievement{
|
||||
/**
|
||||
* @var array[]
|
||||
*/
|
||||
public static $list = array(
|
||||
public static $list = [
|
||||
/*"openInventory" => array(
|
||||
"name" => "Taking Inventory",
|
||||
"requires" => [],
|
||||
),*/
|
||||
"mineWood" => array(
|
||||
"mineWood" => [
|
||||
"name" => "Getting Wood",
|
||||
"requires" => array( //"openInventory",
|
||||
),
|
||||
),
|
||||
"buildWorkBench" => array(
|
||||
"requires" => [ //"openInventory",
|
||||
],
|
||||
],
|
||||
"buildWorkBench" => [
|
||||
"name" => "Benchmarking",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"mineWood",
|
||||
),
|
||||
),
|
||||
"buildPickaxe" => array(
|
||||
],
|
||||
],
|
||||
"buildPickaxe" => [
|
||||
"name" => "Time to Mine!",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
),
|
||||
),
|
||||
"buildFurnace" => array(
|
||||
],
|
||||
],
|
||||
"buildFurnace" => [
|
||||
"name" => "Hot Topic",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"buildPickaxe",
|
||||
),
|
||||
),
|
||||
"acquireIron" => array(
|
||||
],
|
||||
],
|
||||
"acquireIron" => [
|
||||
"name" => "Acquire hardware",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"buildFurnace",
|
||||
),
|
||||
),
|
||||
"buildHoe" => array(
|
||||
],
|
||||
],
|
||||
"buildHoe" => [
|
||||
"name" => "Time to Farm!",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
),
|
||||
),
|
||||
"makeBread" => array(
|
||||
],
|
||||
],
|
||||
"makeBread" => [
|
||||
"name" => "Bake Bread",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"buildHoe",
|
||||
),
|
||||
),
|
||||
"bakeCake" => array(
|
||||
],
|
||||
],
|
||||
"bakeCake" => [
|
||||
"name" => "The Lie",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"buildHoe",
|
||||
),
|
||||
),
|
||||
"buildBetterPickaxe" => array(
|
||||
],
|
||||
],
|
||||
"buildBetterPickaxe" => [
|
||||
"name" => "Getting an Upgrade",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"buildPickaxe",
|
||||
),
|
||||
),
|
||||
"buildSword" => array(
|
||||
],
|
||||
],
|
||||
"buildSword" => [
|
||||
"name" => "Time to Strike!",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
),
|
||||
),
|
||||
"diamonds" => array(
|
||||
],
|
||||
],
|
||||
"diamonds" => [
|
||||
"name" => "DIAMONDS!",
|
||||
"requires" => array(
|
||||
"requires" => [
|
||||
"acquireIron",
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
||||
);
|
||||
];
|
||||
|
||||
|
||||
public static function broadcast(Player $player, $achievementId){
|
||||
@ -120,10 +120,10 @@ abstract class Achievement{
|
||||
|
||||
public static function add($achievementId, $achievementName, array $requires = []){
|
||||
if(!isset(Achievement::$list[$achievementId])){
|
||||
Achievement::$list[$achievementId] = array(
|
||||
Achievement::$list[$achievementId] = [
|
||||
"name" => $achievementName,
|
||||
"requires" => $requires,
|
||||
);
|
||||
];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -19,12 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
interface LoggerAttachment{
|
||||
namespace pocketmine;
|
||||
|
||||
class CompatibleClassLoader extends \BaseClassLoader{
|
||||
|
||||
/**
|
||||
* @param mixed $level
|
||||
* @param string $message
|
||||
* @deprecated
|
||||
*/
|
||||
public function log($level, $message);
|
||||
|
||||
public function add($namespace, $paths){
|
||||
$this->addPath(array_shift($paths));
|
||||
}
|
||||
}
|
248
src/pocketmine/CrashDump.php
Normal file
248
src/pocketmine/CrashDump.php
Normal file
@ -0,0 +1,248 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\plugin\PluginBase;
|
||||
use pocketmine\plugin\PluginLoadOrder;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\VersionString;
|
||||
use raklib\RakLib;
|
||||
|
||||
class CrashDump{
|
||||
|
||||
/** @var Server */
|
||||
private $server;
|
||||
private $fp;
|
||||
private $time;
|
||||
private $data = [];
|
||||
private $encodedData = null;
|
||||
private $path;
|
||||
|
||||
public function __construct(Server $server){
|
||||
$this->time = time();
|
||||
$this->server = $server;
|
||||
$this->path = $this->server->getDataPath() . "CrashDump_" . date("D_M_j-H.i.s-T_Y", $this->time) . ".log";
|
||||
$this->fp = fopen($this->path, "wb");
|
||||
$this->data["time"] = $this->time;
|
||||
$this->addLine($this->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", $this->time));
|
||||
$this->addLine();
|
||||
$this->baseCrash();
|
||||
$this->generalData();
|
||||
$this->pluginsData();
|
||||
|
||||
$this->extraData();
|
||||
|
||||
$this->encodeData();
|
||||
}
|
||||
|
||||
public function getPath(){
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getEncodedData(){
|
||||
return $this->encodedData;
|
||||
}
|
||||
|
||||
public function getData(){
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
private function encodeData(){
|
||||
$this->addLine();
|
||||
$this->addLine("----------------------REPORT THE DATA BELOW THIS LINE-----------------------");
|
||||
$this->addLine();
|
||||
$this->addLine("===BEGIN CRASH DUMP===");
|
||||
$this->encodedData = zlib_encode(json_encode($this->data, JSON_UNESCAPED_SLASHES), ZLIB_ENCODING_DEFLATE, 9);
|
||||
foreach(str_split(base64_encode($this->encodedData), 76) as $line){
|
||||
$this->addLine($line);
|
||||
}
|
||||
$this->addLine("===END CRASH DUMP===");
|
||||
}
|
||||
|
||||
private function pluginsData(){
|
||||
if(class_exists("pocketmine\\plugin\\PluginManager", false)){
|
||||
$this->addLine();
|
||||
$this->addLine("Loaded plugins:");
|
||||
$this->data["plugins"] = [];
|
||||
foreach($this->server->getPluginManager()->getPlugins() as $p){
|
||||
$d = $p->getDescription();
|
||||
$this->data["plugins"][$d->getName()] = [
|
||||
"name" => $d->getName(),
|
||||
"version" => $d->getVersion(),
|
||||
"authors" => $d->getAuthors(),
|
||||
"api" => $d->getCompatibleApis(),
|
||||
"enabled" => $p->isEnabled(),
|
||||
"depends" => $d->getDepend(),
|
||||
"softDepends" => $d->getSoftDepend(),
|
||||
"main" => $d->getMain(),
|
||||
"load" => $d->getOrder() === PluginLoadOrder::POSTWORLD ? "POSTWORLD" : "STARTUP",
|
||||
"website" => $d->getWebsite()
|
||||
];
|
||||
$this->addLine($d->getName() . " " . $d->getVersion() . " by " . implode(", ", $d->getAuthors()) . " for API(s) " . implode(", ", $d->getCompatibleApis()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function extraData(){
|
||||
global $arguments;
|
||||
|
||||
if($this->server->getProperty("auto-report.send-settings", true) !== false){
|
||||
$this->data["parameters"] = (array) $arguments;
|
||||
$this->data["server.properties"] = @file_get_contents($this->server->getDataPath() . "server.properties");
|
||||
$this->data["server.properties"] = preg_replace("#^rcon\\.password=(.*)$#m", "rcon.password=******", $this->data["server.properties"]);
|
||||
$this->data["pocketmine.yml"] = @file_get_contents($this->server->getDataPath() . "pocketmine.yml");
|
||||
}else{
|
||||
$this->data["pocketmine.yml"] = "";
|
||||
$this->data["server.properties"] = "";
|
||||
$this->data["parameters"] = [];
|
||||
}
|
||||
$extensions = [];
|
||||
foreach(get_loaded_extensions() as $ext){
|
||||
$extensions[$ext] = phpversion($ext);
|
||||
}
|
||||
$this->data["extensions"] = $extensions;
|
||||
|
||||
if($this->server->getProperty("auto-report.send-phpinfo", true) !== false){
|
||||
ob_start();
|
||||
phpinfo();
|
||||
$this->data["phpinfo"] = ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
private function baseCrash(){
|
||||
global $lastExceptionError, $lastError;
|
||||
|
||||
if(isset($lastExceptionError)){
|
||||
$error = $lastExceptionError;
|
||||
}else{
|
||||
$error = (array) error_get_last();
|
||||
$error["trace"] = @getTrace(4);
|
||||
$errorConversion = [
|
||||
E_ERROR => "E_ERROR",
|
||||
E_WARNING => "E_WARNING",
|
||||
E_PARSE => "E_PARSE",
|
||||
E_NOTICE => "E_NOTICE",
|
||||
E_CORE_ERROR => "E_CORE_ERROR",
|
||||
E_CORE_WARNING => "E_CORE_WARNING",
|
||||
E_COMPILE_ERROR => "E_COMPILE_ERROR",
|
||||
E_COMPILE_WARNING => "E_COMPILE_WARNING",
|
||||
E_USER_ERROR => "E_USER_ERROR",
|
||||
E_USER_WARNING => "E_USER_WARNING",
|
||||
E_USER_NOTICE => "E_USER_NOTICE",
|
||||
E_STRICT => "E_STRICT",
|
||||
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
|
||||
E_DEPRECATED => "E_DEPRECATED",
|
||||
E_USER_DEPRECATED => "E_USER_DEPRECATED",
|
||||
];
|
||||
$error["fullFile"] = $error["file"];
|
||||
$error["file"] = cleanPath($error["file"]);
|
||||
$error["type"] = isset($errorConversion[$error["type"]]) ? $errorConversion[$error["type"]] : $error["type"];
|
||||
if(($pos = strpos($error["message"], "\n")) !== false){
|
||||
$error["message"] = substr($error["message"], 0, $pos);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($lastError)){
|
||||
$this->data["lastError"] = $lastError;
|
||||
}
|
||||
|
||||
$this->data["error"] = $error;
|
||||
unset($this->data["error"]["fullFile"]);
|
||||
unset($this->data["error"]["trace"]);
|
||||
$this->addLine("Error: " . $error["message"]);
|
||||
$this->addLine("File: " . $error["file"]);
|
||||
$this->addLine("Line: " . $error["line"]);
|
||||
$this->addLine("Type: " . $error["type"]);
|
||||
|
||||
if(strpos($error["file"], "src/pocketmine/") === false and strpos($error["file"], "src/raklib/") === false and file_exists($error["fullFile"])){
|
||||
$this->addLine();
|
||||
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
||||
$this->data["plugin"] = true;
|
||||
|
||||
$reflection = new \ReflectionClass(PluginBase::class);
|
||||
$file = $reflection->getProperty("file");
|
||||
$file->setAccessible(true);
|
||||
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
||||
$filePath = \pocketmine\cleanPath($file->getValue($plugin));
|
||||
if(strpos($error["file"], $filePath) === 0){
|
||||
$this->data["plugin"] = $plugin->getName();
|
||||
$this->addLine("BAD PLUGIN: " . $plugin->getDescription()->getFullName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$this->data["plugin"] = false;
|
||||
}
|
||||
|
||||
$this->addLine();
|
||||
$this->addLine("Code:");
|
||||
$this->data["code"] = [];
|
||||
|
||||
if($this->server->getProperty("auto-report.send-code", true) !== false){
|
||||
$file = @file($error["fullFile"], FILE_IGNORE_NEW_LINES);
|
||||
for($l = max(0, $error["line"] - 10); $l < $error["line"] + 10; ++$l){
|
||||
$this->addLine("[" . ($l + 1) . "] " . @$file[$l]);
|
||||
$this->data["code"][$l + 1] = @$file[$l];
|
||||
}
|
||||
}
|
||||
|
||||
$this->addLine();
|
||||
$this->addLine("Backtrace:");
|
||||
foreach(($this->data["trace"] = $error["trace"]) as $line){
|
||||
$this->addLine($line);
|
||||
}
|
||||
$this->addLine();
|
||||
}
|
||||
|
||||
private function generalData(){
|
||||
$version = new VersionString();
|
||||
$this->data["general"] = [];
|
||||
$this->data["general"]["version"] = $version->get(false);
|
||||
$this->data["general"]["build"] = $version->getBuild();
|
||||
$this->data["general"]["protocol"] = Info::CURRENT_PROTOCOL;
|
||||
$this->data["general"]["api"] = \pocketmine\API_VERSION;
|
||||
$this->data["general"]["git"] = \pocketmine\GIT_COMMIT;
|
||||
$this->data["general"]["raklib"] = RakLib::VERSION;
|
||||
$this->data["general"]["uname"] = php_uname("a");
|
||||
$this->data["general"]["php"] = phpversion();
|
||||
$this->data["general"]["zend"] = zend_version();
|
||||
$this->data["general"]["php_os"] = PHP_OS;
|
||||
$this->data["general"]["os"] = Utils::getOS();
|
||||
$this->addLine("PocketMine-MP version: " . $version->get(false) . " #" . $version->getBuild() . " [Protocol " . Info::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
||||
$this->addLine("Git commit: " . GIT_COMMIT);
|
||||
$this->addLine("uname -a: " . php_uname("a"));
|
||||
$this->addLine("PHP Version: " . phpversion());
|
||||
$this->addLine("Zend version: " . zend_version());
|
||||
$this->addLine("OS : " . PHP_OS . ", " . Utils::getOS());
|
||||
}
|
||||
|
||||
public function addLine($line = ""){
|
||||
fwrite($this->fp, $line . PHP_EOL);
|
||||
}
|
||||
|
||||
public function add($str){
|
||||
fwrite($this->fp, $str);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -65,19 +65,22 @@ namespace {
|
||||
}
|
||||
|
||||
namespace pocketmine {
|
||||
use LogLevel;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\Installer;
|
||||
use raklib\RakLib;
|
||||
|
||||
const VERSION = "Alpha_1.4dev";
|
||||
const API_VERSION = "1.1.0";
|
||||
const API_VERSION = "1.7.1";
|
||||
const CODENAME = "絶好(Zekkou)ケーキ(Cake)";
|
||||
const MINECRAFT_VERSION = "v0.9.1 alpha";
|
||||
const PHP_VERSION = "5.5";
|
||||
const MINECRAFT_VERSION = "v0.10.0 alpha";
|
||||
|
||||
/*
|
||||
* Startup code. Do not look at it, it may harm you.
|
||||
* Most of them are hacks to fix date-related bugs, or basic functions used after this
|
||||
* This is the only non-class based file on this project.
|
||||
* Enjoy it as much as I did writing it. I don't want to do it again.
|
||||
*/
|
||||
|
||||
if(\Phar::running(true) !== ""){
|
||||
@define("pocketmine\\PATH", \Phar::running(true) . "/");
|
||||
@ -85,75 +88,216 @@ namespace pocketmine {
|
||||
@define("pocketmine\\PATH", \getcwd() . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
if(!class_exists("SplClassLoader", false)){
|
||||
require_once(\pocketmine\PATH . "src/spl/SplClassLoader.php");
|
||||
if(!extension_loaded("pthreads")){
|
||||
echo "[CRITICAL] Unable to find the pthreads extension." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$autoloader = new \SplClassLoader();
|
||||
$autoloader->setMode(\SplAutoloader::MODE_DEBUG);
|
||||
$autoloader->add("pocketmine", [
|
||||
\pocketmine\PATH . "src"
|
||||
]);
|
||||
if(!class_exists("ClassLoader", false)){
|
||||
require_once(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||
require_once(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||
require_once(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
|
||||
}
|
||||
|
||||
$autoloader = new CompatibleClassLoader();
|
||||
$autoloader->addPath(\pocketmine\PATH . "src");
|
||||
$autoloader->addPath(\pocketmine\PATH . "src" . DIRECTORY_SEPARATOR . "spl");
|
||||
$autoloader->addPath(\pocketmine\PATH . "src" . DIRECTORY_SEPARATOR . "raklib");
|
||||
$autoloader->register(true);
|
||||
if(!class_exists("raklib\\RakLib", false)){
|
||||
require(\pocketmine\PATH . "src/raklib/raklib/RakLib.php");
|
||||
}
|
||||
RakLib::bootstrap($autoloader);
|
||||
|
||||
//Startup code. Do not look at it, it can harm you. Most of them are hacks to fix date-related bugs, or basic functions used after this
|
||||
|
||||
set_time_limit(0); //Who set it to 30 seconds?!?!
|
||||
|
||||
if(ini_get("date.timezone") == ""){ //No Timezone set
|
||||
date_default_timezone_set("GMT");
|
||||
if(strpos(" " . strtoupper(php_uname("s")), " WIN") !== false){
|
||||
$time = time();
|
||||
$time -= $time % 60;
|
||||
//TODO: Parse different time & date formats by region. ¬¬ world
|
||||
//Example: USA
|
||||
exec("time.exe /T", $hour);
|
||||
$i = array_map("intval", explode(":", trim($hour[0])));
|
||||
exec("date.exe /T", $date);
|
||||
$j = array_map("intval", explode(substr($date[0], 2, 1), trim($date[0])));
|
||||
$offset = round((mktime($i[0], $i[1], 0, $j[1], $j[0], $j[2]) - $time) / 60) * 60;
|
||||
}else{
|
||||
exec("date +%s", $t);
|
||||
$offset = round((intval(trim($t[0])) - time()) / 60) * 60;
|
||||
}
|
||||
|
||||
$daylight = (int) date("I");
|
||||
$d = timezone_name_from_abbr("", $offset, $daylight);
|
||||
@ini_set("date.timezone", $d);
|
||||
date_default_timezone_set($d);
|
||||
}else{
|
||||
$d = @date_default_timezone_get();
|
||||
if(strpos($d, "/") === false){
|
||||
$d = timezone_name_from_abbr($d);
|
||||
@ini_set("date.timezone", $d);
|
||||
date_default_timezone_set($d);
|
||||
}
|
||||
}
|
||||
|
||||
gc_disable();
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
gc_enable();
|
||||
error_reporting(-1);
|
||||
ini_set("allow_url_fopen", 1);
|
||||
ini_set("display_errors", 1);
|
||||
ini_set("display_startup_errors", 1);
|
||||
ini_set("default_charset", "utf-8");
|
||||
|
||||
ini_set("memory_limit", "128M"); //Default
|
||||
ini_set("memory_limit", "256M"); //Default
|
||||
define("pocketmine\\START_TIME", microtime(true));
|
||||
|
||||
$opts = getopt("", array("enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard"));
|
||||
$opts = getopt("", ["enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard", "enable-profiler"]);
|
||||
|
||||
define("pocketmine\\DATA", isset($opts["data"]) ? realpath($opts["data"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
|
||||
define("pocketmine\\PLUGIN_PATH", isset($opts["plugins"]) ? realpath($opts["plugins"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
||||
define("pocketmine\\DATA", isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
|
||||
define("pocketmine\\PLUGIN_PATH", isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
||||
|
||||
define("pocketmine\\ANSI", ((strpos(strtoupper(php_uname("s")), "WIN") === false or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"])));
|
||||
define("pocketmine\\ANSI", (Utils::getOS() !== "win" or isset($opts["enable-ansi"])) and !isset($opts["disable-ansi"]));
|
||||
|
||||
|
||||
@mkdir(\pocketmine\DATA, 0777, true);
|
||||
|
||||
//Logger has a dependency on timezone, so we'll set it to UTC until we can get the actual timezone.
|
||||
date_default_timezone_set("UTC");
|
||||
$logger = new MainLogger(\pocketmine\DATA . "server.log", \pocketmine\ANSI);
|
||||
|
||||
if(!ini_get("date.timezone")){
|
||||
if(($timezone = detect_system_timezone()) and date_default_timezone_set($timezone)){
|
||||
//Success! Timezone has already been set and validated in the if statement.
|
||||
//This here is just for redundancy just in case some program wants to read timezone data from the ini.
|
||||
ini_set("date.timezone", $timezone);
|
||||
}else{
|
||||
//If system timezone detection fails or timezone is an invalid value.
|
||||
if($response = Utils::getURL("http://ip-api.com/json")
|
||||
and $ip_geolocation_data = json_decode($response, true)
|
||||
and $ip_geolocation_data['status'] != 'fail'
|
||||
and date_default_timezone_set($ip_geolocation_data['timezone']))
|
||||
{
|
||||
//Again, for redundancy.
|
||||
ini_set("date.timezone", $ip_geolocation_data['timezone']);
|
||||
}else{
|
||||
ini_set("date.timezone", "UTC");
|
||||
date_default_timezone_set("UTC");
|
||||
$logger->warning("Timezone could not be automatically determined. An incorrect timezone will result in incorrect timestamps on console logs. It has been set to \"UTC\" by default. You can change it on the php.ini file.");
|
||||
}
|
||||
}
|
||||
}else{
|
||||
/*
|
||||
* This is here so that people don't come to us complaining and fill up the issue tracker when they put
|
||||
* an incorrect timezone abbreviation in php.ini apparently.
|
||||
*/
|
||||
$default_timezone = date_default_timezone_get();
|
||||
if(strpos($default_timezone, "/") === false){
|
||||
$default_timezone = timezone_name_from_abbr($default_timezone);
|
||||
ini_set("date.timezone", $default_timezone);
|
||||
date_default_timezone_set($default_timezone);
|
||||
}
|
||||
}
|
||||
|
||||
function detect_system_timezone(){
|
||||
switch(Utils::getOS()){
|
||||
case 'win':
|
||||
$regex = '/(UTC)(\+*\-*\d*\d*\:*\d*\d*)/';
|
||||
|
||||
/*
|
||||
* wmic timezone get Caption
|
||||
* Get the timezone offset
|
||||
*
|
||||
* Sample Output var_dump
|
||||
* array(3) {
|
||||
* [0] =>
|
||||
* string(7) "Caption"
|
||||
* [1] =>
|
||||
* string(20) "(UTC+09:30) Adelaide"
|
||||
* [2] =>
|
||||
* string(0) ""
|
||||
* }
|
||||
*/
|
||||
exec("wmic timezone get Caption", $output);
|
||||
|
||||
$string = trim(implode("\n", $output));
|
||||
|
||||
//Detect the Time Zone string
|
||||
preg_match($regex, $string, $matches);
|
||||
|
||||
if(!isset($matches[2]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$offset = $matches[2];
|
||||
|
||||
if($offset == ""){
|
||||
return "UTC";
|
||||
}
|
||||
|
||||
return parse_offset($offset);
|
||||
break;
|
||||
case 'linux':
|
||||
// Ubuntu / Debian.
|
||||
if(file_exists('/etc/timezone')){
|
||||
$data = file_get_contents('/etc/timezone');
|
||||
if($data){
|
||||
return trim($data);
|
||||
}
|
||||
}
|
||||
|
||||
// RHEL / CentOS
|
||||
if(file_exists('/etc/sysconfig/clock')){
|
||||
$data = parse_ini_file('/etc/sysconfig/clock');
|
||||
if(!empty($data['ZONE'])){
|
||||
return trim($data['ZONE']);
|
||||
}
|
||||
}
|
||||
|
||||
//Portable method for incompatible linux distributions.
|
||||
|
||||
$offset = trim(exec('date +%:z'));
|
||||
|
||||
if($offset == "+00:00"){
|
||||
return "UTC";
|
||||
}
|
||||
|
||||
return parse_offset($offset);
|
||||
break;
|
||||
case 'mac':
|
||||
if(is_link('/etc/localtime')){
|
||||
$filename = readlink('/etc/localtime');
|
||||
if(strpos($filename, '/usr/share/zoneinfo/') === 0){
|
||||
$timezone = substr($filename, 20);
|
||||
return trim($timezone);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $offset In the format of +09:00, +02:00, -04:00 etc.
|
||||
* @return string
|
||||
*/
|
||||
function parse_offset($offset){
|
||||
//Make signed offsets unsigned for date_parse
|
||||
if(strpos($offset, '-') !== false){
|
||||
$negative_offset = true;
|
||||
$offset = str_replace('-', '', $offset);
|
||||
}else{
|
||||
if(strpos($offset, '+') !== false){
|
||||
$negative_offset = false;
|
||||
$offset = str_replace('+', '', $offset);
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$parsed = date_parse($offset);
|
||||
$offset = $parsed['hour'] * 3600 + $parsed['minute'] * 60 + $parsed['second'];
|
||||
|
||||
//After date_parse is done, put the sign back
|
||||
if($negative_offset == true){
|
||||
$offset = -abs($offset);
|
||||
}
|
||||
|
||||
//And then, look the offset up.
|
||||
//timezone_name_from_abbr is not used because it returns false on some(most) offsets because it's mapping function is weird.
|
||||
//That's been a bug in PHP since 2008!
|
||||
foreach(timezone_abbreviations_list() as $zones){
|
||||
foreach($zones as $timezone){
|
||||
if($timezone['offset'] == $offset){
|
||||
return $timezone['timezone_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(isset($opts["enable-profiler"])){
|
||||
if(function_exists("profiler_enable")){
|
||||
\profiler_enable();
|
||||
$logger->notice("Execution is being profiled");
|
||||
}else{
|
||||
$logger->notice("No profiler found. Please install https://github.com/krakjoe/profiler");
|
||||
}
|
||||
}
|
||||
|
||||
function kill($pid){
|
||||
switch(Utils::getOS()){
|
||||
case "win":
|
||||
@ -166,62 +310,46 @@ namespace pocketmine {
|
||||
}
|
||||
}
|
||||
|
||||
function getTrace($start = 1){
|
||||
$e = new \Exception();
|
||||
$trace = $e->getTrace();
|
||||
function getTrace($start = 1, $trace = null){
|
||||
if($trace === null){
|
||||
if(function_exists("xdebug_get_function_stack")){
|
||||
$trace = array_reverse(xdebug_get_function_stack());
|
||||
}else{
|
||||
$e = new \Exception();
|
||||
$trace = $e->getTrace();
|
||||
}
|
||||
}
|
||||
|
||||
$messages = [];
|
||||
$j = 0;
|
||||
for($i = (int) $start; isset($trace[$i]); ++$i, ++$j){
|
||||
$params = "";
|
||||
if(isset($trace[$i]["args"])){
|
||||
foreach($trace[$i]["args"] as $name => $value){
|
||||
if(isset($trace[$i]["args"]) or isset($trace[$i]["params"])){
|
||||
if(isset($trace[$i]["args"])){
|
||||
$args = $trace[$i]["args"];
|
||||
}else{
|
||||
$args = $trace[$i]["params"];
|
||||
}
|
||||
foreach($args as $name => $value){
|
||||
$params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . @strval($value)) . ", ";
|
||||
}
|
||||
}
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? $trace[$i]["file"] : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . $trace[$i]["type"] : "") . $trace[$i]["function"] . "(" . substr($params, 0, -2) . ")";
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . substr($params, 0, -2) . ")";
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
function error_handler($errno, $errstr, $errfile, $errline){
|
||||
if(error_reporting() === 0){ //@ error-control
|
||||
return false;
|
||||
}
|
||||
$errorConversion = array(
|
||||
E_ERROR => "E_ERROR",
|
||||
E_WARNING => "E_WARNING",
|
||||
E_PARSE => "E_PARSE",
|
||||
E_NOTICE => "E_NOTICE",
|
||||
E_CORE_ERROR => "E_CORE_ERROR",
|
||||
E_CORE_WARNING => "E_CORE_WARNING",
|
||||
E_COMPILE_ERROR => "E_COMPILE_ERROR",
|
||||
E_COMPILE_WARNING => "E_COMPILE_WARNING",
|
||||
E_USER_ERROR => "E_USER_ERROR",
|
||||
E_USER_WARNING => "E_USER_WARNING",
|
||||
E_USER_NOTICE => "E_USER_NOTICE",
|
||||
E_STRICT => "E_STRICT",
|
||||
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
|
||||
E_DEPRECATED => "E_DEPRECATED",
|
||||
E_USER_DEPRECATED => "E_USER_DEPRECATED",
|
||||
);
|
||||
$type = ($errno === E_ERROR or $errno === E_WARNING or $errno === E_USER_ERROR or $errno === E_USER_WARNING) ? LogLevel::ERROR : LogLevel::NOTICE;
|
||||
$errno = isset($errorConversion[$errno]) ? $errorConversion[$errno] : $errno;
|
||||
$logger = MainLogger::getLogger();
|
||||
$logger->log($type, "A $errno error happened: \"$errstr\" in \"$errfile\" at line $errline");
|
||||
foreach(getTrace() as $i => $line){
|
||||
$logger->debug($line);
|
||||
}
|
||||
|
||||
return true;
|
||||
function cleanPath($path){
|
||||
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
|
||||
}
|
||||
|
||||
set_error_handler("\\pocketmine\\error_handler", E_ALL);
|
||||
set_error_handler([\ExceptionHandler::class, "handler"], -1);
|
||||
|
||||
$errors = 0;
|
||||
|
||||
if(version_compare("5.4.0", PHP_VERSION) > 0){
|
||||
$logger->critical("Use PHP >= 5.4.0");
|
||||
if(version_compare("5.6.0", PHP_VERSION) > 0){
|
||||
$logger->critical("You must use PHP >= 5.6");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
@ -235,18 +363,13 @@ namespace pocketmine {
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("pthreads")){
|
||||
$logger->critical("Unable to find the pthreads extension.");
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "2.0.8") < 0){
|
||||
$logger->critical("pthreads >= 2.0.8 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}else{
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "2.0.4") < 0){
|
||||
$logger->critical("pthreads >= 2.0.4 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(!extension_loaded("uopz")){
|
||||
@ -313,12 +436,36 @@ namespace pocketmine {
|
||||
$logger->warning("Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||
}
|
||||
|
||||
ThreadManager::init();
|
||||
$server = new Server($autoloader, $logger, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
$server->start();
|
||||
|
||||
$logger->info("Stopping other threads");
|
||||
|
||||
foreach(ThreadManager::getInstance()->getAll() as $id => $thread){
|
||||
if($thread->isRunning()){
|
||||
$logger->debug("Stopping " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
||||
if($thread instanceof Thread){
|
||||
$thread->kill();
|
||||
sleep(1);
|
||||
if($thread->isRunning()){
|
||||
$thread->detach();
|
||||
}
|
||||
}elseif($thread instanceof Worker){
|
||||
$thread->kill();
|
||||
sleep(1);
|
||||
if($thread->isRunning()){
|
||||
$thread->detach();
|
||||
}
|
||||
}
|
||||
}elseif(!$thread->isJoined()){
|
||||
$logger->debug("Joining " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
||||
$thread->join();
|
||||
}
|
||||
}
|
||||
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
|
||||
kill(getmypid());
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,13 +19,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
interface LogLevel{
|
||||
const EMERGENCY = "emergency";
|
||||
const ALERT = "alert";
|
||||
const CRITICAL = "critical";
|
||||
const ERROR = "error";
|
||||
const WARNING = "warning";
|
||||
const NOTICE = "notice";
|
||||
const INFO = "info";
|
||||
const DEBUG = "debug";
|
||||
namespace pocketmine;
|
||||
|
||||
/**
|
||||
* This class must be extended by all custom threading classes
|
||||
*/
|
||||
abstract class Thread extends \Thread{
|
||||
|
||||
public final function start($options = PTHREADS_INHERIT_ALL){
|
||||
ThreadManager::getInstance()->add($this);
|
||||
|
||||
return parent::start($options);
|
||||
}
|
||||
}
|
69
src/pocketmine/ThreadManager.php
Normal file
69
src/pocketmine/ThreadManager.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
class ThreadManager extends \Threaded{
|
||||
|
||||
/** @var ThreadManager */
|
||||
private static $instance = null;
|
||||
|
||||
public static function init(){
|
||||
self::$instance = new ThreadManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ThreadManager
|
||||
*/
|
||||
public static function getInstance(){
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Worker|Thread $thread
|
||||
*/
|
||||
public function add($thread){
|
||||
if($thread instanceof Thread or $thread instanceof Worker){
|
||||
$this->{spl_object_hash($thread)} = $thread;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Worker|Thread $thread
|
||||
*/
|
||||
public function remove($thread){
|
||||
if($thread instanceof Thread or $thread instanceof Worker){
|
||||
unset($this->{spl_object_hash($thread)});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Worker[]|Thread[]
|
||||
*/
|
||||
public function getAll(){
|
||||
$array = [];
|
||||
foreach($this as $key => $thread){
|
||||
$array[$key] = $thread;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
34
src/pocketmine/Worker.php
Normal file
34
src/pocketmine/Worker.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
/**
|
||||
* This class must be extended by all custom threading classes
|
||||
*/
|
||||
abstract class Worker extends \Worker{
|
||||
|
||||
public final function start($options = PTHREADS_INHERIT_ALL){
|
||||
ThreadManager::getInstance()->add($this);
|
||||
|
||||
return parent::start($options);
|
||||
}
|
||||
}
|
@ -29,8 +29,8 @@ class AcaciaWoodStairs extends Stair{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -21,30 +21,31 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
|
||||
/**
|
||||
* Air block
|
||||
*/
|
||||
class Air extends Transparent{
|
||||
public $isActivable = false;
|
||||
public $breakable = false;
|
||||
public $isFlowable = true;
|
||||
public $isTransparent = true;
|
||||
public $isReplaceable = true;
|
||||
public $isPlaceable = false;
|
||||
public $hasPhysics = false;
|
||||
public $isSolid = false;
|
||||
public $isFullBlock = true;
|
||||
protected $id = self::AIR;
|
||||
protected $meta = 0;
|
||||
protected $name = "Air";
|
||||
protected $hardness = 0;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::AIR, 0, "Air");
|
||||
$this->isActivable = false;
|
||||
$this->breakable = false;
|
||||
$this->isFlowable = true;
|
||||
$this->isTransparent = true;
|
||||
$this->isReplaceable = true;
|
||||
$this->isPlaceable = false;
|
||||
$this->hasPhysics = false;
|
||||
$this->isSolid = false;
|
||||
$this->isFullBlock = true;
|
||||
$this->hardness = 0;
|
||||
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -22,6 +22,8 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\network\protocol\ChatPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -33,14 +35,30 @@ class Bed extends Transparent{
|
||||
$this->hardness = 1;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 0.5625,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
/*if($player instanceof Player and Server::getInstance()->api->time->getPhase($this->getLevel()) !== "night"){
|
||||
$pk = new ChatPacket;
|
||||
|
||||
$time = $this->getLevel()->getTime() % Level::TIME_FULL;
|
||||
|
||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||
|
||||
if($player instanceof Player and !$isNight){
|
||||
$pk = new ChatPacket();
|
||||
$pk->message = "You can only sleep at night";
|
||||
$player->dataPacket($pk);
|
||||
|
||||
return true;
|
||||
}*/
|
||||
}
|
||||
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
@ -57,17 +75,19 @@ class Bed extends Transparent{
|
||||
$b = $blockEast;
|
||||
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$b = $blockWest;
|
||||
}elseif($player instanceof Player){
|
||||
$pk = new ChatPacket;
|
||||
$pk->message = "This bed is incomplete";
|
||||
$player->dataPacket($pk);
|
||||
}else{
|
||||
if($player instanceof Player){
|
||||
$pk = new ChatPacket();
|
||||
$pk->message = "This bed is incomplete";
|
||||
$player->dataPacket($pk);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if($player instanceof Player and $player->sleepOn($b) === false){
|
||||
$pk = new ChatPacket;
|
||||
$pk = new ChatPacket();
|
||||
$pk->message = "This bed is occupied";
|
||||
$player->dataPacket($pk);
|
||||
}
|
||||
@ -78,19 +98,19 @@ class Bed extends Transparent{
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->isTransparent === false){
|
||||
$faces = array(
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
);
|
||||
];
|
||||
$d = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$next = $this->getSide($faces[(($d + 3) % 4)]);
|
||||
$downNext = $this->getSide(0);
|
||||
if($next->isReplaceable === true and $downNext->isTransparent === false){
|
||||
$meta = (($d + 3) % 4) & 0x03;
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, false, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | 0x08), true, false, true);
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | 0x08), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -107,34 +127,34 @@ class Bed extends Transparent{
|
||||
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
if($blockNorth->getID() === $this->id and $blockNorth->meta !== 0x08){ //Checks if the block ID and meta are right
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getID() === $this->id and $blockSouth->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getID() === $this->id and $blockEast->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getID() === $this->id and $blockWest->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array(Item::BED, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::BED, 0, 1],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -22,70 +22,19 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Beetroot extends Flowable{
|
||||
class Beetroot extends Crops{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::BEETROOT_BLOCK, $meta, "Beetroot Block");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$item->count--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //TODO: Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get(Item::BEETROOT_SEEDS, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}else{
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(Item::BEETROOT, 0, 1);
|
||||
$drops[] = array(Item::BEETROOT_SEEDS, 0, mt_rand(0, 3));
|
||||
$drops[] = [Item::BEETROOT, 0, 1];
|
||||
$drops[] = [Item::BEETROOT_SEEDS, 0, mt_rand(0, 3)];
|
||||
}else{
|
||||
$drops[] = array(Item::BEETROOT_SEEDS, 0, 1);
|
||||
$drops[] = [Item::BEETROOT_SEEDS, 0, 1];
|
||||
}
|
||||
|
||||
return $drops;
|
||||
|
@ -29,8 +29,8 @@ class BirchWoodStairs extends Stair{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -24,17 +24,22 @@
|
||||
*/
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Villager;
|
||||
use pocketmine\entity\Zombie;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\MovingObjectPosition;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\metadata\Metadatable;
|
||||
use pocketmine\metadata\MetadataValue;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\plugin\Plugin;
|
||||
|
||||
|
||||
abstract class Block extends Position implements Metadatable{
|
||||
class Block extends Position implements Metadatable{
|
||||
const AIR = 0;
|
||||
const STONE = 1;
|
||||
const GRASS = 2;
|
||||
@ -97,7 +102,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
const OBSIDIAN = 49;
|
||||
const TORCH = 50;
|
||||
const FIRE = 51;
|
||||
|
||||
const MONSTER_SPAWNER = 52;
|
||||
const WOOD_STAIRS = 53;
|
||||
const WOODEN_STAIRS = 53;
|
||||
const OAK_WOOD_STAIRS = 53;
|
||||
@ -139,6 +144,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
const SUGARCANE_BLOCK = 83;
|
||||
|
||||
const FENCE = 85;
|
||||
const FENCE_OAK = 85;
|
||||
const PUMPKIN = 86;
|
||||
const NETHERRACK = 87;
|
||||
const SOUL_SAND = 88;
|
||||
@ -162,16 +168,21 @@ abstract class Block extends Position implements Metadatable{
|
||||
const MELON_BLOCK = 103;
|
||||
const PUMPKIN_STEM = 104;
|
||||
const MELON_STEM = 105;
|
||||
|
||||
const VINE = 106;
|
||||
const VINES = 106;
|
||||
const FENCE_GATE = 107;
|
||||
const BRICK_STAIRS = 108;
|
||||
const STONE_BRICK_STAIRS = 109;
|
||||
const MYCELIUM = 110;
|
||||
|
||||
const NETHER_BRICKS = 112;
|
||||
const NETHER_BRICK_BLOCK = 112;
|
||||
|
||||
const NETHER_BRICKS_STAIRS = 114;
|
||||
|
||||
const END_PORTAL = 120;
|
||||
const END_STONE = 121;
|
||||
|
||||
const SANDSTONE_STAIRS = 128;
|
||||
const EMERALD_ORE = 129;
|
||||
|
||||
@ -218,17 +229,30 @@ abstract class Block extends Position implements Metadatable{
|
||||
const HARDENED_CLAY = 172;
|
||||
const COAL_BLOCK = 173;
|
||||
|
||||
const FENCE_GATE_SPRUCE = 183;
|
||||
const FENCE_GATE_BIRCH = 184;
|
||||
const FENCE_GATE_JUNGLE = 185;
|
||||
const FENCE_GATE_DARK_OAK = 186;
|
||||
const FENCE_GATE_ACACIA = 187;
|
||||
const FENCE_SPRUCE = 188;
|
||||
const FENCE_BIRCH = 189;
|
||||
const FENCE_JUNGLE = 190;
|
||||
const FENCE_DARK_OAK = 191;
|
||||
const FENCE_ACACIA = 192;
|
||||
|
||||
const PODZOL = 243;
|
||||
const BEETROOT_BLOCK = 244;
|
||||
const STONECUTTER = 245;
|
||||
const GLOWING_OBSIDIAN = 246;
|
||||
const NETHER_REACTOR = 247;
|
||||
|
||||
public static $creative = array(
|
||||
public static $creative = [
|
||||
//Building
|
||||
[Item::COBBLESTONE, 0],
|
||||
[Item::STONE_BRICKS, 0],
|
||||
[Item::STONE_BRICKS, 1],
|
||||
[Item::STONE_BRICKS, 2],
|
||||
[Item::STONE_BRICKS, 3],
|
||||
[Item::MOSS_STONE, 0],
|
||||
[Item::WOODEN_PLANKS, 0],
|
||||
[Item::WOODEN_PLANKS, 1],
|
||||
@ -246,9 +270,9 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::STONE, 5],
|
||||
[Item::STONE, 6],
|
||||
[Item::DIRT, 0],
|
||||
//TODO: PODZOL
|
||||
[Item::PODZOL, 0],
|
||||
[Item::GRASS, 0],
|
||||
//TODO: MYCELIUM
|
||||
[Item::MYCELIUM, 0],
|
||||
[Item::CLAY_BLOCK, 0],
|
||||
[Item::HARDENED_CLAY, 0],
|
||||
[Item::STAINED_CLAY, 0],
|
||||
@ -271,6 +295,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::SANDSTONE, 1],
|
||||
[Item::SANDSTONE, 2],
|
||||
[Item::SAND, 0],
|
||||
[Item::SAND, 1],
|
||||
[Item::GRAVEL, 0],
|
||||
[Item::TRUNK, 0],
|
||||
[Item::TRUNK, 1],
|
||||
@ -318,7 +343,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::OBSIDIAN, 0],
|
||||
[Item::ICE, 0],
|
||||
[Item::SNOW_BLOCK, 0],
|
||||
//TODO: ENDSTONE
|
||||
[Item::END_STONE, 0],
|
||||
|
||||
//Decoration
|
||||
[Item::COBBLESTONE_WALL, 0],
|
||||
@ -333,7 +358,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::SNOW_LAYER, 0],
|
||||
[Item::GLASS, 0],
|
||||
[Item::GLOWSTONE_BLOCK, 0],
|
||||
//TODO: Vines
|
||||
[Item::VINES, 0],
|
||||
[Item::NETHER_REACTOR, 0],
|
||||
[Item::LADDER, 0],
|
||||
[Item::SPONGE, 0],
|
||||
@ -341,7 +366,16 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::WOODEN_DOOR, 0],
|
||||
[Item::TRAPDOOR, 0],
|
||||
[Item::FENCE, 0],
|
||||
[Item::FENCE_SPRUCE, 0],
|
||||
[Item::FENCE_BIRCH, 0],
|
||||
[Item::FENCE_DARK_OAK, 0],
|
||||
[Item::FENCE_JUNGLE, 0],
|
||||
[Item::FENCE_GATE, 0],
|
||||
[Item::FENCE_GATE_BIRCH, 0],
|
||||
[Item::FENCE_GATE_SPRUCE, 0],
|
||||
[Item::FENCE_GATE_DARK_OAK, 0],
|
||||
[Item::FENCE_GATE_JUNGLE, 0],
|
||||
[Item::FENCE_GATE_ACACIA, 0],
|
||||
[Item::IRON_BARS, 0],
|
||||
[Item::BED, 0],
|
||||
[Item::BOOKSHELF, 0],
|
||||
@ -350,7 +384,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::STONECUTTER, 0],
|
||||
[Item::CHEST, 0],
|
||||
[Item::FURNACE, 0],
|
||||
//TODO: End Portal
|
||||
[Item::END_PORTAL, 0],
|
||||
[Item::DANDELION, 0],
|
||||
[Item::POPPY, 0],
|
||||
//TODO: blue orchid
|
||||
@ -396,7 +430,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::LEAVES2, 1],
|
||||
[Item::CAKE, 0],
|
||||
[Item::SIGN, 0],
|
||||
//TODO: Monster Spawner
|
||||
[Item::MONSTER_SPAWNER, 0],
|
||||
[Item::WOOL, 0],
|
||||
[Item::WOOL, 7],
|
||||
[Item::WOOL, 6],
|
||||
@ -446,11 +480,11 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::CLOCK, 0],
|
||||
[Item::COMPASS, 0],
|
||||
[Item::MINECART, 0],
|
||||
//TODO: Villager
|
||||
[Item::SPAWN_EGG, 10], //Chicken
|
||||
[Item::SPAWN_EGG, 11], //Cow
|
||||
[Item::SPAWN_EGG, 12], //Pig
|
||||
[Item::SPAWN_EGG, 13], //Sheep
|
||||
[Item::SPAWN_EGG, Villager::NETWORK_ID],
|
||||
//[Item::SPAWN_EGG, 10], //Chicken
|
||||
//[Item::SPAWN_EGG, 11], //Cow
|
||||
//[Item::SPAWN_EGG, 12], //Pig
|
||||
//[Item::SPAWN_EGG, 13], //Sheep
|
||||
//TODO: Wolf
|
||||
//TODO: Mooshroom
|
||||
//TODO: Creeper
|
||||
@ -458,7 +492,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
//TODO: Silverfish
|
||||
//TODO: Skeleton
|
||||
//TODO: Slime
|
||||
//TODO: Zombie
|
||||
[Item::SPAWN_EGG, Zombie::NETWORK_ID],
|
||||
//TODO: PigZombie
|
||||
//TODO: Replace with Entity constants
|
||||
|
||||
@ -490,15 +524,16 @@ abstract class Block extends Position implements Metadatable{
|
||||
[Item::DYE, 9],
|
||||
[Item::DYE, 8],
|
||||
|
||||
);
|
||||
];
|
||||
|
||||
/** @var Block[] */
|
||||
public static $list = [];
|
||||
/** @var \SplFixedArray */
|
||||
public static $list = null;
|
||||
protected $id;
|
||||
protected $meta;
|
||||
protected $name;
|
||||
protected $breakTime;
|
||||
protected $hardness;
|
||||
protected $name = "Unknown";
|
||||
protected $breakTime = 0.20;
|
||||
protected $hardness = 10;
|
||||
public $hasEntityCollision = false;
|
||||
public $isActivable = false;
|
||||
public $breakable = true;
|
||||
public $isFlowable = false;
|
||||
@ -514,142 +549,159 @@ abstract class Block extends Position implements Metadatable{
|
||||
public $z = 0;
|
||||
public $frictionFactor = 0.6;
|
||||
|
||||
/** @var AxisAlignedBB */
|
||||
protected $boundingBox = null;
|
||||
|
||||
public static function init(){
|
||||
if(count(self::$list) === 0){
|
||||
self::$list = array(
|
||||
self::AIR => new Air(),
|
||||
self::STONE => new Stone(),
|
||||
self::GRASS => new Grass(),
|
||||
self::DIRT => new Dirt(),
|
||||
self::COBBLESTONE => new Cobblestone(),
|
||||
self::PLANKS => new Planks(),
|
||||
self::SAPLING => new Sapling(),
|
||||
self::BEDROCK => new Bedrock(),
|
||||
self::WATER => new Water(),
|
||||
self::STILL_WATER => new StillWater(),
|
||||
self::LAVA => new Lava(),
|
||||
self::STILL_LAVA => new StillLava(),
|
||||
self::SAND => new Sand(),
|
||||
self::GRAVEL => new Gravel(),
|
||||
self::GOLD_ORE => new GoldOre(),
|
||||
self::IRON_ORE => new IronOre(),
|
||||
self::COAL_ORE => new CoalOre(),
|
||||
self::WOOD => new Wood(),
|
||||
self::LEAVES => new Leaves(),
|
||||
self::SPONGE => new Sponge(),
|
||||
self::GLASS => new Glass(),
|
||||
self::LAPIS_ORE => new LapisOre(),
|
||||
self::LAPIS_BLOCK => new Lapis(),
|
||||
self::SANDSTONE => new Sandstone(),
|
||||
self::BED_BLOCK => new Bed(),
|
||||
self::COBWEB => new Cobweb(),
|
||||
self::TALL_GRASS => new TallGrass(),
|
||||
self::DEAD_BUSH => new DeadBush(),
|
||||
self::WOOL => new Wool(),
|
||||
self::DANDELION => new Dandelion(),
|
||||
self::POPPY => new CyanFlower(),
|
||||
self::BROWN_MUSHROOM => new BrownMushroom(),
|
||||
self::RED_MUSHROOM => new RedMushroom(),
|
||||
self::GOLD_BLOCK => new Gold(),
|
||||
self::IRON_BLOCK => new Iron(),
|
||||
self::DOUBLE_SLAB => new DoubleSlab(),
|
||||
self::SLAB => new Slab(),
|
||||
self::BRICKS_BLOCK => new Bricks(),
|
||||
self::TNT => new TNT(),
|
||||
self::BOOKSHELF => new Bookshelf(),
|
||||
self::MOSS_STONE => new MossStone(),
|
||||
self::OBSIDIAN => new Obsidian(),
|
||||
self::TORCH => new Torch(),
|
||||
self::FIRE => new Fire(),
|
||||
if(self::$list === null){
|
||||
self::$list = new \SplFixedArray(256);
|
||||
self::$list[self::AIR] = Air::class;;
|
||||
self::$list[self::STONE] = Stone::class;;
|
||||
self::$list[self::GRASS] = Grass::class;;
|
||||
self::$list[self::DIRT] = Dirt::class;;
|
||||
self::$list[self::COBBLESTONE] = Cobblestone::class;;
|
||||
self::$list[self::PLANKS] = Planks::class;;
|
||||
self::$list[self::SAPLING] = Sapling::class;;
|
||||
self::$list[self::BEDROCK] = Bedrock::class;;
|
||||
self::$list[self::WATER] = Water::class;;
|
||||
self::$list[self::STILL_WATER] = StillWater::class;;
|
||||
self::$list[self::LAVA] = Lava::class;;
|
||||
self::$list[self::STILL_LAVA] = StillLava::class;;
|
||||
self::$list[self::SAND] = Sand::class;;
|
||||
self::$list[self::GRAVEL] = Gravel::class;;
|
||||
self::$list[self::GOLD_ORE] = GoldOre::class;;
|
||||
self::$list[self::IRON_ORE] = IronOre::class;;
|
||||
self::$list[self::COAL_ORE] = CoalOre::class;;
|
||||
self::$list[self::WOOD] = Wood::class;;
|
||||
self::$list[self::LEAVES] = Leaves::class;;
|
||||
self::$list[self::SPONGE] = Sponge::class;;
|
||||
self::$list[self::GLASS] = Glass::class;;
|
||||
self::$list[self::LAPIS_ORE] = LapisOre::class;;
|
||||
self::$list[self::LAPIS_BLOCK] = Lapis::class;;
|
||||
self::$list[self::SANDSTONE] = Sandstone::class;;
|
||||
self::$list[self::BED_BLOCK] = Bed::class;;
|
||||
self::$list[self::COBWEB] = Cobweb::class;;
|
||||
self::$list[self::TALL_GRASS] = TallGrass::class;;
|
||||
self::$list[self::DEAD_BUSH] = DeadBush::class;;
|
||||
self::$list[self::WOOL] = Wool::class;;
|
||||
self::$list[self::DANDELION] = Dandelion::class;;
|
||||
self::$list[self::POPPY] = CyanFlower::class;;
|
||||
self::$list[self::BROWN_MUSHROOM] = BrownMushroom::class;;
|
||||
self::$list[self::RED_MUSHROOM] = RedMushroom::class;;
|
||||
self::$list[self::GOLD_BLOCK] = Gold::class;;
|
||||
self::$list[self::IRON_BLOCK] = Iron::class;;
|
||||
self::$list[self::DOUBLE_SLAB] = DoubleSlab::class;;
|
||||
self::$list[self::SLAB] = Slab::class;;
|
||||
self::$list[self::BRICKS_BLOCK] = Bricks::class;;
|
||||
self::$list[self::TNT] = TNT::class;;
|
||||
self::$list[self::BOOKSHELF] = Bookshelf::class;;
|
||||
self::$list[self::MOSS_STONE] = MossStone::class;;
|
||||
self::$list[self::OBSIDIAN] = Obsidian::class;;
|
||||
self::$list[self::TORCH] = Torch::class;;
|
||||
self::$list[self::FIRE] = Fire::class;;
|
||||
self::$list[self::MONSTER_SPAWNER] = MonsterSpawner::class;;
|
||||
self::$list[self::WOOD_STAIRS] = WoodStairs::class;;
|
||||
self::$list[self::CHEST] = Chest::class;;
|
||||
|
||||
self::WOOD_STAIRS => new WoodStairs(),
|
||||
self::CHEST => new Chest(),
|
||||
self::$list[self::DIAMOND_ORE] = DiamondOre::class;;
|
||||
self::$list[self::DIAMOND_BLOCK] = Diamond::class;;
|
||||
self::$list[self::WORKBENCH] = Workbench::class;;
|
||||
self::$list[self::WHEAT_BLOCK] = Wheat::class;;
|
||||
self::$list[self::FARMLAND] = Farmland::class;;
|
||||
self::$list[self::FURNACE] = Furnace::class;;
|
||||
self::$list[self::BURNING_FURNACE] = BurningFurnace::class;;
|
||||
self::$list[self::SIGN_POST] = SignPost::class;;
|
||||
self::$list[self::WOOD_DOOR_BLOCK] = WoodDoor::class;;
|
||||
self::$list[self::LADDER] = Ladder::class;;
|
||||
|
||||
self::DIAMOND_ORE => new DiamondOre(),
|
||||
self::DIAMOND_BLOCK => new Diamond(),
|
||||
self::WORKBENCH => new Workbench(),
|
||||
self::WHEAT_BLOCK => new Wheat(),
|
||||
self::FARMLAND => new Farmland(),
|
||||
self::FURNACE => new Furnace(),
|
||||
self::BURNING_FURNACE => new BurningFurnace(),
|
||||
self::SIGN_POST => new SignPost(),
|
||||
self::WOOD_DOOR_BLOCK => new WoodDoor(),
|
||||
self::LADDER => new Ladder(),
|
||||
self::$list[self::COBBLESTONE_STAIRS] = CobblestoneStairs::class;;
|
||||
self::$list[self::WALL_SIGN] = WallSign::class;;
|
||||
|
||||
self::COBBLESTONE_STAIRS => new CobblestoneStairs(),
|
||||
self::WALL_SIGN => new WallSign(),
|
||||
self::$list[self::IRON_DOOR_BLOCK] = IronDoor::class;;
|
||||
self::$list[self::REDSTONE_ORE] = RedstoneOre::class;;
|
||||
self::$list[self::GLOWING_REDSTONE_ORE] = GlowingRedstoneOre::class;;
|
||||
|
||||
self::IRON_DOOR_BLOCK => new IronDoor(),
|
||||
self::REDSTONE_ORE => new RedstoneOre(),
|
||||
self::GLOWING_REDSTONE_ORE => new GlowingRedstoneOre(),
|
||||
self::$list[self::SNOW_LAYER] = SnowLayer::class;;
|
||||
self::$list[self::ICE] = Ice::class;;
|
||||
self::$list[self::SNOW_BLOCK] = Snow::class;;
|
||||
self::$list[self::CACTUS] = Cactus::class;;
|
||||
self::$list[self::CLAY_BLOCK] = Clay::class;;
|
||||
self::$list[self::SUGARCANE_BLOCK] = Sugarcane::class;;
|
||||
|
||||
self::SNOW_LAYER => new SnowLayer(),
|
||||
self::ICE => new Ice(),
|
||||
self::SNOW_BLOCK => new Snow(),
|
||||
self::CACTUS => new Cactus(),
|
||||
self::CLAY_BLOCK => new Clay(),
|
||||
self::SUGARCANE_BLOCK => new Sugarcane(),
|
||||
self::$list[self::FENCE] = Fence::class;;
|
||||
self::$list[self::PUMPKIN] = Pumpkin::class;;
|
||||
self::$list[self::NETHERRACK] = Netherrack::class;;
|
||||
self::$list[self::SOUL_SAND] = SoulSand::class;;
|
||||
self::$list[self::GLOWSTONE_BLOCK] = Glowstone::class;;
|
||||
|
||||
self::FENCE => new Fence(),
|
||||
self::PUMPKIN => new Pumpkin(),
|
||||
self::NETHERRACK => new Netherrack(),
|
||||
self::SOUL_SAND => new SoulSand(),
|
||||
self::GLOWSTONE_BLOCK => new Glowstone(),
|
||||
self::$list[self::LIT_PUMPKIN] = LitPumpkin::class;;
|
||||
self::$list[self::CAKE_BLOCK] = Cake::class;;
|
||||
|
||||
self::LIT_PUMPKIN => new LitPumpkin(),
|
||||
self::CAKE_BLOCK => new Cake(),
|
||||
self::$list[self::TRAPDOOR] = Trapdoor::class;;
|
||||
|
||||
self::TRAPDOOR => new Trapdoor(),
|
||||
self::$list[self::STONE_BRICKS] = StoneBricks::class;;
|
||||
|
||||
self::STONE_BRICKS => new StoneBricks(),
|
||||
self::$list[self::IRON_BARS] = IronBars::class;;
|
||||
self::$list[self::GLASS_PANE] = GlassPane::class;;
|
||||
self::$list[self::MELON_BLOCK] = Melon::class;;
|
||||
self::$list[self::PUMPKIN_STEM] = PumpkinStem::class;;
|
||||
self::$list[self::MELON_STEM] = MelonStem::class;;
|
||||
self::$list[self::VINE] = Vine::class;;
|
||||
self::$list[self::FENCE_GATE] = FenceGate::class;;
|
||||
self::$list[self::BRICK_STAIRS] = BrickStairs::class;;
|
||||
self::$list[self::STONE_BRICK_STAIRS] = StoneBrickStairs::class;;
|
||||
|
||||
self::IRON_BARS => new IronBars(),
|
||||
self::GLASS_PANE => new GlassPane(),
|
||||
self::MELON_BLOCK => new Melon(),
|
||||
self::PUMPKIN_STEM => new PumpkinStem(),
|
||||
self::MELON_STEM => new MelonStem(),
|
||||
self::$list[self::MYCELIUM] = Mycelium::class;;
|
||||
self::$list[self::NETHER_BRICKS] = NetherBrick::class;;
|
||||
|
||||
self::FENCE_GATE => new FenceGate(),
|
||||
self::BRICK_STAIRS => new BrickStairs(),
|
||||
self::STONE_BRICK_STAIRS => new StoneBrickStairs(),
|
||||
self::$list[self::NETHER_BRICKS_STAIRS] = NetherBrickStairs::class;;
|
||||
|
||||
self::NETHER_BRICKS => new NetherBrick(),
|
||||
self::$list[self::END_PORTAL] = EndPortal::class;;
|
||||
self::$list[self::END_STONE] = EndStone::class;;
|
||||
self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class;;
|
||||
self::$list[self::EMERALD_ORE] = EmeraldOre::class;;
|
||||
|
||||
self::NETHER_BRICKS_STAIRS => new NetherBrickStairs(),
|
||||
self::$list[self::EMERALD_BLOCK] = Emerald::class;;
|
||||
self::$list[self::SPRUCE_WOOD_STAIRS] = SpruceWoodStairs::class;;
|
||||
self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class;;
|
||||
self::$list[self::JUNGLE_WOOD_STAIRS] = JungleWoodStairs::class;;
|
||||
self::$list[self::STONE_WALL] = StoneWall::class;;
|
||||
|
||||
self::SANDSTONE_STAIRS => new SandstoneStairs(),
|
||||
self::EMERALD_ORE => new EmeraldOre(),
|
||||
self::$list[self::CARROT_BLOCK] = Carrot::class;;
|
||||
self::$list[self::POTATO_BLOCK] = Potato::class;;
|
||||
|
||||
self::EMERALD_BLOCK => new Emerald(),
|
||||
self::SPRUCE_WOOD_STAIRS => new SpruceWoodStairs(),
|
||||
self::BIRCH_WOOD_STAIRS => new BirchWoodStairs(),
|
||||
self::JUNGLE_WOOD_STAIRS => new JungleWoodStairs(),
|
||||
self::STONE_WALL => new StoneWall(),
|
||||
self::$list[self::QUARTZ_BLOCK] = Quartz::class;;
|
||||
self::$list[self::QUARTZ_STAIRS] = QuartzStairs::class;;
|
||||
self::$list[self::DOUBLE_WOOD_SLAB] = DoubleWoodSlab::class;;
|
||||
self::$list[self::WOOD_SLAB] = WoodSlab::class;;
|
||||
self::$list[self::STAINED_CLAY] = StainedClay::class;;
|
||||
|
||||
self::CARROT_BLOCK => new Carrot(),
|
||||
self::POTATO_BLOCK => new Potato(),
|
||||
self::$list[self::LEAVES2] = Leaves2::class;;
|
||||
self::$list[self::WOOD2] = Wood2::class;;
|
||||
self::$list[self::ACACIA_WOOD_STAIRS] = AcaciaWoodStairs::class;;
|
||||
self::$list[self::DARK_OAK_WOOD_STAIRS] = DarkOakWoodStairs::class;;
|
||||
|
||||
self::QUARTZ_BLOCK => new Quartz(),
|
||||
self::QUARTZ_STAIRS => new QuartzStairs(),
|
||||
self::DOUBLE_WOOD_SLAB => new DoubleWoodSlab(),
|
||||
self::WOOD_SLAB => new WoodSlab(),
|
||||
self::STAINED_CLAY => new StainedClay(),
|
||||
self::$list[self::HAY_BALE] = HayBale::class;;
|
||||
self::$list[self::CARPET] = Carpet::class;;
|
||||
self::$list[self::HARDENED_CLAY] = HardenedClay::class;;
|
||||
self::$list[self::COAL_BLOCK] = Coal::class;;
|
||||
|
||||
self::LEAVES2 => new Leaves2(),
|
||||
self::WOOD2 => new Wood2(),
|
||||
self::ACACIA_WOOD_STAIRS => new AcaciaWoodStairs(),
|
||||
self::DARK_OAK_WOOD_STAIRS => new DarkOakWoodStairs(),
|
||||
self::$list[self::FENCE_GATE_SPRUCE] = FenceGateSpruce::class;
|
||||
self::$list[self::FENCE_GATE_BIRCH] = FenceGateBirch::class;
|
||||
self::$list[self::FENCE_GATE_JUNGLE] = FenceGateJungle::class;
|
||||
self::$list[self::FENCE_GATE_DARK_OAK] = FenceGateDarkOak::class;
|
||||
self::$list[self::FENCE_GATE_ACACIA] = FenceGateAcacia::class;
|
||||
self::$list[self::FENCE_SPRUCE] = FenceSpruce::class;
|
||||
self::$list[self::FENCE_BIRCH] = FenceBirch::class;
|
||||
self::$list[self::FENCE_DARK_OAK] = FenceDarkOak::class;
|
||||
self::$list[self::FENCE_JUNGLE] = FenceJungle::class;
|
||||
self::$list[self::FENCE_ACACIA] = FenceAcacia::class;
|
||||
|
||||
self::HAY_BALE => new HayBale(),
|
||||
self::CARPET => new Carpet(),
|
||||
self::HARDENED_CLAY => new HardenedClay(),
|
||||
self::COAL_BLOCK => new Coal(),
|
||||
|
||||
self::BEETROOT_BLOCK => new Beetroot(),
|
||||
self::STONECUTTER => new Stonecutter(),
|
||||
self::GLOWING_OBSIDIAN => new GlowingObsidian(),
|
||||
self::NETHER_REACTOR => new NetherReactor(),
|
||||
);
|
||||
self::$list[self::PODZOL] = Podzol::class;;
|
||||
self::$list[self::BEETROOT_BLOCK] = Beetroot::class;;
|
||||
self::$list[self::STONECUTTER] = Stonecutter::class;;
|
||||
self::$list[self::GLOWING_OBSIDIAN] = GlowingObsidian::class;;
|
||||
self::$list[self::NETHER_REACTOR] = NetherReactor::class;;
|
||||
}
|
||||
}
|
||||
|
||||
@ -661,14 +713,22 @@ abstract class Block extends Position implements Metadatable{
|
||||
* @return Block
|
||||
*/
|
||||
public static function get($id, $meta = 0, Position $pos = null){
|
||||
if(isset(self::$list[$id])){
|
||||
$block = clone self::$list[$id];
|
||||
$block->setDamage($meta);
|
||||
}else{
|
||||
$block = new Generic($id, $meta);
|
||||
try{
|
||||
$block = self::$list[$id];
|
||||
if($block !== null){
|
||||
$block = new $block($meta);
|
||||
}else{
|
||||
$block = new Block($id, $meta);
|
||||
}
|
||||
}catch(\RuntimeException $e){
|
||||
$block = new Block($id, $meta);
|
||||
}
|
||||
if($pos instanceof Position){
|
||||
$block->position($pos);
|
||||
|
||||
if($pos !== null){
|
||||
$block->x = $pos->x;
|
||||
$block->y = $pos->y;
|
||||
$block->z = $pos->z;
|
||||
$block->level = $pos->level;
|
||||
}
|
||||
|
||||
return $block;
|
||||
@ -683,8 +743,69 @@ abstract class Block extends Position implements Metadatable{
|
||||
$this->id = (int) $id;
|
||||
$this->meta = (int) $meta;
|
||||
$this->name = $name;
|
||||
$this->breakTime = 0.20;
|
||||
$this->hardness = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the Block, using block space and block target, and side. Returns if the block has been placed.
|
||||
*
|
||||
* @param Item $item
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param float $fx
|
||||
* @param float $fy
|
||||
* @param float $fz
|
||||
* @param Player $player = null
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
return $this->getLevel()->setBlock($this, $this, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the item can be broken with an specific Item
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isBreakable(Item $item){
|
||||
return $this->breakable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the actions needed so the block is broken with the Item
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function onBreak(Item $item){
|
||||
return $this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires a block update on the Block
|
||||
*
|
||||
* @param int $type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onUpdate($type){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Do actions when activated by Item. Returns if it has done anything
|
||||
*
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
return $this->isActivable;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -704,10 +825,14 @@ abstract class Block extends Position implements Metadatable{
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getID(){
|
||||
final public function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function addVelocityToEntity(Entity $entity, Vector3 $vector){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
@ -746,7 +871,7 @@ abstract class Block extends Position implements Metadatable{
|
||||
return [];
|
||||
}else{
|
||||
return [
|
||||
array($this->id, $this->meta, 1),
|
||||
[$this->id, $this->meta, 1],
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -786,41 +911,41 @@ abstract class Block extends Position implements Metadatable{
|
||||
return "Block " . $this->name . " (" . $this->id . ":" . $this->meta . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the item can be broken with an specific Item
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract function isBreakable(Item $item);
|
||||
|
||||
/**
|
||||
* Do the actions needed so the block is broken with the Item
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function onBreak(Item $item);
|
||||
|
||||
/**
|
||||
* Checks for collision against an AxisAlignedBB
|
||||
*
|
||||
* @param AxisAlignedBB $bb
|
||||
* @param Block[] $list
|
||||
*/
|
||||
public function collidesWithBB(AxisAlignedBB $bb, &$list = array()){
|
||||
public function collidesWithBB(AxisAlignedBB $bb, &$list = []){
|
||||
$bb2 = $this->getBoundingBox();
|
||||
if($bb2->intersectsWith($bb)){
|
||||
if($bb2 !== null and $bb2->intersectsWith($bb)){
|
||||
$list[] = $bb2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Entity $entity
|
||||
*/
|
||||
public function onEntityCollide(Entity $entity){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB
|
||||
*/
|
||||
public function getBoundingBox(){
|
||||
if($this->boundingBox !== null){
|
||||
return $this->boundingBox;
|
||||
}else{
|
||||
return $this->boundingBox = $this->recalculateBoundingBox();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB
|
||||
*/
|
||||
protected function recalculateBoundingBox(){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
@ -831,40 +956,87 @@ abstract class Block extends Position implements Metadatable{
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the Block, using block space and block target, and side. Returns if the block has been placed.
|
||||
*
|
||||
* @param Item $item
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param float $fx
|
||||
* @param float $fy
|
||||
* @param float $fz
|
||||
* @param Player $player = null
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null);
|
||||
public function calculateIntercept(Vector3 $pos1, Vector3 $pos2){
|
||||
$bb = $this->getBoundingBox();
|
||||
if($bb === null){
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do actions when activated by Item. Returns if it has done anything
|
||||
*
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract function onActivate(Item $item, Player $player = null);
|
||||
$v1 = $pos1->getIntermediateWithXValue($pos2, $bb->minX);
|
||||
$v2 = $pos1->getIntermediateWithXValue($pos2, $bb->maxX);
|
||||
$v3 = $pos1->getIntermediateWithYValue($pos2, $bb->minY);
|
||||
$v4 = $pos1->getIntermediateWithYValue($pos2, $bb->maxY);
|
||||
$v5 = $pos1->getIntermediateWithZValue($pos2, $bb->minZ);
|
||||
$v6 = $pos1->getIntermediateWithZValue($pos2, $bb->maxZ);
|
||||
|
||||
/**
|
||||
* Fires a block update on the Block
|
||||
*
|
||||
* @param int $type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract function onUpdate($type);
|
||||
if($v1 !== null and !$bb->isVectorInYZ($v1)){
|
||||
$v1 = null;
|
||||
}
|
||||
|
||||
if($v2 !== null and !$bb->isVectorInYZ($v2)){
|
||||
$v2 = null;
|
||||
}
|
||||
|
||||
if($v3 !== null and !$bb->isVectorInXZ($v3)){
|
||||
$v3 = null;
|
||||
}
|
||||
|
||||
if($v4 !== null and !$bb->isVectorInXZ($v4)){
|
||||
$v4 = null;
|
||||
}
|
||||
|
||||
if($v5 !== null and !$bb->isVectorInXY($v5)){
|
||||
$v5 = null;
|
||||
}
|
||||
|
||||
if($v6 !== null and !$bb->isVectorInXY($v6)){
|
||||
$v6 = null;
|
||||
}
|
||||
|
||||
$vector = $v1;
|
||||
|
||||
if($v2 !== null and ($vector === null or $pos1->distanceSquared($v2) < $pos1->distanceSquared($vector))){
|
||||
$vector = $v2;
|
||||
}
|
||||
|
||||
if($v3 !== null and ($vector === null or $pos1->distanceSquared($v3) < $pos1->distanceSquared($vector))){
|
||||
$vector = $v3;
|
||||
}
|
||||
|
||||
if($v4 !== null and ($vector === null or $pos1->distanceSquared($v4) < $pos1->distanceSquared($vector))){
|
||||
$vector = $v4;
|
||||
}
|
||||
|
||||
if($v5 !== null and ($vector === null or $pos1->distanceSquared($v5) < $pos1->distanceSquared($vector))){
|
||||
$vector = $v5;
|
||||
}
|
||||
|
||||
if($v6 !== null and ($vector === null or $pos1->distanceSquared($v6) < $pos1->distanceSquared($vector))){
|
||||
$vector = $v6;
|
||||
}
|
||||
|
||||
if($vector === null){
|
||||
return null;
|
||||
}
|
||||
|
||||
$f = -1;
|
||||
|
||||
if($vector === $v1){
|
||||
$f = 4;
|
||||
}elseif($vector === $v2){
|
||||
$f = 5;
|
||||
}elseif($vector === $v3){
|
||||
$f = 0;
|
||||
}elseif($vector === $v4){
|
||||
$f = 1;
|
||||
}elseif($vector === $v5){
|
||||
$f = 2;
|
||||
}elseif($vector === $v6){
|
||||
$f = 3;
|
||||
}
|
||||
|
||||
return MovingObjectPosition::fromBlock($this->x, $this->y, $this->z, $f, $vector->add($this->x, $this->y, $this->z));
|
||||
}
|
||||
|
||||
public function setMetadata($metadataKey, MetadataValue $metadataValue){
|
||||
if($this->getLevel() instanceof Level){
|
||||
@ -889,4 +1061,4 @@ abstract class Block extends Position implements Metadatable{
|
||||
$this->getLevel()->getBlockMetadata()->removeMetadata($this, $metadataKey, $plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -48,9 +48,9 @@ class Bricks extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::BRICKS_BLOCK, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::BRICKS_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -33,9 +33,8 @@ class BrownMushroom extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get($this->id));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -47,11 +46,16 @@ class BrownMushroom extends Flowable{
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->isTransparent === false){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -39,29 +39,29 @@ class BurningFurnace extends Solid{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$faces = array(
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
);
|
||||
];
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$nbt = new Compound(false, array(
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$nbt = new Compound(false, [
|
||||
new Enum("Items", []),
|
||||
new String("id", Tile::FURNACE),
|
||||
new Int("x", $this->x),
|
||||
new Int("y", $this->y),
|
||||
new Int("z", $this->z)
|
||||
));
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
new Furnace($this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4), $nbt);
|
||||
Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -73,15 +73,15 @@ class BurningFurnace extends Solid{
|
||||
if($t instanceof Furnace){
|
||||
$furnace = $t;
|
||||
}else{
|
||||
$nbt = new Compound(false, array(
|
||||
$nbt = new Compound(false, [
|
||||
new Enum("Items", []),
|
||||
new String("id", Tile::FURNACE),
|
||||
new Int("x", $this->x),
|
||||
new Int("y", $this->y),
|
||||
new Int("z", $this->z)
|
||||
));
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$furnace = new Furnace($this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4), $nbt);
|
||||
$furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
}
|
||||
|
||||
if(($player->getGamemode() & 0x01) === 0x01){
|
||||
@ -114,16 +114,7 @@ class BurningFurnace extends Solid{
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
if($item->isPickaxe() >= 1){
|
||||
$drops[] = array(Item::FURNACE, 0, 1);
|
||||
}
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
if($t instanceof Furnace){
|
||||
for($s = 0; $s < $t->getInventory()->getSize(); ++$s){
|
||||
$slot = $t->getInventory()->getItem($s);
|
||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||
$drops[] = array($slot->getID(), $slot->getDamage(), $slot->getCount());
|
||||
}
|
||||
}
|
||||
$drops[] = [Item::FURNACE, 0, 1];
|
||||
}
|
||||
|
||||
return $drops;
|
||||
|
@ -21,27 +21,56 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3 as Vector3;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Cactus extends Transparent{
|
||||
|
||||
public $hasEntityCollision = true;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::CACTUS, $meta, "Cactus");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 2;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x + 0.0625,
|
||||
$this->y,
|
||||
$this->z + 0.0625,
|
||||
$this->x + 0.9375,
|
||||
$this->y + 1,
|
||||
$this->z + 0.9375
|
||||
);
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
|
||||
$entity->attack($ev->getFinalDamage(), $ev);
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::SAND and $down->getID() !== self::CACTUS){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), false);
|
||||
Server::getInstance()->api->entity->drop($this, Item::get($this->id));
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
if($down->getID() !== self::SAND and $down->getID() !== self::CACTUS){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if(!$b->isFlowable){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getID() !== self::CACTUS){
|
||||
@ -49,18 +78,18 @@ class Cactus extends Transparent{
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getID() === self::AIR){
|
||||
$this->getLevel()->setBlock($b, new Cactus(), true, false, true);
|
||||
break;
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Cactus()));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->meta = 0;
|
||||
$this->getLevel()->setBlock($this, $this, false);
|
||||
$this->getLevel()->setBlock($this, $this);
|
||||
}else{
|
||||
++$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, false);
|
||||
$this->getLevel()->setBlock($this, $this);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +104,7 @@ class Cactus extends Transparent{
|
||||
$block2 = $this->getSide(4);
|
||||
$block3 = $this->getSide(5);
|
||||
if($block0->isTransparent === true and $block1->isTransparent === true and $block2->isTransparent === true and $block3->isTransparent === true){
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -85,8 +114,8 @@ class Cactus extends Transparent{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -21,9 +21,12 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\entity\EntityRegainHealthEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Cake extends Transparent{
|
||||
public function __construct($meta = 0){
|
||||
@ -34,10 +37,24 @@ class Cake extends Transparent{
|
||||
$this->hardness = 2.5;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
$f = (1 + $this->getDamage() * 2) / 16;
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $f,
|
||||
$this->y,
|
||||
$this->z + 0.0625,
|
||||
$this->x + 1 - 0.0625,
|
||||
$this->y + 0.5,
|
||||
$this->z + 1 - 0.0625
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -48,7 +65,7 @@ class Cake extends Transparent{
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -64,11 +81,14 @@ class Cake extends Transparent{
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($player instanceof Player and $player->getHealth() < 20){
|
||||
++$this->meta;
|
||||
$player->heal(3, "cake");
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityRegainHealthEvent($player, 3, EntityRegainHealthEvent::CAUSE_EATING));
|
||||
if(!$ev->isCancelled()){
|
||||
$player->heal($ev->getAmount(), $ev);
|
||||
}
|
||||
if($this->meta >= 0x06){
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -23,12 +23,13 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Carpet extends Flowable{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::CARPET, $meta, "Carpet");
|
||||
$names = array(
|
||||
$names = [
|
||||
0 => "White Carpet",
|
||||
1 => "Orange Carpet",
|
||||
2 => "Magenta Carpet",
|
||||
@ -45,17 +46,29 @@ class Carpet extends Flowable{
|
||||
13 => "Green Carpet",
|
||||
14 => "Red Carpet",
|
||||
15 => "Black Carpet",
|
||||
);
|
||||
];
|
||||
$this->name = $names[$this->meta];
|
||||
$this->hardness = 0;
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = true;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 0.0625,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -65,9 +78,8 @@ class Carpet extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){ //TODO: Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get($this->id, $this->meta, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
if($this->getSide(0)->getID() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
|
@ -22,70 +22,18 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Carrot extends Flowable{
|
||||
class Carrot extends Crops{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::CARROT_BLOCK, $meta, "Carrot Block");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$item->count--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
//TODO
|
||||
//Server::getInstance()->api->entity->drop($this, Item::get(CARROT, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}else{
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(Item::CARROT, 0, mt_rand(1, 4));
|
||||
$drops[] = [Item::CARROT, 0, mt_rand(1, 4)];
|
||||
}else{
|
||||
$drops[] = array(Item::CARROT, 0, 1);
|
||||
$drops[] = [Item::CARROT, 0, 1];
|
||||
}
|
||||
|
||||
return $drops;
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\nbt\tag\Enum;
|
||||
@ -41,15 +42,27 @@ class Chest extends Transparent{
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x + 0.0625,
|
||||
$this->y,
|
||||
$this->z + 0.0625,
|
||||
$this->x + 0.9375,
|
||||
$this->y + 0.9475,
|
||||
$this->z + 0.9375
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$faces = array(
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
);
|
||||
];
|
||||
|
||||
$chest = false;
|
||||
$chest = null;
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
@ -68,18 +81,18 @@ class Chest extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$nbt = new Compound(false, array(
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$nbt = new Compound(false, [
|
||||
new Enum("Items", []),
|
||||
new String("id", Tile::CHEST),
|
||||
new Int("x", $this->x),
|
||||
new Int("y", $this->y),
|
||||
new Int("z", $this->z)
|
||||
));
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$tile = new TileChest($this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4), $nbt);
|
||||
$tile = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
|
||||
if($chest instanceof TileChest){
|
||||
if($chest instanceof TileChest and $tile instanceof TileChest){
|
||||
$chest->pairWith($tile);
|
||||
$tile->pairWith($chest);
|
||||
}
|
||||
@ -92,7 +105,7 @@ class Chest extends Transparent{
|
||||
if($t instanceof TileChest){
|
||||
$t->unpair();
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -109,19 +122,19 @@ class Chest extends Transparent{
|
||||
if($t instanceof TileChest){
|
||||
$chest = $t;
|
||||
}else{
|
||||
$nbt = new Compound(false, array(
|
||||
$nbt = new Compound(false, [
|
||||
new Enum("Items", []),
|
||||
new String("id", Tile::CHEST),
|
||||
new Int("x", $this->x),
|
||||
new Int("y", $this->y),
|
||||
new Int("z", $this->z)
|
||||
));
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$chest = new TileChest($this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4), $nbt);
|
||||
$chest = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
}
|
||||
|
||||
|
||||
if(($player->gamemode & 0x01) === 0x01){
|
||||
if($player->isCreative()){
|
||||
return true;
|
||||
}
|
||||
$player->addWindow($chest->getInventory());
|
||||
@ -131,19 +144,8 @@ class Chest extends Transparent{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
if($t instanceof TileChest){
|
||||
for($s = 0; $s < $t->getRealInventory()->getSize(); ++$s){
|
||||
$slot = $t->getRealInventory()->getItem($s);
|
||||
if($slot->getID() > Item::AIR and $slot->getCount() > 0){
|
||||
$drops[] = array($slot->getID(), $slot->getDamage(), $slot->getCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $drops;
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -30,8 +30,8 @@ class Clay extends Solid{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array(Item::CLAY, 0, 4),
|
||||
);
|
||||
return [
|
||||
[Item::CLAY, 0, 4],
|
||||
];
|
||||
}
|
||||
}
|
@ -48,9 +48,9 @@ class Coal extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::COAL_BLOCK, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::COAL_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ class CoalOre extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::COAL, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::COAL, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ class Cobblestone extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::COBBLESTONE, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::COBBLESTONE, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -21,9 +21,13 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Cobweb extends Flowable{
|
||||
|
||||
public $hasEntityCollision = true;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::COBWEB, 0, "Cobweb");
|
||||
$this->isSolid = true;
|
||||
@ -31,6 +35,10 @@ class Cobweb extends Flowable{
|
||||
$this->hardness = 25;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$entity->fallDistance = 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [];
|
||||
}
|
||||
|
100
src/pocketmine/block/Crops.php
Normal file
100
src/pocketmine/block/Crops.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
abstract class Crops extends Flowable{
|
||||
|
||||
public $isActivable = true;
|
||||
public $hardness = 0;
|
||||
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$block = clone $this;
|
||||
$block->meta += mt_rand(2, 5);
|
||||
if($block->meta > 7){
|
||||
$block->meta = 7;
|
||||
}
|
||||
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block));
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
|
||||
}
|
||||
|
||||
$item->count--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
$block = clone $this;
|
||||
++$block->meta;
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block));
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true, true);
|
||||
}else{
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -31,10 +31,15 @@ class CyanFlower extends Flowable{
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -44,9 +49,8 @@ class CyanFlower extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //TODO: Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get($this->id, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
|
@ -31,10 +31,15 @@ class Dandelion extends Flowable{
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -44,10 +49,8 @@ class Dandelion extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
//TODO
|
||||
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
|
@ -29,8 +29,8 @@ class DarkOakWoodStairs extends Stair{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -30,6 +30,11 @@ class DeadBush extends Flowable{
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
|
@ -42,9 +42,9 @@ class Diamond extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::DIAMOND_BLOCK, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::DIAMOND_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ class DiamondOre extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::DIAMOND, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::DIAMOND, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -25,16 +25,21 @@ use pocketmine\item\Item;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Dirt extends Solid{
|
||||
|
||||
public $isActivable = true;
|
||||
protected $hardness = 2.5;
|
||||
protected $id = self::DIRT;
|
||||
protected $meta = 0;
|
||||
protected $name = "Dirt";
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::DIRT, 0, "Dirt");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 2.5;
|
||||
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::FARMLAND, 0), true, false, true);
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::FARMLAND, 0), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
@ -34,6 +35,170 @@ abstract class Door extends Transparent{
|
||||
$this->isSolid = false;
|
||||
}
|
||||
|
||||
private function getFullDamage(){
|
||||
$damage = $this->getDamage();
|
||||
$flag = ($damage & 0x08) > 0;
|
||||
|
||||
if($flag){
|
||||
$first = $this->getSide(0)->getDamage();
|
||||
$second = $damage;
|
||||
}else{
|
||||
$first = $damage;
|
||||
$second = $this->getSide(1)->getDamage();
|
||||
}
|
||||
|
||||
$flag1 = ($second & 0x01) > 0;
|
||||
|
||||
return $first & 0x07 | ($flag ? 8 : 0) | ($flag1 ? 0x10 : 0);
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
$f = 0.1875;
|
||||
$damage = $this->getFullDamage();
|
||||
|
||||
$bb = new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 2,
|
||||
$this->z + 1
|
||||
);
|
||||
|
||||
$j = $damage & 0x03;
|
||||
$flag = (($damage & 0x04) > 0);
|
||||
$flag1 = (($damage & 0x10) > 0);
|
||||
|
||||
if($j === 0){
|
||||
if($flag){
|
||||
if(!$flag1){
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + $f
|
||||
);
|
||||
}else{
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z + 1 - $f,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}else{
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + $f,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}elseif($j === 1){
|
||||
if($flag){
|
||||
if(!$flag1){
|
||||
$bb->setBounds(
|
||||
$this->x + 1 - $f,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}else{
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + $f,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}else{
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + $f
|
||||
);
|
||||
}
|
||||
}elseif($j === 2){
|
||||
if($flag){
|
||||
if(!$flag1){
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z + 1 - $f,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}else{
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + $f
|
||||
);
|
||||
}
|
||||
}else{
|
||||
$bb->setBounds(
|
||||
$this->x + 1 - $f,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}elseif($j === 3){
|
||||
if($flag){
|
||||
if(!$flag1){
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + $f,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}else{
|
||||
$bb->setBounds(
|
||||
$this->x + 1 - $f,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}else{
|
||||
$bb->setBounds(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z + 1 - $f,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $bb;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
@ -57,22 +222,22 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}
|
||||
$direction = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$face = array(
|
||||
$face = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
);
|
||||
];
|
||||
$next = $this->getSide($face[(($direction + 2) % 4)]);
|
||||
$next2 = $this->getSide($face[$direction]);
|
||||
$metaUp = 0x08;
|
||||
if($next->getID() === $this->id or ($next2->isTransparent === false and $next->isTransparent === true)){ //Door hinge
|
||||
$metaUp |= 0x01;
|
||||
}
|
||||
$this->getLevel()->setBlock($blockUp, Block::get($this->id, $metaUp), true, false, true); //Top
|
||||
|
||||
$this->meta = $player->getDirection() & 0x03;
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true); //Bottom
|
||||
$this->getLevel()->setBlock($block, $this, true, true); //Bottom
|
||||
$this->getLevel()->setBlock($blockUp, $b = Block::get($this->id, $metaUp), true); //Top
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -83,15 +248,15 @@ abstract class Door extends Transparent{
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === $this->id){
|
||||
$this->getLevel()->setBlock($down, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($down, new Air(), true);
|
||||
}
|
||||
}else{
|
||||
$up = $this->getSide(1);
|
||||
if($up->getID() === $this->id){
|
||||
$this->getLevel()->setBlock($up, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($up, new Air(), true);
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -101,12 +266,12 @@ abstract class Door extends Transparent{
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === $this->id){
|
||||
$meta = $down->getDamage() ^ 0x04;
|
||||
$this->getLevel()->setBlock($down, Block::get($this->id, $meta), true, false, true);
|
||||
$this->getLevel()->setBlock($down, Block::get($this->id, $meta), true);
|
||||
$players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->getID()]);
|
||||
}
|
||||
$pk = new LevelEventPacket;
|
||||
$pk = new LevelEventPacket();
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
@ -120,12 +285,12 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}else{
|
||||
$this->meta ^= 0x04;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->getID()]);
|
||||
}
|
||||
$pk = new LevelEventPacket;
|
||||
$pk = new LevelEventPacket();
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
|
@ -26,7 +26,7 @@ use pocketmine\item\Item;
|
||||
class DoubleSlab extends Solid{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::DOUBLE_SLAB, $meta, "Double Slab");
|
||||
$names = array(
|
||||
$names = [
|
||||
0 => "Stone",
|
||||
1 => "Sandstone",
|
||||
2 => "Wooden",
|
||||
@ -34,7 +34,8 @@ class DoubleSlab extends Solid{
|
||||
4 => "Brick",
|
||||
5 => "Stone Brick",
|
||||
6 => "Quartz",
|
||||
);
|
||||
7 => "",
|
||||
];
|
||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Slab";
|
||||
$this->hardness = 30;
|
||||
}
|
||||
@ -58,9 +59,9 @@ class DoubleSlab extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::SLAB, $this->meta & 0x07, 2),
|
||||
);
|
||||
return [
|
||||
[Item::SLAB, $this->meta & 0x07, 2],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -26,14 +26,14 @@ use pocketmine\item\Item;
|
||||
class DoubleWoodSlab extends Solid{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::DOUBLE_WOOD_SLAB, $meta, "Double Wooden Slab");
|
||||
$names = array(
|
||||
$names = [
|
||||
0 => "Oak",
|
||||
1 => "Spruce",
|
||||
2 => "Birch",
|
||||
3 => "Jungle",
|
||||
4 => "Acacia",
|
||||
5 => "Dark Oak",
|
||||
);
|
||||
];
|
||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||
$this->hardness = 15;
|
||||
}
|
||||
@ -56,9 +56,9 @@ class DoubleWoodSlab extends Solid{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array(Item::WOOD_SLAB, $this->meta & 0x07, 2),
|
||||
);
|
||||
return [
|
||||
[Item::WOOD_SLAB, $this->meta & 0x07, 2],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -42,9 +42,9 @@ class Emerald extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::EMERALD_BLOCK, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::EMERALD_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ class EmeraldOre extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::EMERALD, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::EMERALD, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
43
src/pocketmine/block/EndPortal.php
Normal file
43
src/pocketmine/block/EndPortal.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
class EndPortal extends Solid{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::END_PORTAL, $meta, "End Portal");
|
||||
$this->hardness = 18000000;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + (($this->getDamage() & 0x04) > 0 ? 1 : 0.8125),
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}
|
48
src/pocketmine/block/EndStone.php
Normal file
48
src/pocketmine/block/EndStone.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class EndStone extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::END_STONE, 0, "End Stone");
|
||||
$this->hardness = 45;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
switch($item->isPickaxe()){
|
||||
case 5:
|
||||
return 0.6;
|
||||
case 4:
|
||||
return 0.75;
|
||||
case 3:
|
||||
return 1.15;
|
||||
case 2:
|
||||
return 0.4;
|
||||
case 1:
|
||||
return 2.25;
|
||||
default:
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,19 +21,52 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
use pocketmine\nbt\tag\Double;
|
||||
use pocketmine\nbt\tag\Enum;
|
||||
use pocketmine\nbt\tag\Float;
|
||||
use pocketmine\nbt\tag\Int;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Fallable extends Solid{
|
||||
abstract class Fallable extends Solid{
|
||||
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->hasPhysics = true;
|
||||
}
|
||||
public $hasPhysics = true;
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, true);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($this->hasPhysics === true and $type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::AIR or ($down instanceof Liquid)){
|
||||
$fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
|
||||
"Pos" => new Enum("Pos", [
|
||||
new Double("", $this->x + 0.5),
|
||||
new Double("", $this->y),
|
||||
new Double("", $this->z + 0.5)
|
||||
]),
|
||||
"Motion" => new Enum("Motion", [
|
||||
new Double("", 0),
|
||||
new Double("", 0),
|
||||
new Double("", 0)
|
||||
]),
|
||||
"Rotation" => new Enum("Rotation", [
|
||||
new Float("", 0),
|
||||
new Float("", 0)
|
||||
]),
|
||||
"TileID" => new Int("TileID", $this->getID()),
|
||||
"Data" => new Byte("Data", $this->getDamage()),
|
||||
]));
|
||||
|
||||
$fall->spawnToAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
class Farmland extends Solid{
|
||||
public function __construct($meta = 0){
|
||||
@ -29,9 +30,21 @@ class Farmland extends Solid{
|
||||
$this->hardness = 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array(Item::DIRT, 0, 1),
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 0.9375,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -21,12 +21,39 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
class Fence extends Transparent{
|
||||
public function __construct(){
|
||||
parent::__construct(self::FENCE, 0, "Fence");
|
||||
parent::__construct(self::FENCE, 0, "Oak Fence");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
$flag = $this->canConnect($this->getSide(2));
|
||||
$flag1 = $this->canConnect($this->getSide(3));
|
||||
$flag2 = $this->canConnect($this->getSide(4));
|
||||
$flag3 = $this->canConnect($this->getSide(5));
|
||||
|
||||
$f = $flag2 ? 0 : 0.375;
|
||||
$f1 = $flag3 ? 1 : 0.625;
|
||||
$f2 = $flag ? 0 : 0.375;
|
||||
$f3 = $flag1 ? 1 : 0.625;
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $f,
|
||||
$this->y,
|
||||
$this->z + $f2,
|
||||
$this->x + $f1,
|
||||
$this->y + 1,
|
||||
$this->z + $f3
|
||||
);
|
||||
}
|
||||
|
||||
public function canConnect(Block $block){
|
||||
return (!($block instanceof Fence) and !($block instanceof FenceGate)) ? $block->isSolid : true;
|
||||
}
|
||||
|
||||
}
|
30
src/pocketmine/block/FenceAcacia.php
Normal file
30
src/pocketmine/block/FenceAcacia.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceAcacia extends Fence{
|
||||
public function __construct(){
|
||||
Transparent::__construct(self::FENCE_ACACIA, 0, "Acacia Fence");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
30
src/pocketmine/block/FenceBirch.php
Normal file
30
src/pocketmine/block/FenceBirch.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceBirch extends Fence{
|
||||
public function __construct(){
|
||||
Transparent::__construct(self::FENCE_BIRCH, 0, "Birch Fence");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
30
src/pocketmine/block/FenceDarkOak.php
Normal file
30
src/pocketmine/block/FenceDarkOak.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceDarkOak extends Fence{
|
||||
public function __construct(){
|
||||
Transparent::__construct(self::FENCE_DARK_OAK, 0, "Dark Oak Fence");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
@ -22,11 +22,12 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\Player;
|
||||
|
||||
class FenceGate extends Transparent{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::FENCE_GATE, $meta, "Fence Gate");
|
||||
parent::__construct(self::FENCE_GATE, $meta, "Oak Fence Gate");
|
||||
$this->isActivable = true;
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
@ -36,39 +37,68 @@ class FenceGate extends Transparent{
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
if(($this->getDamage() & 0x04) > 0){
|
||||
return null;
|
||||
}
|
||||
|
||||
$i = ($this->getDamage() & 0x03);
|
||||
if($i === 2 and $i === 0){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z + 0.375,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 0.625
|
||||
);
|
||||
}else{
|
||||
return new AxisAlignedBB(
|
||||
$this->x + 0.375,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 0.625,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$faces = array(
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
3 => 2,
|
||||
);
|
||||
];
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03;
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
$faces = array(
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
3 => 2,
|
||||
);
|
||||
];
|
||||
$this->meta = ($faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03) | ((~$this->meta) & 0x04);
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
36
src/pocketmine/block/FenceGateAcacia.php
Normal file
36
src/pocketmine/block/FenceGateAcacia.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateAcacia extends FenceGate{
|
||||
public function __construct($meta = 0){
|
||||
Transparent::__construct(self::FENCE_GATE_ACACIA, $meta, "Acacia Fence Gate");
|
||||
$this->isActivable = true;
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
36
src/pocketmine/block/FenceGateBirch.php
Normal file
36
src/pocketmine/block/FenceGateBirch.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateBirch extends FenceGate{
|
||||
public function __construct($meta = 0){
|
||||
Transparent::__construct(self::FENCE_GATE_BIRCH, $meta, "Birch Fence Gate");
|
||||
$this->isActivable = true;
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
36
src/pocketmine/block/FenceGateDarkOak.php
Normal file
36
src/pocketmine/block/FenceGateDarkOak.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateDarkOak extends FenceGate{
|
||||
public function __construct($meta = 0){
|
||||
Transparent::__construct(self::FENCE_GATE_DARK_OAK, $meta, "Dark Oak Fence Gate");
|
||||
$this->isActivable = true;
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
36
src/pocketmine/block/FenceGateJungle.php
Normal file
36
src/pocketmine/block/FenceGateJungle.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateJungle extends FenceGate{
|
||||
public function __construct($meta = 0){
|
||||
Transparent::__construct(self::FENCE_GATE_JUNGLE, $meta, "Jungle Fence Gate");
|
||||
$this->isActivable = true;
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
36
src/pocketmine/block/FenceGateSpruce.php
Normal file
36
src/pocketmine/block/FenceGateSpruce.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateSpruce extends FenceGate{
|
||||
public function __construct($meta = 0){
|
||||
Transparent::__construct(self::FENCE_GATE_SPRUCE, $meta, "Spruce Fence Gate");
|
||||
$this->isActivable = true;
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
30
src/pocketmine/block/FenceJungle.php
Normal file
30
src/pocketmine/block/FenceJungle.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceJungle extends Fence{
|
||||
public function __construct(){
|
||||
Transparent::__construct(self::FENCE_JUNGLE, 0, "Jungle Fence");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
30
src/pocketmine/block/FenceSpruce.php
Normal file
30
src/pocketmine/block/FenceSpruce.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceSpruce extends Fence{
|
||||
public function __construct(){
|
||||
Transparent::__construct(self::FENCE_SPRUCE, 0, "Spruce Fence");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 15;
|
||||
}
|
||||
}
|
@ -21,10 +21,18 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Fire extends Flowable{
|
||||
|
||||
public $hasEntityCollision = true;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::FIRE, $meta, "Fire");
|
||||
$this->isReplaceable = true;
|
||||
@ -33,6 +41,21 @@ class Fire extends Flowable{
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
|
||||
$entity->attack($ev->getFinalDamage(), $ev);
|
||||
|
||||
$ev = new EntityCombustByBlockEvent($this, $entity, 8);
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev);
|
||||
if(!$ev->isCancelled()){
|
||||
$entity->setOnFire($ev->getDuration());
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [];
|
||||
}
|
||||
@ -45,12 +68,12 @@ class Fire extends Flowable{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getID() !== self::NETHERRACK){
|
||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
|
@ -22,11 +22,10 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class Flowable extends Transparent{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isFlowable = true;
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = false;
|
||||
}
|
||||
abstract class Flowable extends Transparent{
|
||||
|
||||
public $isFlowable = true;
|
||||
public $isFullBlock = false;
|
||||
public $isSolid = false;
|
||||
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Generic extends Block{
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
return $this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
return $this->breakable;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
return $this->getLevel()->setBlock($this, new Air(), true, false, true);
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($this->hasPhysics === true and $type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::AIR or ($down instanceof Liquid)){
|
||||
$data = array(
|
||||
"x" => $this->x + 0.5,
|
||||
"y" => $this->y + 0.5,
|
||||
"z" => $this->z + 0.5,
|
||||
"Tile" => $this->id,
|
||||
);
|
||||
$server = Server::getInstance();
|
||||
/*$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
//TODO
|
||||
//$e = $server->api->entity->add($this->getLevel(), ENTITY_FALLING, FALLING_SAND, $data);
|
||||
//$e->spawnToAll();
|
||||
$server->api->block->blockUpdateAround(clone $this, Level::BLOCK_UPDATE_NORMAL, 1);*/
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
return $this->isActivable;
|
||||
}
|
||||
}
|
@ -22,11 +22,9 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class GlassPane extends Transparent{
|
||||
class GlassPane extends Thin{
|
||||
public function __construct(){
|
||||
parent::__construct(self::GLASS_PANE, 0, "Glass Pane");
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = false;
|
||||
}
|
||||
|
||||
}
|
@ -54,9 +54,9 @@ class GlowingRedstoneOre extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::REDSTONE_DUST, 0, mt_rand(4, 5)),
|
||||
);
|
||||
return [
|
||||
[Item::REDSTONE_DUST, 0, mt_rand(4, 5)],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ class Glowstone extends Transparent{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array(Item::GLOWSTONE_DUST, 0, mt_rand(2, 4)),
|
||||
);
|
||||
return [
|
||||
[Item::GLOWSTONE_DUST, 0, mt_rand(2, 4)],
|
||||
];
|
||||
}
|
||||
}
|
@ -42,9 +42,9 @@ class Gold extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::GOLD_BLOCK, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::GOLD_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ class GoldOre extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 4){
|
||||
return array(
|
||||
array(Item::GOLD_ORE, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::GOLD_ORE, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -21,18 +21,25 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\generator\object\TallGrass;
|
||||
use pocketmine\level\generator\object\TallGrass as TallGrassObject;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
class Grass extends Solid{
|
||||
|
||||
public $isActivable = true;
|
||||
protected $hardness = 3;
|
||||
protected $id = self::GRASS;
|
||||
protected $meta = 0;
|
||||
protected $name = "Grass";
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::GRASS, 0, "Grass");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 3;
|
||||
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
@ -47,11 +54,13 @@ class Grass extends Solid{
|
||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||
$block = $this->getLevel()->getBlockIdAt($x, $y, $z);
|
||||
if($block === Block::DIRT){
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
if($block->getID() === Block::DIRT){
|
||||
if($block->getSide(1) instanceof Transparent){
|
||||
$this->getLevel()->setBlock($block, new Grass());
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass()));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($block, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,7 +69,7 @@ class Grass extends Solid{
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
$item->count--;
|
||||
TallGrass::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
|
||||
TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
|
||||
|
||||
return true;
|
||||
}elseif($item->isHoe()){
|
||||
|
@ -31,14 +31,14 @@ class Gravel extends Fallable{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if(mt_rand(1, 10) === 1){
|
||||
return array(
|
||||
array(Item::FLINT, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::FLINT, 0, 1],
|
||||
];
|
||||
}
|
||||
|
||||
return array(
|
||||
array(Item::GRAVEL, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::GRAVEL, 0, 1],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -31,25 +31,25 @@ class HayBale extends Solid{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$faces = array(
|
||||
$faces = [
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0b1000,
|
||||
3 => 0b1000,
|
||||
4 => 0b0100,
|
||||
5 => 0b0100,
|
||||
);
|
||||
];
|
||||
|
||||
$this->meta = ($this->meta & 0x03) | $faces[$face];
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -30,7 +30,7 @@ class Ice extends Transparent{
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$this->getLevel()->setBlock($this, new Water(), true, false, true);
|
||||
$this->getLevel()->setBlock($this, new Water(), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -44,9 +44,9 @@ class Iron extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 3){
|
||||
return array(
|
||||
array(Item::IRON_BLOCK, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::IRON_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -22,11 +22,9 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class IronBars extends Transparent{
|
||||
class IronBars extends Thin{
|
||||
public function __construct(){
|
||||
parent::__construct(self::IRON_BARS, 0, "Iron Bars");
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = false;
|
||||
}
|
||||
|
||||
}
|
@ -49,9 +49,9 @@ class IronDoor extends Door{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::IRON_DOOR, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::IRON_DOOR, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -44,9 +44,9 @@ class IronOre extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 3){
|
||||
return array(
|
||||
array(Item::IRON_ORE, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::IRON_ORE, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -29,8 +29,8 @@ class JungleWoodStairs extends Stair{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -21,11 +21,16 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Ladder extends Transparent{
|
||||
|
||||
public $hasEntityCollision = true;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::LADDER, $meta, "Ladder");
|
||||
$this->isSolid = false;
|
||||
@ -33,17 +38,68 @@ class Ladder extends Transparent{
|
||||
$this->hardness = 2;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$entity->fallDistance = 0;
|
||||
$entity->onGround = true;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
$f = 0.125;
|
||||
|
||||
if($this->meta === 2){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z + 1 - $f,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}elseif($this->meta === 3){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + $f
|
||||
);
|
||||
}elseif($this->meta === 4){
|
||||
return new AxisAlignedBB(
|
||||
$this->x + 1 - $f,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}elseif($this->meta === 5){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + $f,
|
||||
$this->y + 1,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
if($target->isTransparent === false){
|
||||
$faces = array(
|
||||
$faces = [
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 5,
|
||||
);
|
||||
];
|
||||
if(isset($faces[$face])){
|
||||
$this->meta = $faces[$face];
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -65,8 +121,8 @@ class Ladder extends Transparent{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array($this->id, 0, 1),
|
||||
);
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -44,9 +44,9 @@ class Lapis extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 3){
|
||||
return array(
|
||||
array(Item::LAPIS_BLOCK, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::LAPIS_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -45,9 +45,9 @@ class LapisOre extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 3){
|
||||
return array(
|
||||
array(Item::DYE, 4, mt_rand(4, 8)),
|
||||
);
|
||||
return [
|
||||
[Item::DYE, 4, mt_rand(4, 8)],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -21,134 +21,42 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Lava extends Liquid{
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::LAVA, $meta, "Lava");
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$entity->fallDistance *= 0.5;
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4);
|
||||
$entity->attack($ev->getFinalDamage(), $ev);
|
||||
|
||||
$ev = new EntityCombustByBlockEvent($this, $entity, 15);
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev);
|
||||
if(!$ev->isCancelled()){
|
||||
$entity->setOnFire($ev->getDuration());
|
||||
}
|
||||
|
||||
if($entity instanceof Player){
|
||||
$entity->onGround = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
Server::getInstance()->api->block->scheduleBlockUpdate(clone $this, 40, Level::BLOCK_UPDATE_NORMAL);
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, false);
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function getSourceCount(){
|
||||
$count = 0;
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
if($this->getSide($side) instanceof Lava){
|
||||
$b = $this->getSide($side);
|
||||
$level = $b->meta & 0x07;
|
||||
if($level == 0x00){
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
public function checkWater(){
|
||||
for($side = 1; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof Water){
|
||||
$level = $this->meta & 0x07;
|
||||
if($level == 0x00){
|
||||
$this->getLevel()->setBlock($this, new Obsidian(), false, false, true);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, new Cobblestone(), false, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getFrom(){
|
||||
for($side = 0; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof Lava){
|
||||
$tlevel = $b->meta & 0x07;
|
||||
$level = $this->meta & 0x07;
|
||||
if(($tlevel + 2) == $level || ($side == 0x01 && $level == 0x01) || ($tlevel == 6 && $level == 7)){
|
||||
return $b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
//return false;
|
||||
$newId = $this->id;
|
||||
$level = $this->meta & 0x07;
|
||||
if($type !== Level::BLOCK_UPDATE_NORMAL){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->checkWater()){
|
||||
return;
|
||||
}
|
||||
|
||||
$falling = $this->meta >> 3;
|
||||
$down = $this->getSide(0);
|
||||
|
||||
$from = $this->getFrom();
|
||||
if($from !== null || $level == 0x00){
|
||||
if($level !== 0x07){
|
||||
if($down instanceof Air || $down instanceof Lava){
|
||||
$this->getLevel()->setBlock($down, new Lava(0x01), false, false, true);
|
||||
Server::getInstance()->api->block->scheduleBlockUpdate(new Position($down, 0, 0, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b instanceof Lava){
|
||||
|
||||
}elseif($b->isFlowable === true){
|
||||
$this->getLevel()->setBlock($b, new Lava(min($level + 2, 7)), false, false, true);
|
||||
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//Extend Remove for Left Lavas
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$sb = $this->getSide($side);
|
||||
if($sb instanceof Lava){
|
||||
$tlevel = $sb->meta & 0x07;
|
||||
if($tlevel != 0x00){
|
||||
for($s = 0; $s <= 5; $s++){
|
||||
$ssb = $sb->getSide($s);
|
||||
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
$this->getLevel()->setBlock($sb, new Air(), false, false, true);
|
||||
}
|
||||
}
|
||||
$b = $this->getSide(0)->getSide($side);
|
||||
if($b instanceof Lava){
|
||||
$tlevel = $b->meta & 0x07;
|
||||
if($tlevel != 0x00){
|
||||
for($s = 0; $s <= 5; $s++){
|
||||
$ssb = $sb->getSide($s);
|
||||
Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($ssb, $this->level), 40, Level::BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
$this->getLevel()->setBlock($b, new Air(), false, false, true);
|
||||
}
|
||||
}
|
||||
//Server::getInstance()->api->block->scheduleBlockUpdate(Position::fromObject($b, $this->level), 10, Level::BLOCK_UPDATE_NORMAL);
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,9 +21,11 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\LeavesDecayEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Leaves extends Transparent{
|
||||
const OAK = 0;
|
||||
@ -35,12 +37,12 @@ class Leaves extends Transparent{
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::LEAVES, $meta, "Leaves");
|
||||
$names = array(
|
||||
$names = [
|
||||
self::OAK => "Oak Leaves",
|
||||
self::SPRUCE => "Spruce Leaves",
|
||||
self::BIRCH => "Birch Leaves",
|
||||
self::JUNGLE => "Jungle Leaves",
|
||||
);
|
||||
];
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
$this->hardness = 1;
|
||||
}
|
||||
@ -121,16 +123,13 @@ class Leaves extends Transparent{
|
||||
$this->meta &= 0x03;
|
||||
$visited = [];
|
||||
$check = 0;
|
||||
if($this->findLog($this, $visited, 0, $check) === true){
|
||||
$this->getLevel()->setBlock($this, $this, false, false, true);
|
||||
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this));
|
||||
|
||||
if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){
|
||||
$this->getLevel()->setBlock($this, $this, false, false);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
if(mt_rand(1, 20) === 1){ //Saplings
|
||||
$this->getLevel()->dropItem($this, Item::get($this->id, $this->meta & 0x03, 1));
|
||||
}
|
||||
if(($this->meta & 0x03) === self::OAK and mt_rand(1, 200) === 1){ //Apples
|
||||
$this->getLevel()->dropItem($this, Item::get(Item::APPLE, 0, 1));
|
||||
}
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -142,19 +141,19 @@ class Leaves extends Transparent{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$this->meta |= 0x04;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
if($item->isShears()){
|
||||
$drops[] = array(Item::LEAVES, $this->meta & 0x03, 1);
|
||||
$drops[] = [Item::LEAVES, $this->meta & 0x03, 1];
|
||||
}else{
|
||||
if(mt_rand(1, 20) === 1){ //Saplings
|
||||
$drops[] = array(Item::SAPLING, $this->meta & 0x03, 1);
|
||||
$drops[] = [Item::SAPLING, $this->meta & 0x03, 1];
|
||||
}
|
||||
if(($this->meta & 0x03) === self::OAK and mt_rand(1, 200) === 1){ //Apples
|
||||
$drops[] = array(Item::APPLE, 0, 1);
|
||||
$drops[] = [Item::APPLE, 0, 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,18 +21,20 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\LeavesDecayEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Leaves2 extends Leaves{
|
||||
|
||||
public function __construct($meta = 0){
|
||||
Transparent::__construct(self::LEAVES, $meta, "Leaves");
|
||||
$names = array(
|
||||
$names = [
|
||||
self::ACACIA => "Acacia Leaves",
|
||||
self::DARK_OAK => "Dark Oak Leaves",
|
||||
);
|
||||
];
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
$this->hardness = 1;
|
||||
}
|
||||
@ -113,13 +115,13 @@ class Leaves2 extends Leaves{
|
||||
$this->meta &= 0x03;
|
||||
$visited = [];
|
||||
$check = 0;
|
||||
if($this->findLog($this, $visited, 0, $check) === true){
|
||||
$this->getLevel()->setBlock($this, $this, false, false, true);
|
||||
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new LeavesDecayEvent($this));
|
||||
|
||||
if($ev->isCancelled() or $this->findLog($this, $visited, 0, $check) === true){
|
||||
$this->getLevel()->setBlock($this, $this, false, false);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
if(mt_rand(1, 20) === 1){ //Saplings
|
||||
$this->getLevel()->dropItem($this, Item::get($this->id, $this->meta & 0x03, 1));
|
||||
}
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -131,16 +133,16 @@ class Leaves2 extends Leaves{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$this->meta |= 0x04;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
if($item->isShears()){
|
||||
$drops[] = array(Item::LEAVES2, $this->meta & 0x03, 1);
|
||||
$drops[] = [Item::LEAVES2, $this->meta & 0x03, 1];
|
||||
}else{
|
||||
if(mt_rand(1, 20) === 1){ //Saplings
|
||||
$drops[] = array(Item::SAPLING, $this->meta & 0x03, 1);
|
||||
$drops[] = [Item::SAPLING, $this->meta & 0x03, 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,13 +22,400 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class Liquid extends Transparent{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isLiquid = true;
|
||||
$this->breakable = false;
|
||||
$this->isReplaceable = true;
|
||||
$this->isSolid = false;
|
||||
$this->isFullBlock = true;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
abstract class Liquid extends Transparent{
|
||||
public $hasEntityCollision = true;
|
||||
|
||||
public $isLiquid = true;
|
||||
public $breakable = false;
|
||||
public $isReplaceable = true;
|
||||
public $isSolid = false;
|
||||
public $isFullBlock = true;
|
||||
|
||||
public $adjacentSources = 0;
|
||||
public $isOptimalFlowDirection = [0, 0, 0, 0];
|
||||
public $flowCost = [0, 0, 0, 0];
|
||||
|
||||
public function getFluidHeightPercent(){
|
||||
$d = $this->meta;
|
||||
if($d >= 8){
|
||||
$d = 0;
|
||||
}
|
||||
|
||||
return ($d + 1) / 9;
|
||||
}
|
||||
|
||||
protected function getFlowDecay(Vector3 $pos){
|
||||
if(!($pos instanceof Block)){
|
||||
$pos = $this->getLevel()->getBlock($pos);
|
||||
}
|
||||
|
||||
if($pos->getID() !== $this->getID()){
|
||||
return -1;
|
||||
}else{
|
||||
return $pos->getDamage();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getEffectiveFlowDecay(Vector3 $pos){
|
||||
if(!($pos instanceof Block)){
|
||||
$pos = $this->getLevel()->getBlock($pos);
|
||||
}
|
||||
|
||||
if($pos->getID() !== $this->getID()){
|
||||
return -1;
|
||||
}
|
||||
|
||||
$decay = $pos->getDamage();
|
||||
|
||||
if($decay >= 8){
|
||||
$decay = 0;
|
||||
}
|
||||
|
||||
return $decay;
|
||||
}
|
||||
|
||||
public function getFlowVector(){
|
||||
$vector = new Vector3(0, 0, 0);
|
||||
|
||||
$decay = $this->getEffectiveFlowDecay($this);
|
||||
|
||||
for($j = 0; $j < 4; ++$j){
|
||||
|
||||
$x = $this->x;
|
||||
$y = $this->y;
|
||||
$z = $this->z;
|
||||
|
||||
if($j === 0){
|
||||
--$x;
|
||||
}elseif($j === 1){
|
||||
++$x;
|
||||
}elseif($j === 2){
|
||||
--$z;
|
||||
}elseif($j === 3){
|
||||
++$z;
|
||||
}
|
||||
$sideBlock = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
$blockDecay = $this->getEffectiveFlowDecay($sideBlock);
|
||||
|
||||
if($blockDecay < 0){
|
||||
if(!$sideBlock->isFlowable){
|
||||
continue;
|
||||
}
|
||||
|
||||
$blockDecay = $this->getEffectiveFlowDecay($sideBlock->getSide(0));
|
||||
|
||||
if($blockDecay >= 0){
|
||||
$realDecay = $blockDecay - ($decay - 8);
|
||||
$vector = $vector->add(($sideBlock->x - $this->x) * $realDecay, ($sideBlock->y - $this->y) * $realDecay, ($sideBlock->z - $this->z) * $realDecay);
|
||||
}
|
||||
|
||||
continue;
|
||||
}else{
|
||||
$realDecay = $blockDecay - $decay;
|
||||
$vector = $vector->add(($sideBlock->x - $this->x) * $realDecay, ($sideBlock->y - $this->y) * $realDecay, ($sideBlock->z - $this->z) * $realDecay);
|
||||
}
|
||||
}
|
||||
|
||||
if($this->getDamage() >= 8){
|
||||
$falling = false;
|
||||
|
||||
if(!$this->getLevel()->getBlock($this->add(0, 0, -1))->isFlowable){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(0, 0, 1))->isFlowable){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(-1, 0, 0))->isFlowable){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(1, 0, 0))->isFlowable){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(0, 1, -1))->isFlowable){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(0, 1, 1))->isFlowable){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(-1, 1, 0))->isFlowable){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(1, 1, 0))->isFlowable){
|
||||
$falling = true;
|
||||
}
|
||||
|
||||
if($falling){
|
||||
$vector = $vector->normalize()->add(0, -6, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return $vector->normalize();
|
||||
}
|
||||
|
||||
public function addVelocityToEntity(Entity $entity, Vector3 $vector){
|
||||
$flow = $this->getFlowVector();
|
||||
$vector->x += $flow->x;
|
||||
$vector->y += $flow->y;
|
||||
$vector->z += $flow->z;
|
||||
}
|
||||
|
||||
public function tickRate(){
|
||||
if($this instanceof Water){
|
||||
return 5;
|
||||
}elseif($this instanceof Lava){
|
||||
return 30;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$this->checkForHarden();
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
}elseif($type === Level::BLOCK_UPDATE_SCHEDULED){
|
||||
$decay = $this->getFlowDecay($this);
|
||||
$multiplier = $this instanceof Lava ? 2 : 1;
|
||||
|
||||
$flag = true;
|
||||
|
||||
if($decay > 0){
|
||||
$smallestFlowDecay = -100;
|
||||
$this->adjacentSources = 0;
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->getSide(4), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->getSide(5), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->getSide(2), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->getSide(3), $smallestFlowDecay);
|
||||
|
||||
$k = $smallestFlowDecay + $multiplier;
|
||||
|
||||
if($k >= 8 or $smallestFlowDecay < 0){
|
||||
$k = -1;
|
||||
}
|
||||
|
||||
if(($topFlowDecay = $this->getFlowDecay($this->getSide(1))) >= 0){
|
||||
if($topFlowDecay >= 8){
|
||||
$k = $topFlowDecay;
|
||||
}else{
|
||||
$k = $topFlowDecay | 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if($this->adjacentSources >= 2 and $this instanceof Water){
|
||||
$bottomBlock = $this->getSide(0);
|
||||
if($bottomBlock->isSolid){
|
||||
$k = 0;
|
||||
}elseif($bottomBlock instanceof Water and $bottomBlock->getDamage() === 0){
|
||||
$k = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if($this instanceof Lava and $decay < 8 and $k < 8 and $k > 1 and mt_rand(0, 4) !== 0){
|
||||
$k = $decay;
|
||||
$flag = false;
|
||||
}
|
||||
|
||||
if($k !== $decay){
|
||||
$decay = $k;
|
||||
if($decay < 0){
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::AIR), true);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, Block::get($this->id, $decay), true);
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
}
|
||||
}elseif($flag){
|
||||
//$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
//$this->updateFlow();
|
||||
}
|
||||
}else{
|
||||
//$this->updateFlow();
|
||||
}
|
||||
|
||||
$bottomBlock = $this->getSide(0);
|
||||
|
||||
if($bottomBlock->isFlowable or $bottomBlock instanceof Liquid){
|
||||
if($this instanceof Lava and $bottomBlock instanceof Water){
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get(Item::STONE), true);
|
||||
return;
|
||||
}
|
||||
|
||||
if($decay >= 8){
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay), true);
|
||||
$this->getLevel()->scheduleUpdate($bottomBlock, $this->tickRate());
|
||||
}else{
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay + 8), true);
|
||||
$this->getLevel()->scheduleUpdate($bottomBlock, $this->tickRate());
|
||||
}
|
||||
}elseif($decay >= 0 and ($decay === 0 or !$bottomBlock->isFlowable)){
|
||||
$flags = $this->getOptimalFlowDirections();
|
||||
|
||||
$l = $decay + $multiplier;
|
||||
|
||||
if($decay >= 8){
|
||||
$l = 1;
|
||||
}
|
||||
|
||||
if($l >= 8){
|
||||
$this->checkForHarden();
|
||||
return;
|
||||
}
|
||||
|
||||
if($flags[0]){
|
||||
$this->flowIntoBlock($this->getSide(4), $l);
|
||||
}
|
||||
|
||||
if($flags[1]){
|
||||
$this->flowIntoBlock($this->getSide(5), $l);
|
||||
}
|
||||
|
||||
if($flags[2]){
|
||||
$this->flowIntoBlock($this->getSide(2), $l);
|
||||
}
|
||||
|
||||
if($flags[3]){
|
||||
$this->flowIntoBlock($this->getSide(3), $l);
|
||||
}
|
||||
}
|
||||
|
||||
$this->checkForHarden();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private function flowIntoBlock(Block $block, $newFlowDecay){
|
||||
if($block->isFlowable){
|
||||
if($block->getID() > 0){
|
||||
$this->getLevel()->useBreakOn($block);
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $newFlowDecay), true);
|
||||
$this->getLevel()->scheduleUpdate($block, $this->tickRate());
|
||||
}
|
||||
}
|
||||
|
||||
private function calculateFlowCost(Block $block, $accumulatedCost, $previousDirection){
|
||||
$cost = 1000;
|
||||
|
||||
for($j = 0; $j < 4; ++$j){
|
||||
if(
|
||||
($j === 0 and $previousDirection === 1) or
|
||||
($j === 1 and $previousDirection === 0) or
|
||||
($j === 2 and $previousDirection === 3) or
|
||||
($j === 3 and $previousDirection === 2)
|
||||
){
|
||||
$x = $block->x;
|
||||
$y = $block->y;
|
||||
$z = $block->z;
|
||||
|
||||
if($j === 0){
|
||||
--$x;
|
||||
}elseif($j === 1){
|
||||
++$x;
|
||||
}elseif($j === 2){
|
||||
--$z;
|
||||
}elseif($j === 3){
|
||||
++$z;
|
||||
}
|
||||
$blockSide = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
|
||||
if(!$blockSide->isFlowable and !($blockSide instanceof Liquid)){
|
||||
continue;
|
||||
}elseif($blockSide instanceof Liquid and $blockSide->getDamage() === 0){
|
||||
continue;
|
||||
}elseif($blockSide->getSide(0)->isFlowable){
|
||||
return $accumulatedCost;
|
||||
}
|
||||
|
||||
if($accumulatedCost >= 4){
|
||||
continue;
|
||||
}
|
||||
|
||||
$realCost = $this->calculateFlowCost($blockSide, $accumulatedCost + 1, $j);
|
||||
|
||||
if($realCost < $cost){
|
||||
$cost = $realCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $cost;
|
||||
}
|
||||
|
||||
private function getOptimalFlowDirections(){
|
||||
for($j = 0; $j < 4; ++$j){
|
||||
$this->flowCost[$j] = 1000;
|
||||
|
||||
$x = $this->x;
|
||||
$y = $this->y;
|
||||
$z = $this->z;
|
||||
|
||||
if($j === 0){
|
||||
--$x;
|
||||
}elseif($j === 1){
|
||||
++$x;
|
||||
}elseif($j === 2){
|
||||
--$z;
|
||||
}elseif($j === 3){
|
||||
++$z;
|
||||
}
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
|
||||
if(!$block->isFlowable and !($block instanceof Liquid)){
|
||||
continue;
|
||||
}elseif($block instanceof Liquid and $block->getDamage() === 0){
|
||||
continue;
|
||||
}elseif($block->getSide(0)->isFlowable){
|
||||
$this->flowCost[$j] = 0;
|
||||
}else{
|
||||
$this->flowCost[$j] = $this->calculateFlowCost($block, 1, $j);
|
||||
}
|
||||
}
|
||||
|
||||
$minCost = $this->flowCost[0];
|
||||
|
||||
for($i = 1; $i < 4; ++$i){
|
||||
if($this->flowCost[$i] < $minCost){
|
||||
$minCost = $this->flowCost[$i];
|
||||
}
|
||||
}
|
||||
|
||||
for($i = 0; $i < 4; ++$i){
|
||||
$this->isOptimalFlowDirection[$i] = ($this->flowCost[$i] === $minCost);
|
||||
}
|
||||
|
||||
return $this->isOptimalFlowDirection;
|
||||
}
|
||||
|
||||
private function getSmallestFlowDecay(Vector3 $pos, $decay){
|
||||
$blockDecay = $this->getFlowDecay($pos);
|
||||
|
||||
if($blockDecay < 0){
|
||||
return $decay;
|
||||
}elseif($blockDecay === 0){
|
||||
++$this->adjacentSources;
|
||||
}elseif($blockDecay >= 8){
|
||||
$blockDecay = 0;
|
||||
}
|
||||
|
||||
return ($decay >= 0 && $blockDecay >= $decay) ? $decay : $blockDecay;
|
||||
}
|
||||
|
||||
private function checkForHarden(){
|
||||
if($this instanceof Lava){
|
||||
$colliding = false;
|
||||
for($side = 0; $side <= 5 and !$colliding; ++$side){
|
||||
$colliding = $this->getSide($side) instanceof Water;
|
||||
}
|
||||
|
||||
if($colliding){
|
||||
if($this->getDamage() === 0){
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::OBSIDIAN), true);
|
||||
}elseif($this->getDamage() <= 4){
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::COBBLESTONE), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
}
|
@ -31,14 +31,10 @@ class LitPumpkin extends Solid{
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$faces = array(
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
);
|
||||
$this->meta = $faces[$player->getDirection()];
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
if($player instanceof Player){
|
||||
$this->meta = ((int) $player->getDirection() + 5) % 4;
|
||||
}
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ class Melon extends Transparent{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array(Item::MELON_SLICE, 0, mt_rand(3, 7)),
|
||||
);
|
||||
return [
|
||||
[Item::MELON_SLICE, 0, mt_rand(3, 7)],
|
||||
];
|
||||
}
|
||||
}
|
@ -21,41 +21,31 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class MelonStem extends Flowable{
|
||||
class MelonStem extends Crops{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::MELON_STEM, $meta, "Melon Stem");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //TODO: Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get(Item::MELON_SEEDS, 0, mt_rand(0, 2)));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
$block = clone $this;
|
||||
++$block->meta;
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($this, $block));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($this, $ev->getNewState(), true);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}else{
|
||||
@ -68,7 +58,10 @@ class MelonStem extends Flowable{
|
||||
$side = $this->getSide(mt_rand(2, 5));
|
||||
$d = $side->getSide(0);
|
||||
if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){
|
||||
$this->getLevel()->setBlock($side, new Melon(), true, false, true);
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, new Melon()));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($side, $ev->getNewState(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -79,23 +72,9 @@ class MelonStem extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->count--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return array(
|
||||
array(Item::MELON_SEEDS, 0, mt_rand(0, 2)),
|
||||
);
|
||||
return [
|
||||
[Item::MELON_SEEDS, 0, mt_rand(0, 2)],
|
||||
];
|
||||
}
|
||||
}
|
52
src/pocketmine/block/MonsterSpawner.php
Normal file
52
src/pocketmine/block/MonsterSpawner.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class MonsterSpawner extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::MONSTER_SPAWNER, 0, "Monster Spawner");
|
||||
$this->hardness = 25;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
switch($item->isPickaxe()){
|
||||
case 5:
|
||||
return 0.95;
|
||||
case 4:
|
||||
return 1.25;
|
||||
case 3:
|
||||
return 1.9;
|
||||
case 2:
|
||||
return 0.65;
|
||||
case 1:
|
||||
return 3.75;
|
||||
default:
|
||||
return 25;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [];
|
||||
}
|
||||
}
|
@ -49,9 +49,9 @@ class MossStone extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::MOSS_STONE, $this->meta, 1),
|
||||
);
|
||||
return [
|
||||
[Item::MOSS_STONE, $this->meta, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
59
src/pocketmine/block/Mycelium.php
Normal file
59
src/pocketmine/block/Mycelium.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Mycelium extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::MYCELIUM, 0, "Mycelium");
|
||||
$this->hardness = 2.5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
];
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
//TODO: light levels
|
||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
if($block->getID() === Block::DIRT){
|
||||
if($block->getSide(1) instanceof Transparent){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Mycelium()));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($block, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -49,9 +49,9 @@ class NetherBrick extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::NETHER_BRICKS, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::NETHER_BRICKS, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -49,9 +49,9 @@ class Netherrack extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 1){
|
||||
return array(
|
||||
array(Item::NETHERRACK, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::NETHERRACK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -40,9 +40,9 @@ class Obsidian extends Solid{
|
||||
|
||||
public function getDrops(Item $item){
|
||||
if($item->isPickaxe() >= 5){
|
||||
return array(
|
||||
array(Item::OBSIDIAN, 0, 1),
|
||||
);
|
||||
return [
|
||||
[Item::OBSIDIAN, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
@ -32,14 +32,14 @@ class Planks extends Solid{
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::PLANKS, $meta, "Wood Planks");
|
||||
$names = array(
|
||||
$names = [
|
||||
self::OAK => "Oak Wood Planks",
|
||||
self::SPRUCE => "Spruce Wood Planks",
|
||||
self::BIRCH => "Birch Wood Planks",
|
||||
self::JUNGLE => "Jungle Wood Planks",
|
||||
self::ACACIA => "Acacia Wood Planks",
|
||||
self::DARK_OAK => "Jungle Wood Planks",
|
||||
);
|
||||
];
|
||||
$this->name = $names[$this->meta & 0x07];
|
||||
$this->hardness = 15;
|
||||
}
|
||||
|
@ -19,9 +19,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
|
||||
class TNTPrimed extends Entity implements Explosive{
|
||||
namespace pocketmine\block;
|
||||
|
||||
class Podzol extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::PODZOL, 0, "Podzol");
|
||||
$this->hardness = 2.5;
|
||||
}
|
||||
}
|
@ -22,71 +22,18 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Potato extends Flowable{
|
||||
class Potato extends Crops{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::POTATO_BLOCK, $meta, "Potato Block");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 0;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$this->meta = 0x07;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
$item->count--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //TODO: Replace with common break method
|
||||
$this->getLevel()->dropItem($this, Item::get(Item::POTATO, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if($this->meta < 0x07){
|
||||
++$this->meta;
|
||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}else{
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = array(Item::POTATO, 0, mt_rand(1, 4));
|
||||
$drops[] = [Item::POTATO, 0, mt_rand(1, 4)];
|
||||
}else{
|
||||
$drops[] = array(Item::POTATO, 0, 1);
|
||||
$drops[] = [Item::POTATO, 0, 1];
|
||||
}
|
||||
|
||||
return $drops;
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Pumpkin extends Solid{
|
||||
public function __construct(){
|
||||
@ -28,4 +30,13 @@ class Pumpkin extends Solid{
|
||||
$this->hardness = 5;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
if($player instanceof Player){
|
||||
$this->meta = ((int) $player->getDirection() + 5) % 4;
|
||||
}
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user