mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-14 05:15:11 +00:00
Compare commits
1152 Commits
Alpha_1.4d
...
api/1.12.0
Author | SHA1 | Date | |
---|---|---|---|
2b2a1b18e7 | |||
1b812d373c | |||
5621ab0c49 | |||
4258e22c02 | |||
0380e9009a | |||
866fde5351 | |||
9f953fa675 | |||
4d95c65d95 | |||
26c9eed82e | |||
f3c46b12c5 | |||
b14d14d3d5 | |||
60ab35774a | |||
2df901b064 | |||
0c09361c46 | |||
1ebf2476df | |||
fe85b5026d | |||
bfd3fb6636 | |||
0723112207 | |||
be9f5521e1 | |||
6063738e69 | |||
ef738ef299 | |||
5796784442 | |||
a1cc60d472 | |||
f7ec1de0fd | |||
b856e5e909 | |||
f7e6246dc2 | |||
b166628940 | |||
4e76c30788 | |||
33e312c7d0 | |||
2ac27bd382 | |||
f490ff8074 | |||
eeef81e2b1 | |||
4a8ca96aaa | |||
eef33d64e6 | |||
7cf5df7e46 | |||
ac2bcf7e30 | |||
ec226105e4 | |||
2a1a09a923 | |||
20911930cf | |||
2eaa12005e | |||
fdcddcc04b | |||
4fd5e9ba7d | |||
7b17bf416e | |||
d0f743a99e | |||
cbb1c55a06 | |||
d881dbf1a2 | |||
383fcba8e1 | |||
e5f28e0f7a | |||
cf3f32fdae | |||
c4bdbc5443 | |||
62a8f58bb0 | |||
f21ed39c1c | |||
b358a2e474 | |||
21c6eeef11 | |||
96f67bdadf | |||
6ee61cce7b | |||
7f6704f761 | |||
9e4d88a852 | |||
5682026eae | |||
2a805dc0ed | |||
bdb9b1865b | |||
1e03c5b795 | |||
ec82434ef4 | |||
7bafa217c8 | |||
fe55023761 | |||
ac4194eb3f | |||
6e69e15dfd | |||
a53b041984 | |||
d542dfc2ce | |||
188f4d7778 | |||
71490f60f2 | |||
05dbf7b47f | |||
14ff537e71 | |||
9e14435dbb | |||
32680843fa | |||
9768bf4f8a | |||
7c806c7920 | |||
b61c54c9cb | |||
a349f6d4dd | |||
9541c9751b | |||
3c0efe9af2 | |||
24c1e6880d | |||
74917923b6 | |||
f20d5b2c69 | |||
eaa42f8449 | |||
1e2038fac5 | |||
c8abbf4f2f | |||
009a3b657f | |||
5b57fe6967 | |||
f133154919 | |||
8d4decc548 | |||
3bb037204e | |||
c578898aa4 | |||
0f5f71e612 | |||
75cab3dfc3 | |||
03f178379e | |||
ce59703dd0 | |||
a77d82ac81 | |||
1833da01fe | |||
c97e1fdce0 | |||
0e9bff6f4e | |||
3dd4fe706c | |||
9a2170d296 | |||
8a41512194 | |||
51062940c5 | |||
66435d4f6a | |||
c4d63326be | |||
f91a3a2666 | |||
d429992f5b | |||
76c27fc18b | |||
a0f8bc15dc | |||
adc5aa11ac | |||
388f5c2c91 | |||
f64caf6c96 | |||
b2b4cf788c | |||
d7be531868 | |||
5ad4f44dce | |||
7201372b0d | |||
744ea6af8f | |||
1da0a48edb | |||
be6b0656a0 | |||
4f7aac50d3 | |||
149234f125 | |||
cfe5ca91b2 | |||
46f20d36b3 | |||
cde2d39029 | |||
36ddbf286d | |||
8d4abe2f39 | |||
32722856ea | |||
7753b1d8be | |||
92a2be024a | |||
66f28f6dc4 | |||
1122a3c511 | |||
0c6d8b9815 | |||
70a7c4c552 | |||
840690d801 | |||
f3a53be117 | |||
ea7c0cb357 | |||
85c43ba011 | |||
fbbe02a3bc | |||
fb05636694 | |||
63a5269313 | |||
7705d8c52f | |||
419abdaad6 | |||
d6ebff412c | |||
7a34417e67 | |||
76e6ccebd5 | |||
e61db8ad06 | |||
b1edfd7631 | |||
f3bdef7513 | |||
9791071262 | |||
aa38a4885f | |||
de0f653027 | |||
13906b32b8 | |||
925b0c1b07 | |||
db409851e9 | |||
ab18b7833f | |||
1a1b8830a4 | |||
7e539ec85a | |||
563f6f8e4f | |||
82b0dbfe8e | |||
a4769248fb | |||
fb03df3d06 | |||
44b5c23ee1 | |||
bff51322af | |||
cc58d96071 | |||
001915fcd6 | |||
cd607b0cec | |||
5ec4b3f46f | |||
d9a9808844 | |||
f718d06a7d | |||
563f7404fe | |||
0ddf396b08 | |||
d830386786 | |||
49f34ec524 | |||
9ec609d025 | |||
0ead3ec781 | |||
fdf395721e | |||
211e1ae121 | |||
923be2fffc | |||
fb257c16f1 | |||
b33706d427 | |||
6bcb319fb5 | |||
d4b2e3d1b7 | |||
7754aa71a3 | |||
978aa2ba0f | |||
c2b3f7cd7f | |||
3872a21474 | |||
11e2d23b83 | |||
2cd78d4ae3 | |||
08f09cc3c8 | |||
1b13a4c1ec | |||
71587db2be | |||
8caf04ade5 | |||
488fbc27fe | |||
84d1f4596b | |||
6fc7ee2775 | |||
ef00103fec | |||
bdf069ebe1 | |||
5942cafa53 | |||
fbdbac06cc | |||
fba12f2a13 | |||
7ad98d4659 | |||
1d8c29add7 | |||
d4cae729c3 | |||
529f9b148b | |||
20842636f9 | |||
7b699d9afd | |||
ba635b8858 | |||
04f3cc4905 | |||
4a1e122605 | |||
a0739a7b03 | |||
f73bd02198 | |||
ec7db3be4f | |||
2ea8835b12 | |||
0aebcb9f81 | |||
1578fc3ddb | |||
514ce0fb04 | |||
f6e88ec055 | |||
15b4cd8fb3 | |||
f88aed1208 | |||
6ed63edd89 | |||
897774f848 | |||
bf4a8398c4 | |||
05385acb36 | |||
094234dc0f | |||
c2f72ea9ac | |||
e3c48b22cb | |||
5860bdcc4d | |||
1b84340e3f | |||
61828baa8f | |||
11ecaaa87f | |||
b2c25eaf36 | |||
ddc152ae0a | |||
08a612954e | |||
5b10ccf431 | |||
2add19a4c8 | |||
7ee21f6254 | |||
f79476f530 | |||
4fbafe7c2f | |||
d6186fa7c6 | |||
88797d4c6c | |||
fc2e4ddc63 | |||
7f28deefcb | |||
81fe98d4cc | |||
dfec44645b | |||
1ef6328635 | |||
c0782caab9 | |||
298b973604 | |||
5ca4f5416c | |||
c36c0dfa66 | |||
64c366bdb5 | |||
68ea9b067f | |||
79adbdeafe | |||
e09ebb0623 | |||
91388c6b86 | |||
42eda170b5 | |||
6ee3a7b8d7 | |||
18f6e1805f | |||
0b176b3fe0 | |||
bb945446b7 | |||
1d1766a876 | |||
bd560ab3b1 | |||
547aa2ae31 | |||
a993f15387 | |||
1865622b89 | |||
31387ff0be | |||
928660d59a | |||
5e2a21fc26 | |||
410f6ba618 | |||
05a9ad57bd | |||
ba226d03c3 | |||
674a486654 | |||
e9963b603d | |||
e2bae92df8 | |||
8d468a1efb | |||
ddeea2942c | |||
a65c300a0a | |||
363e0e3b13 | |||
6504047292 | |||
87a779afaf | |||
6b1b6711bd | |||
f71cf1c749 | |||
3685d967a8 | |||
d1006de421 | |||
3cf42b558c | |||
5a0d1affcc | |||
414549659a | |||
3b6e10b759 | |||
c2138aa30c | |||
de052a79de | |||
c29ae333a2 | |||
0c041ebca3 | |||
3224cd7dc5 | |||
3f60f7c0fb | |||
c786ace355 | |||
60ac8f91ba | |||
5720cb2be7 | |||
c32a7467bb | |||
0626d27003 | |||
2ae095a15a | |||
5d102c2ede | |||
a7b1c6e086 | |||
d855bbba0b | |||
73d1d131e1 | |||
0aa9586a52 | |||
205f6d50c1 | |||
ac6e2f9bf7 | |||
1ddd58fd3b | |||
66b58e36a1 | |||
86184a230e | |||
b4a0afc2c8 | |||
f2e2cec024 | |||
0117e8dfae | |||
69f841a00c | |||
02ba9ffc16 | |||
71657a2a4e | |||
76767294bf | |||
3cae81c01b | |||
141c0a297e | |||
45c6694ef9 | |||
9b09b7ddd1 | |||
c9adc336ee | |||
d5ba2a72a5 | |||
9f6b5992e3 | |||
e51858ae17 | |||
c2baaf435d | |||
c422b83abf | |||
e0a6d0feab | |||
0a85ad0d1f | |||
91315645cd | |||
47de616ac5 | |||
e0522d8b1a | |||
08f2b7f291 | |||
72c4c01542 | |||
668ddeeb13 | |||
286c1ee880 | |||
ed2ba70a29 | |||
962c28aaca | |||
7d1313c63d | |||
d19631226f | |||
6836e4fe58 | |||
4a79c65544 | |||
d1760d9bb8 | |||
355ddc469c | |||
4e934654ef | |||
38f3dda13b | |||
c68cd2c496 | |||
a6b8170d9c | |||
9da26fdb88 | |||
1666602652 | |||
d2bf92c3ed | |||
93a50d08e7 | |||
1f977f68c0 | |||
91a26c15dd | |||
add380c7ed | |||
652987110a | |||
58253be0a0 | |||
b42424eb22 | |||
1d1a8a316e | |||
a2b3e48b45 | |||
ebc8928c21 | |||
62ba36b474 | |||
2c59983672 | |||
8ae9cd4eaf | |||
275a1e3f60 | |||
6735234bf4 | |||
d66a2d7105 | |||
c882df7465 | |||
f21e457dc0 | |||
6bf30c133a | |||
d34499e67b | |||
c2a3298a7e | |||
b31604a536 | |||
c00370cfbf | |||
7c0bd45d1d | |||
5f2254cc42 | |||
8169803bb4 | |||
5a35e7b058 | |||
1b25cd6ffa | |||
891eeff75a | |||
b4f62bf423 | |||
7c76c1e3d7 | |||
37bc1273ee | |||
ffcdf49912 | |||
3e893ed0f7 | |||
bfb7e8bb9e | |||
5067b96184 | |||
cb2157ea80 | |||
6af87814e3 | |||
5b3e65345f | |||
8aa8ae5094 | |||
b5b46bfd7e | |||
2ae80031f0 | |||
85c5714cbf | |||
bc31df37d0 | |||
29ca349b3d | |||
4ec584d800 | |||
4383e272eb | |||
f9361aa931 | |||
220d2b7bee | |||
d5601b0c9f | |||
5bfc747622 | |||
b0f8c14640 | |||
328cd585c0 | |||
807107e581 | |||
94c2ec8498 | |||
9158cc4f19 | |||
11c13cd666 | |||
284958a21e | |||
91e8bdbd37 | |||
9e0b9a6e5b | |||
e48a3e5713 | |||
1ce7cc64a6 | |||
7f9aad6840 | |||
3af784012c | |||
a6c19734ce | |||
8ddd701d76 | |||
15ee0c37c6 | |||
fc128affc5 | |||
218fd999b0 | |||
eeeaac04e9 | |||
8679ad5b86 | |||
2cd757d80a | |||
be20f61a93 | |||
59e9446fe5 | |||
4f47dac8ec | |||
b54c0835b7 | |||
1e00ff9e4a | |||
1ac7f9f061 | |||
5b3ce2da9d | |||
00942d3a2b | |||
4b442a9d7c | |||
44dfb59409 | |||
696ba08a81 | |||
d80b8524fb | |||
2175d7922a | |||
5fcb0d6aa5 | |||
9ca3ad8971 | |||
a644b46ec4 | |||
9d3f59fab6 | |||
6309d4abf1 | |||
39291e4061 | |||
bb71a3c4a6 | |||
eb0525e892 | |||
f49db47b2e | |||
3ff5e12302 | |||
99ad65ba44 | |||
5f4f996efe | |||
21e0739845 | |||
3a157d0f02 | |||
8e56782138 | |||
116ede3679 | |||
7c0f5987d3 | |||
547e152e40 | |||
7905fbdd29 | |||
ae65701a23 | |||
9134a69936 | |||
907fe8aff6 | |||
afa9acf22f | |||
9a5afff4ab | |||
2f8c281a2e | |||
2096dace68 | |||
8421985102 | |||
f63e859b3a | |||
c56eb0b9df | |||
3f2e5bbef4 | |||
9886eb4768 | |||
ea44eee5df | |||
9173f930ca | |||
80b6a8ebaf | |||
7c64a33389 | |||
9fac896f28 | |||
5bd76e955c | |||
63f1a50be4 | |||
24c6cca664 | |||
9fac990b19 | |||
e8e7938490 | |||
f6c4a726b3 | |||
8eec5e6b5e | |||
bd7fa71d7f | |||
7d406066a7 | |||
3e9196d224 | |||
f30986d187 | |||
f8c144be31 | |||
c61e4adcf1 | |||
5a55040ab9 | |||
83360187c9 | |||
a893174473 | |||
9d97a940a6 | |||
cd21c28d46 | |||
a76be6cf38 | |||
37fd0372cc | |||
ed02026815 | |||
042a143dd6 | |||
4b73dbd9f8 | |||
d4e4430df0 | |||
469ef84733 | |||
efe75f2836 | |||
53f2f21f2d | |||
9c28f0a5be | |||
5bf5014b60 | |||
f37e79b611 | |||
7a0118820c | |||
c8b5c023cd | |||
f9dd929e04 | |||
87970726e4 | |||
1daf9a96a3 | |||
6c8b33fcc8 | |||
438591bd75 | |||
7ef8edccf4 | |||
074c8b876d | |||
f9762c870a | |||
4039895d3c | |||
d207a5daea | |||
8e3667c95b | |||
0da628deca | |||
04bdb13103 | |||
e8ad828498 | |||
f46473bbe8 | |||
692045d714 | |||
47cbf56725 | |||
3de14d8ba6 | |||
5fffabe05b | |||
3128ae9736 | |||
7be4e2fa81 | |||
95b305ce87 | |||
767800662c | |||
fe32e6f5d0 | |||
2cec0d9f36 | |||
d800a21bd4 | |||
8d9fbec4ce | |||
ab72c32769 | |||
346626305c | |||
fafbd500e1 | |||
2db2e8cfc4 | |||
854479180f | |||
902ba81e02 | |||
1ac17abec0 | |||
714ea54121 | |||
aa992684ba | |||
0c58de86b7 | |||
7ecac019a9 | |||
6cb88afe1a | |||
a677bcb331 | |||
2f6007342c | |||
b6c0eb8c96 | |||
afa8496767 | |||
d7be2ce439 | |||
6dcb5da069 | |||
3cf1692c96 | |||
d04af590d1 | |||
d4c43215b1 | |||
a40918aabf | |||
20f9352714 | |||
a605e90dfc | |||
9fc250956f | |||
db2dfc47a6 | |||
408a537001 | |||
922bfb33ac | |||
8e47c93fbc | |||
c175485cd8 | |||
b6981cc31d | |||
1f9cd6a99b | |||
ded7ada7d7 | |||
1b50879823 | |||
1bd9cbd4d3 | |||
96122d3be7 | |||
71d602a4cf | |||
c81bbdaaa9 | |||
2752393c42 | |||
312e064b07 | |||
94f91967f3 | |||
fe900b417e | |||
4c30b6b8a1 | |||
c41ac7b0a2 | |||
b220bd2a45 | |||
04ee94dc91 | |||
ea8f10efa4 | |||
04ecbd1a76 | |||
ddfc9d9ce1 | |||
a4735eaf76 | |||
306f492fc0 | |||
5e5f8bf33d | |||
3bb2f12cde | |||
1041bb0e6a | |||
49e93cee80 | |||
8b6681c56d | |||
9e3d432b9e | |||
841a3d5ee6 | |||
a5294d5ec7 | |||
5373e6be07 | |||
075137bd3c | |||
68da4b5b39 | |||
e4557a2e8e | |||
964bf98ca6 | |||
747f7685e7 | |||
bb82e7be50 | |||
7506f01302 | |||
a98da3bab1 | |||
f0d6128282 | |||
161e7ae7ec | |||
6104c5b5a3 | |||
af82d616c1 | |||
a0d4bff385 | |||
79236c971c | |||
20e63ae543 | |||
add7879720 | |||
1a064d38b1 | |||
294e680d5d | |||
811970e58d | |||
941961f5ef | |||
1963d8fde0 | |||
e44ed4da3b | |||
a72488d41e | |||
3930f379cf | |||
66ba327e62 | |||
329ca62465 | |||
26e47ef694 | |||
61ea149ff0 | |||
b3c3f896a3 | |||
d139e5f342 | |||
3abf36ad07 | |||
0bc9a9bdab | |||
98340522d9 | |||
6d09754ea7 | |||
a3b1d318cc | |||
f866efb622 | |||
b1c4578726 | |||
f4181a6e36 | |||
38089af098 | |||
cd135b39ad | |||
dd3207cbd8 | |||
a7abd5ff9d | |||
a3e50f6337 | |||
441a98e60a | |||
4a90ac270f | |||
a906a2988b | |||
545f68382c | |||
8249cac592 | |||
7b7bbe9105 | |||
05679c7872 | |||
8eb80be691 | |||
f55b0d0b45 | |||
754e0dbb49 | |||
525c8db779 | |||
c7f578f297 | |||
19c030281f | |||
ca9fe1b89a | |||
9fd6a695f6 | |||
c07b0ff35b | |||
00be3f0dd3 | |||
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 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@ players/*
|
|||||||
worlds/*
|
worlds/*
|
||||||
plugins/*
|
plugins/*
|
||||||
bin/*
|
bin/*
|
||||||
|
timings/*
|
||||||
*.log
|
*.log
|
||||||
*.txt
|
*.txt
|
||||||
*.phar
|
*.phar
|
||||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -9,3 +9,9 @@
|
|||||||
[submodule "src/spl"]
|
[submodule "src/spl"]
|
||||||
path = src/spl
|
path = src/spl
|
||||||
url = https://github.com/PocketMine/PocketMine-SPL.git
|
url = https://github.com/PocketMine/PocketMine-SPL.git
|
||||||
|
[submodule "tests/TesterPlugin"]
|
||||||
|
path = tests/TesterPlugin
|
||||||
|
url = https://github.com/PocketMine/TesterPlugin.git
|
||||||
|
[submodule "src/pocketmine/lang/locale"]
|
||||||
|
path = src/pocketmine/lang/locale
|
||||||
|
url = https://github.com/PocketMine/PocketMine-Language.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
|
language: php
|
||||||
|
|
||||||
php:
|
php:
|
||||||
- 5.4
|
|
||||||
- 5.5
|
|
||||||
- 5.6
|
- 5.6
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
except:
|
- master
|
||||||
- Core-Rewrite
|
|
||||||
- master
|
|
||||||
- 0.9.0
|
|
||||||
|
|
||||||
before_script:
|
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
|
- echo | pecl install channel://pecl.php.net/yaml-1.1.1
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- php src/tests/ServerSuiteTest.php --no-wizard
|
- php tests/TravisTest.php
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0
|
#webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0
|
||||||
|
@ -34,14 +34,13 @@ You must follow these guidelines if you wish to contribute to the PocketMine-MP
|
|||||||
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.
|
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, and MUST NOT have spaces before.
|
* 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)_
|
* `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.
|
* Control structure keywords or opening braces MUST NOT have one space before or after them.
|
||||||
* Code MUST use tabs for indenting.
|
* Code MUST use tabs for indenting.
|
||||||
* Long arrays MAY be split across multiple lines, where each subsequent line is indented once.
|
* Long arrays MAY be split across multiple lines, where each subsequent line is indented once.
|
||||||
* Files MUST use only the `<?php` tag.
|
* Files MUST use only the `<?php` tag.
|
||||||
* Files MUST NOT have an ending `?>` tag.
|
* Files MUST NOT have an ending `?>` tag.
|
||||||
* Code MUST use namespaces.
|
* Code MUST use namespaces.
|
||||||
* Strings SHOULD use the double quote `"` except when the single quote is required.
|
* Strings SHOULD use the double quote `"` except when the single quote is required.
|
||||||
* Argument lists MAY NOT be split across multiple lines, except long arrays.
|
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
@ -72,6 +71,19 @@ 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
|
## Bug Tracking for Collaborators
|
||||||
|
|
||||||
### Labels
|
### Labels
|
||||||
@ -91,6 +103,7 @@ Category labels are prefixed by `C:`. Multiple category labels may be applied to
|
|||||||
Pull Requests are prefixed by `PR:`. Only one label may be applied for a Pull Request.
|
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: 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: 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
|
||||||
Status labels show the status of the issue. Multiple status labels may be applied.
|
Status labels show the status of the issue. Multiple status labels may be applied.
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* ____ _ _ __ __ _ __ __ ____
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
@ -14,13 +14,14 @@
|
|||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* @author PocketMine Team
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace pocketmine;
|
namespace pocketmine;
|
||||||
|
|
||||||
|
use pocketmine\event\TranslationContainer;
|
||||||
use pocketmine\utils\TextFormat;
|
use pocketmine\utils\TextFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,10 +107,11 @@ abstract class Achievement{
|
|||||||
|
|
||||||
public static function broadcast(Player $player, $achievementId){
|
public static function broadcast(Player $player, $achievementId){
|
||||||
if(isset(Achievement::$list[$achievementId])){
|
if(isset(Achievement::$list[$achievementId])){
|
||||||
|
$translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"]]);
|
||||||
if(Server::getInstance()->getConfigString("announce-player-achievements", true) === true){
|
if(Server::getInstance()->getConfigString("announce-player-achievements", true) === true){
|
||||||
Server::getInstance()->broadcastMessage($player->getDisplayName() . " has just earned the achievement " . TextFormat::GREEN . Achievement::$list[$achievementId]["name"]);
|
Server::getInstance()->broadcastMessage($translation);
|
||||||
}else{
|
}else{
|
||||||
$player->sendMessage("You have just earned the achievement " . TextFormat::GREEN . Achievement::$list[$achievementId]["name"]);
|
$player->sendMessage($translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* @author PocketMine Team
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -22,6 +22,7 @@
|
|||||||
namespace pocketmine;
|
namespace pocketmine;
|
||||||
|
|
||||||
use pocketmine\network\protocol\Info;
|
use pocketmine\network\protocol\Info;
|
||||||
|
use pocketmine\plugin\PluginBase;
|
||||||
use pocketmine\plugin\PluginLoadOrder;
|
use pocketmine\plugin\PluginLoadOrder;
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
use pocketmine\utils\VersionString;
|
use pocketmine\utils\VersionString;
|
||||||
@ -41,7 +42,10 @@ class CrashDump{
|
|||||||
$this->time = time();
|
$this->time = time();
|
||||||
$this->server = $server;
|
$this->server = $server;
|
||||||
$this->path = $this->server->getDataPath() . "CrashDump_" . date("D_M_j-H.i.s-T_Y", $this->time) . ".log";
|
$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->fp = @fopen($this->path, "wb");
|
||||||
|
if(!is_resource($this->fp)){
|
||||||
|
throw new \RuntimeException("Could not create Crash Dump");
|
||||||
|
}
|
||||||
$this->data["time"] = $this->time;
|
$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->server->getName() . " Crash Dump " . date("D M j H:i:s T Y", $this->time));
|
||||||
$this->addLine();
|
$this->addLine();
|
||||||
@ -136,7 +140,7 @@ class CrashDump{
|
|||||||
$error = $lastExceptionError;
|
$error = $lastExceptionError;
|
||||||
}else{
|
}else{
|
||||||
$error = (array) error_get_last();
|
$error = (array) error_get_last();
|
||||||
$error["trace"] = getTrace(4);
|
$error["trace"] = @getTrace(3);
|
||||||
$errorConversion = [
|
$errorConversion = [
|
||||||
E_ERROR => "E_ERROR",
|
E_ERROR => "E_ERROR",
|
||||||
E_WARNING => "E_WARNING",
|
E_WARNING => "E_WARNING",
|
||||||
@ -179,7 +183,7 @@ class CrashDump{
|
|||||||
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
||||||
$this->data["plugin"] = true;
|
$this->data["plugin"] = true;
|
||||||
|
|
||||||
$reflection = new \ReflectionClass("pocketmine\\plugin\\PluginBase");
|
$reflection = new \ReflectionClass(PluginBase::class);
|
||||||
$file = $reflection->getProperty("file");
|
$file = $reflection->getProperty("file");
|
||||||
$file->setAccessible(true);
|
$file->setAccessible(true);
|
||||||
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
|
||||||
@ -228,7 +232,7 @@ class CrashDump{
|
|||||||
$this->data["general"]["zend"] = zend_version();
|
$this->data["general"]["zend"] = zend_version();
|
||||||
$this->data["general"]["php_os"] = PHP_OS;
|
$this->data["general"]["php_os"] = PHP_OS;
|
||||||
$this->data["general"]["os"] = Utils::getOS();
|
$this->data["general"]["os"] = Utils::getOS();
|
||||||
$this->addLine("PocketMine-MP version: " . $version->get(false) . " #" . $version->getNumber() . " [Protocol " . Info::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
$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("Git commit: " . GIT_COMMIT);
|
||||||
$this->addLine("uname -a: " . php_uname("a"));
|
$this->addLine("uname -a: " . php_uname("a"));
|
||||||
$this->addLine("PHP Version: " . phpversion());
|
$this->addLine("PHP Version: " . phpversion());
|
||||||
|
422
src/pocketmine/MemoryManager.php
Normal file
422
src/pocketmine/MemoryManager.php
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
<?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;
|
||||||
|
|
||||||
|
use pocketmine\event\server\LowMemoryEvent;
|
||||||
|
use pocketmine\event\Timings;
|
||||||
|
use pocketmine\scheduler\GarbageCollectionTask;
|
||||||
|
use pocketmine\utils\Utils;
|
||||||
|
use pocketmine\utils\UUID;
|
||||||
|
|
||||||
|
class MemoryManager{
|
||||||
|
|
||||||
|
/** @var Server */
|
||||||
|
private $server;
|
||||||
|
|
||||||
|
private $memoryLimit;
|
||||||
|
private $globalMemoryLimit;
|
||||||
|
private $checkRate;
|
||||||
|
private $checkTicker = 0;
|
||||||
|
private $lowMemory = false;
|
||||||
|
|
||||||
|
private $continuousTrigger = true;
|
||||||
|
private $continuousTriggerRate;
|
||||||
|
private $continuousTriggerCount = 0;
|
||||||
|
private $continuousTriggerTicker = 0;
|
||||||
|
|
||||||
|
private $garbageCollectionPeriod;
|
||||||
|
private $garbageCollectionTicker = 0;
|
||||||
|
private $garbageCollectionTrigger;
|
||||||
|
private $garbageCollectionAsync;
|
||||||
|
|
||||||
|
private $chunkLimit;
|
||||||
|
private $chunkCollect;
|
||||||
|
private $chunkTrigger;
|
||||||
|
|
||||||
|
private $chunkCache;
|
||||||
|
private $cacheTrigger;
|
||||||
|
|
||||||
|
/** @var \WeakRef[] */
|
||||||
|
private $leakWatch = [];
|
||||||
|
|
||||||
|
private $leakInfo = [];
|
||||||
|
|
||||||
|
private $leakSeed = 0;
|
||||||
|
|
||||||
|
public function __construct(Server $server){
|
||||||
|
$this->server = $server;
|
||||||
|
|
||||||
|
$this->init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function init(){
|
||||||
|
$this->memoryLimit = ((int) $this->server->getProperty("memory.main-limit", 0)) * 1024 * 1024;
|
||||||
|
|
||||||
|
$defaultMemory = 1024;
|
||||||
|
|
||||||
|
if(preg_match("/([0-9]+)([KMGkmg])/", $this->server->getConfigString("memory-limit", ""), $matches) > 0){
|
||||||
|
$m = (int) $matches[1];
|
||||||
|
if($m <= 0){
|
||||||
|
$defaultMemory = 0;
|
||||||
|
}else{
|
||||||
|
switch(strtoupper($matches[2])){
|
||||||
|
case "K":
|
||||||
|
$defaultMemory = $m / 1024;
|
||||||
|
break;
|
||||||
|
case "M":
|
||||||
|
$defaultMemory = $m;
|
||||||
|
break;
|
||||||
|
case "G":
|
||||||
|
$defaultMemory = $m * 1024;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$defaultMemory = $m;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$hardLimit = ((int) $this->server->getProperty("memory.main-hard-limit", $defaultMemory));
|
||||||
|
|
||||||
|
if($hardLimit <= 0){
|
||||||
|
ini_set("memory_limit", -1);
|
||||||
|
}else{
|
||||||
|
ini_set("memory_limit", $hardLimit . "M");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->globalMemoryLimit = ((int) $this->server->getProperty("memory.global-limit", 0)) * 1024 * 1024;
|
||||||
|
$this->checkRate = (int) $this->server->getProperty("memory.check-rate", 20);
|
||||||
|
$this->continuousTrigger = (bool) $this->server->getProperty("memory.continuous-trigger", true);
|
||||||
|
$this->continuousTriggerRate = (int) $this->server->getProperty("memory.continuous-trigger-rate", 30);
|
||||||
|
|
||||||
|
$this->garbageCollectionPeriod = (int) $this->server->getProperty("memory.garbage-collection.period", 36000);
|
||||||
|
$this->garbageCollectionTrigger = (bool) $this->server->getProperty("memory.garbage-collection.low-memory-trigger", true);
|
||||||
|
$this->garbageCollectionAsync = (bool) $this->server->getProperty("memory.garbage-collection.collect-async-worker", true);
|
||||||
|
|
||||||
|
$this->chunkLimit = (int) $this->server->getProperty("memory.max-chunks.trigger-limit", 96);
|
||||||
|
$this->chunkCollect = (bool) $this->server->getProperty("memory.max-chunks.trigger-chunk-collect", true);
|
||||||
|
$this->chunkTrigger = (bool) $this->server->getProperty("memory.max-chunks.low-memory-trigger", true);
|
||||||
|
|
||||||
|
$this->chunkCache = (bool) $this->server->getProperty("memory.world-caches.disable-chunk-cache", true);
|
||||||
|
$this->cacheTrigger = (bool) $this->server->getProperty("memory.world-caches.low-memory-trigger", true);
|
||||||
|
|
||||||
|
gc_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isLowMemory(){
|
||||||
|
return $this->lowMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canUseChunkCache(){
|
||||||
|
return !($this->lowMemory and $this->chunkTrigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getViewDistance($distance){
|
||||||
|
return $this->lowMemory ? min($this->chunkLimit, $distance) : $distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function trigger($memory, $limit, $global = false, $triggerCount = 0){
|
||||||
|
$this->server->getLogger()->debug("[Memory Manager] ".($global ? "Global " : "") ."Low memory triggered, limit ". round(($limit / 1024) / 1024, 2)."MB, using ". round(($memory / 1024) / 1024, 2)."MB");
|
||||||
|
|
||||||
|
if($this->cacheTrigger){
|
||||||
|
foreach($this->server->getLevels() as $level){
|
||||||
|
$level->clearCache(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->chunkTrigger and $this->chunkCollect){
|
||||||
|
foreach($this->server->getLevels() as $level){
|
||||||
|
$level->doChunkGarbageCollection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$ev = new LowMemoryEvent($memory, $limit, $global, $triggerCount);
|
||||||
|
$this->server->getPluginManager()->callEvent($ev);
|
||||||
|
|
||||||
|
$cycles = 0;
|
||||||
|
if($this->garbageCollectionTrigger){
|
||||||
|
$cycles = $this->triggerGarbageCollector();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->server->getLogger()->debug("[Memory Manager] Freed " . round(($ev->getMemoryFreed() / 1024) / 1024, 2)."MB, $cycles cycles");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function check(){
|
||||||
|
Timings::$memoryManagerTimer->startTiming();
|
||||||
|
|
||||||
|
if(($this->memoryLimit > 0 or $this->globalMemoryLimit > 0) and ++$this->checkTicker >= $this->checkRate){
|
||||||
|
$this->checkTicker = 0;
|
||||||
|
$memory = Utils::getMemoryUsage(true);
|
||||||
|
$trigger = false;
|
||||||
|
if($this->memoryLimit > 0 and $memory[0] > $this->memoryLimit){
|
||||||
|
$trigger = 0;
|
||||||
|
}elseif($this->globalMemoryLimit > 0 and $memory[1] > $this->globalMemoryLimit){
|
||||||
|
$trigger = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($trigger !== false){
|
||||||
|
if($this->lowMemory and $this->continuousTrigger){
|
||||||
|
if(++$this->continuousTriggerTicker >= $this->continuousTriggerRate){
|
||||||
|
$this->continuousTriggerTicker = 0;
|
||||||
|
$this->trigger($memory[$trigger], $this->memoryLimit, $trigger > 0, ++$this->continuousTriggerCount);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$this->lowMemory = true;
|
||||||
|
$this->continuousTriggerCount = 0;
|
||||||
|
$this->trigger($memory[$trigger], $this->memoryLimit, $trigger > 0);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$this->lowMemory = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->garbageCollectionPeriod > 0 and ++$this->garbageCollectionTicker >= $this->garbageCollectionPeriod){
|
||||||
|
$this->garbageCollectionTicker = 0;
|
||||||
|
$this->triggerGarbageCollector();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timings::$memoryManagerTimer->stopTiming();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function triggerGarbageCollector(){
|
||||||
|
Timings::$garbageCollectorTimer->startTiming();
|
||||||
|
|
||||||
|
if($this->garbageCollectionAsync){
|
||||||
|
$size = $this->server->getScheduler()->getAsyncTaskPoolSize();
|
||||||
|
for($i = 0; $i < $size; ++$i){
|
||||||
|
$this->server->getScheduler()->scheduleAsyncTaskToWorker(new GarbageCollectionTask(), $i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$cycles = gc_collect_cycles();
|
||||||
|
|
||||||
|
Timings::$garbageCollectorTimer->stopTiming();
|
||||||
|
|
||||||
|
return $cycles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param object $object
|
||||||
|
*
|
||||||
|
* @return string Object identifier for future checks
|
||||||
|
*/
|
||||||
|
public function addObjectWatcher($object){
|
||||||
|
if(!is_object($object)){
|
||||||
|
throw new \InvalidArgumentException("Not an object!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$identifier = spl_object_hash($object) . ":" . get_class($object);
|
||||||
|
|
||||||
|
if(isset($this->leakInfo[$identifier])){
|
||||||
|
return $this->leakInfo["id"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->leakInfo[$identifier] = [
|
||||||
|
"id" => $id = md5($identifier . ":" . $this->leakSeed++),
|
||||||
|
"class" => get_class($object),
|
||||||
|
"hash" => $identifier
|
||||||
|
];
|
||||||
|
$this->leakInfo[$id] = $this->leakInfo[$identifier];
|
||||||
|
|
||||||
|
$this->leakWatch[$id] = new \WeakRef($object);
|
||||||
|
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isObjectAlive($id){
|
||||||
|
if(isset($this->leakWatch[$id])){
|
||||||
|
return $this->leakWatch[$id]->valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeObjectWatch($id){
|
||||||
|
if(!isset($this->leakWatch[$id])){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unset($this->leakInfo[$this->leakInfo[$id]["hash"]]);
|
||||||
|
unset($this->leakInfo[$id]);
|
||||||
|
unset($this->leakWatch[$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doObjectCleanup(){
|
||||||
|
foreach($this->leakWatch as $id => $w){
|
||||||
|
if(!$w->valid()){
|
||||||
|
$this->removeObjectWatch($id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getObjectInformation($id, $includeObject = false){
|
||||||
|
if(!isset($this->leakWatch[$id])){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$valid = false;
|
||||||
|
$references = 0;
|
||||||
|
$object = null;
|
||||||
|
|
||||||
|
if($this->leakWatch[$id]->acquire()){
|
||||||
|
$object = $this->leakWatch[$id]->get();
|
||||||
|
$this->leakWatch[$id]->release();
|
||||||
|
|
||||||
|
$valid = true;
|
||||||
|
$references = getReferenceCount($object, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
"id" => $id,
|
||||||
|
"class" => $this->leakInfo[$id]["class"],
|
||||||
|
"hash" => $this->leakInfo[$id]["hash"],
|
||||||
|
"valid" => $valid,
|
||||||
|
"references" => $references,
|
||||||
|
"object" => $includeObject ? $object : null
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dumpServerMemory($outputFolder, $maxNesting, $maxStringSize){
|
||||||
|
gc_disable();
|
||||||
|
|
||||||
|
if(!file_exists($outputFolder)){
|
||||||
|
mkdir($outputFolder, 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->server->getLogger()->notice("[Dump] After the memory dump is done, the server might crash");
|
||||||
|
|
||||||
|
$obData = fopen($outputFolder . "/objects.js", "wb+");
|
||||||
|
|
||||||
|
$staticProperties = [];
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
|
||||||
|
$objects = [];
|
||||||
|
|
||||||
|
$refCounts = [];
|
||||||
|
|
||||||
|
$this->continueDump($this->server, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||||
|
|
||||||
|
do{
|
||||||
|
$continue = false;
|
||||||
|
foreach($objects as $hash => $object){
|
||||||
|
if(!is_object($object)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$continue = true;
|
||||||
|
|
||||||
|
$className = get_class($object);
|
||||||
|
|
||||||
|
$objects[$hash] = true;
|
||||||
|
|
||||||
|
$reflection = new \ReflectionObject($object);
|
||||||
|
|
||||||
|
$info = [
|
||||||
|
"information" => "$hash@$className",
|
||||||
|
"properties" => []
|
||||||
|
];
|
||||||
|
|
||||||
|
if($reflection->getParentClass()){
|
||||||
|
$info["parent"] = $reflection->getParentClass()->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count($reflection->getInterfaceNames()) > 0){
|
||||||
|
$info["implements"] = implode(", ", $reflection->getInterfaceNames());
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($reflection->getProperties() as $property){
|
||||||
|
if($property->isStatic()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$property->isPublic()){
|
||||||
|
$property->setAccessible(true);
|
||||||
|
}
|
||||||
|
$this->continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite($obData, "$hash@$className: ". json_encode($info, JSON_UNESCAPED_SLASHES) . "\n");
|
||||||
|
|
||||||
|
if(!isset($objects["staticProperties"][$className])){
|
||||||
|
$staticProperties[$className] = [];
|
||||||
|
foreach($reflection->getProperties() as $property){
|
||||||
|
if(!$property->isStatic() or $property->getDeclaringClass()->getName() !== $className){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$property->isPublic()){
|
||||||
|
$property->setAccessible(true);
|
||||||
|
}
|
||||||
|
$this->continueDump($property->getValue($object), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "[Dump] Wrote " . count($objects) . " objects\n";
|
||||||
|
}while($continue);
|
||||||
|
|
||||||
|
file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||||
|
file_put_contents($outputFolder . "/serverEntry.js", json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||||
|
file_put_contents($outputFolder . "/referenceCounts.js", json_encode($refCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||||
|
|
||||||
|
echo "[Dump] Finished!\n";
|
||||||
|
|
||||||
|
gc_enable();
|
||||||
|
|
||||||
|
$this->server->forceShutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function continueDump($from, &$data, &$objects, &$refCounts, $recursion, $maxNesting, $maxStringSize){
|
||||||
|
if($maxNesting <= 0){
|
||||||
|
$data = "(error) NESTING LIMIT REACHED";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
--$maxNesting;
|
||||||
|
|
||||||
|
if(is_object($from)){
|
||||||
|
if(!isset($objects[$hash = spl_object_hash($from)])){
|
||||||
|
$objects[$hash] = $from;
|
||||||
|
$refCounts[$hash] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
++$refCounts[$hash];
|
||||||
|
|
||||||
|
$data = "(object) $hash@" . get_class($from);
|
||||||
|
}elseif(is_array($from)){
|
||||||
|
if($recursion >= 5){
|
||||||
|
$data = "(error) ARRAY RECURSION LIMIT REACHED";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$data = [];
|
||||||
|
foreach($from as $key => $value){
|
||||||
|
$this->continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize);
|
||||||
|
}
|
||||||
|
}elseif(is_string($from)){
|
||||||
|
$data = "(string) len(".strlen($from).") " . substr(Utils::printable($from), 0, $maxStringSize);
|
||||||
|
}elseif(is_resource($from)){
|
||||||
|
$data = "(resource) " . print_r($from, true);
|
||||||
|
}else{
|
||||||
|
$data = $from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
echo str_repeat(" ", $cnt) . "}" . PHP_EOL;
|
echo str_repeat(" ", $cnt) . "}" . PHP_EOL;
|
||||||
break;
|
break;
|
||||||
case is_integer($var):
|
case is_int($var):
|
||||||
echo str_repeat(" ", $cnt) . "int(" . $var . ")" . PHP_EOL;
|
echo str_repeat(" ", $cnt) . "int(" . $var . ")" . PHP_EOL;
|
||||||
break;
|
break;
|
||||||
case is_float($var):
|
case is_float($var):
|
||||||
@ -65,17 +65,25 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace pocketmine {
|
namespace pocketmine {
|
||||||
use LogLevel;
|
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
use pocketmine\utils\MainLogger;
|
use pocketmine\utils\MainLogger;
|
||||||
|
use pocketmine\utils\ServerKiller;
|
||||||
|
use pocketmine\utils\Terminal;
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
use pocketmine\wizard\Installer;
|
use pocketmine\wizard\Installer;
|
||||||
use raklib\RakLib;
|
|
||||||
|
|
||||||
const VERSION = "Alpha_1.4dev";
|
const VERSION = "1.5dev";
|
||||||
const API_VERSION = "1.3.1";
|
const API_VERSION = "1.12.0";
|
||||||
const CODENAME = "絶好(Zekkou)ケーキ(Cake)";
|
const CODENAME = "活発(Kappatsu)フグ(Fugu)";
|
||||||
const MINECRAFT_VERSION = "v0.9.5 alpha";
|
const MINECRAFT_VERSION = "v0.11.0 alpha";
|
||||||
|
const MINECRAFT_VERSION_NETWORK = "0.11.0";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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) !== ""){
|
if(\Phar::running(true) !== ""){
|
||||||
@define("pocketmine\\PATH", \Phar::running(true) . "/");
|
@define("pocketmine\\PATH", \Phar::running(true) . "/");
|
||||||
@ -90,6 +98,7 @@ namespace pocketmine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!class_exists("ClassLoader", false)){
|
if(!class_exists("ClassLoader", false)){
|
||||||
|
require_once(\pocketmine\PATH . "src/spl/ThreadedFactory.php");
|
||||||
require_once(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
require_once(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||||
require_once(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
require_once(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||||
require_once(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
|
require_once(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
|
||||||
@ -99,45 +108,10 @@ namespace pocketmine {
|
|||||||
$autoloader->addPath(\pocketmine\PATH . "src");
|
$autoloader->addPath(\pocketmine\PATH . "src");
|
||||||
$autoloader->addPath(\pocketmine\PATH . "src" . DIRECTORY_SEPARATOR . "spl");
|
$autoloader->addPath(\pocketmine\PATH . "src" . DIRECTORY_SEPARATOR . "spl");
|
||||||
$autoloader->register(true);
|
$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?!?!
|
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_enable();
|
gc_enable();
|
||||||
error_reporting(-1);
|
error_reporting(-1);
|
||||||
ini_set("allow_url_fopen", 1);
|
ini_set("allow_url_fopen", 1);
|
||||||
@ -145,18 +119,182 @@ namespace pocketmine {
|
|||||||
ini_set("display_startup_errors", 1);
|
ini_set("display_startup_errors", 1);
|
||||||
ini_set("default_charset", "utf-8");
|
ini_set("default_charset", "utf-8");
|
||||||
|
|
||||||
ini_set("memory_limit", "256M"); //Default
|
ini_set("memory_limit", -1);
|
||||||
define("pocketmine\\START_TIME", microtime(true));
|
define("pocketmine\\START_TIME", microtime(true));
|
||||||
|
|
||||||
$opts = getopt("", ["enable-ansi", "disable-ansi", "data:", "plugins:", "no-wizard", "enable-profiler"]);
|
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-profiler"]);
|
||||||
|
|
||||||
define("pocketmine\\DATA", isset($opts["data"]) ? realpath($opts["data"]) . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
|
define("pocketmine\\DATA", isset($opts["data"]) ? $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\\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"])));
|
Terminal::init();
|
||||||
|
|
||||||
|
define("pocketmine\\ANSI", Terminal::hasFormattingCodes());
|
||||||
|
|
||||||
|
if(!file_exists(\pocketmine\DATA)){
|
||||||
|
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);
|
$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(isset($opts["enable-profiler"])){
|
||||||
if(function_exists("profiler_enable")){
|
if(function_exists("profiler_enable")){
|
||||||
\profiler_enable();
|
\profiler_enable();
|
||||||
@ -178,6 +316,24 @@ namespace pocketmine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param object $value
|
||||||
|
* @param bool $includeCurrent
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
function getReferenceCount($value, $includeCurrent = true){
|
||||||
|
ob_start();
|
||||||
|
debug_zval_dump($value);
|
||||||
|
$ret = explode("\n", ob_get_contents());
|
||||||
|
ob_end_clean();
|
||||||
|
|
||||||
|
if(count($ret) >= 1 and preg_match('/^.* refcount\\(([0-9]+)\\)\\{$/', trim($ret[0]), $m) > 0){
|
||||||
|
return ((int) $m[1]) - ($includeCurrent ? 3 : 4); //$value + zval call + extra call
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
function getTrace($start = 1, $trace = null){
|
function getTrace($start = 1, $trace = null){
|
||||||
if($trace === null){
|
if($trace === null){
|
||||||
if(function_exists("xdebug_get_function_stack")){
|
if(function_exists("xdebug_get_function_stack")){
|
||||||
@ -199,10 +355,10 @@ namespace pocketmine {
|
|||||||
$args = $trace[$i]["params"];
|
$args = $trace[$i]["params"];
|
||||||
}
|
}
|
||||||
foreach($args as $name => $value){
|
foreach($args as $name => $value){
|
||||||
$params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . @strval($value)) . ", ";
|
$params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value)))) . ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$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) . ")";
|
$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"] . "(" . Utils::printable(substr($params, 0, -2)) . ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $messages;
|
return $messages;
|
||||||
@ -212,54 +368,7 @@ namespace pocketmine {
|
|||||||
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
|
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
function error_handler($errno, $errstr, $errfile, $errline, $trace = null){
|
set_error_handler([\ExceptionHandler::class, "handler"], -1);
|
||||||
global $lastError;
|
|
||||||
if(error_reporting() === 0){ //@ error-control
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$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",
|
|
||||||
];
|
|
||||||
$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;
|
|
||||||
if(($pos = strpos($errstr, "\n")) !== false){
|
|
||||||
$errstr = substr($errstr, 0, $pos);
|
|
||||||
}
|
|
||||||
$logger = MainLogger::getLogger();
|
|
||||||
$oldFile = $errfile;
|
|
||||||
$errfile = cleanPath($errfile);
|
|
||||||
$logger->log($type, "An $errno error happened: \"$errstr\" in \"$errfile\" at line $errline");
|
|
||||||
|
|
||||||
foreach(($trace = getTrace($trace === null ? 3 : 0, $trace)) as $i => $line){
|
|
||||||
$logger->debug($line);
|
|
||||||
}
|
|
||||||
$lastError = [
|
|
||||||
"type" => $type,
|
|
||||||
"message" => $errstr,
|
|
||||||
"fullFile" => $oldFile,
|
|
||||||
"file" => $errfile,
|
|
||||||
"line" => $errline,
|
|
||||||
"trace" => $trace
|
|
||||||
];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_error_handler("\\pocketmine\\error_handler", E_ALL);
|
|
||||||
|
|
||||||
$errors = 0;
|
$errors = 0;
|
||||||
|
|
||||||
@ -282,8 +391,8 @@ namespace pocketmine {
|
|||||||
if(substr_count($pthreads_version, ".") < 2){
|
if(substr_count($pthreads_version, ".") < 2){
|
||||||
$pthreads_version = "0.$pthreads_version";
|
$pthreads_version = "0.$pthreads_version";
|
||||||
}
|
}
|
||||||
if(version_compare($pthreads_version, "2.0.4") < 0){
|
if(version_compare($pthreads_version, "2.0.9") < 0){
|
||||||
$logger->critical("pthreads >= 2.0.4 is required, while you have $pthreads_version.");
|
$logger->critical("pthreads >= 2.0.9 is required, while you have $pthreads_version.");
|
||||||
++$errors;
|
++$errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +456,7 @@ namespace pocketmine {
|
|||||||
new Installer();
|
new Installer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(substr(__FILE__, 0, 7) !== "phar://"){
|
if(\Phar::running(true) === ""){
|
||||||
$logger->warning("Non-packaged PocketMine-MP installation detected, do not use on production.");
|
$logger->warning("Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,30 +466,19 @@ namespace pocketmine {
|
|||||||
$logger->info("Stopping other threads");
|
$logger->info("Stopping other threads");
|
||||||
|
|
||||||
foreach(ThreadManager::getInstance()->getAll() as $id => $thread){
|
foreach(ThreadManager::getInstance()->getAll() as $id => $thread){
|
||||||
if($thread->isRunning()){
|
$logger->debug("Stopping " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
||||||
$logger->debug("Stopping " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
$thread->quit();
|
||||||
if($thread instanceof Thread){
|
|
||||||
$thread->kill();
|
|
||||||
|
|
||||||
if($thread->isRunning() or !$thread->join()){
|
|
||||||
$thread->detach();
|
|
||||||
}
|
|
||||||
}elseif($thread instanceof Worker){
|
|
||||||
$thread->kill();
|
|
||||||
sleep(1);
|
|
||||||
if($thread->isRunning() or !$thread->join()){
|
|
||||||
$thread->detach();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}elseif(!$thread->isJoined()){
|
|
||||||
$logger->debug("Joining " . (new \ReflectionClass($thread))->getShortName() . " thread");
|
|
||||||
$thread->join();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$killer = new ServerKiller(8);
|
||||||
|
$killer->start();
|
||||||
|
$killer->detach();
|
||||||
|
|
||||||
$logger->shutdown();
|
$logger->shutdown();
|
||||||
$logger->join();
|
$logger->join();
|
||||||
|
|
||||||
|
echo Terminal::$FORMAT_RESET . "\n";
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -26,9 +26,66 @@ namespace pocketmine;
|
|||||||
*/
|
*/
|
||||||
abstract class Thread extends \Thread{
|
abstract class Thread extends \Thread{
|
||||||
|
|
||||||
public final function start($options = PTHREADS_INHERIT_ALL){
|
/** @var \ClassLoader */
|
||||||
|
protected $classLoader;
|
||||||
|
|
||||||
|
public function getClassLoader(){
|
||||||
|
return $this->classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setClassLoader(\ClassLoader $loader = null){
|
||||||
|
if($loader === null){
|
||||||
|
$loader = Server::getInstance()->getLoader();
|
||||||
|
}
|
||||||
|
$this->classLoader = $loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerClassLoader(){
|
||||||
|
if(!interface_exists("ClassLoader", false)){
|
||||||
|
require(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||||
|
require(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||||
|
require(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
|
||||||
|
}
|
||||||
|
if($this->classLoader !== null){
|
||||||
|
$this->classLoader->register(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function start($options = PTHREADS_INHERIT_ALL){
|
||||||
ThreadManager::getInstance()->add($this);
|
ThreadManager::getInstance()->add($this);
|
||||||
|
|
||||||
return parent::start($options & ~PTHREADS_INHERIT_CLASSES);
|
if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){
|
||||||
|
if($this->getClassLoader() === null){
|
||||||
|
$this->setClassLoader();
|
||||||
|
}
|
||||||
|
return parent::start($options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the thread using the best way possible. Try to stop it yourself before calling this.
|
||||||
|
*/
|
||||||
|
public function quit(){
|
||||||
|
if($this->isRunning()){
|
||||||
|
$this->kill();
|
||||||
|
$this->detach();
|
||||||
|
}elseif(!$this->isJoined()){
|
||||||
|
if(!$this->isTerminated()){
|
||||||
|
$this->join();
|
||||||
|
}else{
|
||||||
|
$this->kill();
|
||||||
|
$this->detach();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$this->detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadManager::getInstance()->remove($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThreadName(){
|
||||||
|
return (new \ReflectionClass($this))->getShortName();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,9 +26,67 @@ namespace pocketmine;
|
|||||||
*/
|
*/
|
||||||
abstract class Worker extends \Worker{
|
abstract class Worker extends \Worker{
|
||||||
|
|
||||||
public final function start($options = PTHREADS_INHERIT_ALL){
|
/** @var \ClassLoader */
|
||||||
|
protected $classLoader;
|
||||||
|
|
||||||
|
public function getClassLoader(){
|
||||||
|
return $this->classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setClassLoader(\ClassLoader $loader = null){
|
||||||
|
if($loader === null){
|
||||||
|
$loader = Server::getInstance()->getLoader();
|
||||||
|
}
|
||||||
|
$this->classLoader = $loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function registerClassLoader(){
|
||||||
|
if(!interface_exists("ClassLoader", false)){
|
||||||
|
require(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||||
|
require(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||||
|
require(\pocketmine\PATH . "src/pocketmine/CompatibleClassLoader.php");
|
||||||
|
}
|
||||||
|
if($this->classLoader !== null){
|
||||||
|
$this->classLoader->register(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function start($options = PTHREADS_INHERIT_ALL){
|
||||||
ThreadManager::getInstance()->add($this);
|
ThreadManager::getInstance()->add($this);
|
||||||
|
|
||||||
return parent::start($options & ~PTHREADS_INHERIT_CLASSES);
|
if(!$this->isRunning() and !$this->isJoined() and !$this->isTerminated()){
|
||||||
|
if($this->getClassLoader() === null){
|
||||||
|
$this->setClassLoader();
|
||||||
|
}
|
||||||
|
return parent::start($options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the thread using the best way possible. Try to stop it yourself before calling this.
|
||||||
|
*/
|
||||||
|
public function quit(){
|
||||||
|
if($this->isRunning()){
|
||||||
|
$this->unstack();
|
||||||
|
$this->kill();
|
||||||
|
$this->detach();
|
||||||
|
}elseif(!$this->isJoined()){
|
||||||
|
if(!$this->isTerminated()){
|
||||||
|
$this->join();
|
||||||
|
}else{
|
||||||
|
$this->kill();
|
||||||
|
$this->detach();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$this->detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadManager::getInstance()->remove($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThreadName(){
|
||||||
|
return (new \ReflectionClass($this))->getShortName();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -22,10 +22,18 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class AcaciaWoodStairs extends Stair{
|
class AcaciaWoodStairs extends Stair{
|
||||||
|
|
||||||
|
protected $id = self::ACACIA_WOOD_STAIRS;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::ACACIA_WOOD_STAIRS, $meta, "Acacia Wood Stairs");
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Acacia Wood Stairs";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
@ -33,4 +41,16 @@ class AcaciaWoodStairs extends Stair{
|
|||||||
[$this->id, 0, 1],
|
[$this->id, 0, 1],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResistance(){
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
|
}
|
||||||
}
|
}
|
@ -21,31 +21,59 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\item\Item;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Air block
|
* Air block
|
||||||
*/
|
*/
|
||||||
class Air extends Transparent{
|
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 $id = self::AIR;
|
||||||
protected $meta = 0;
|
protected $meta = 0;
|
||||||
protected $name = "Air";
|
|
||||||
protected $hardness = 0;
|
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Air";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canPassThrough(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBreakable(Item $item){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeFlowedInto(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeReplaced(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBePlaced(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSolid(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function getBoundingBox(){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResistance(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -23,15 +23,39 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\network\protocol\ChatPacket;
|
use pocketmine\math\AxisAlignedBB;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\utils\TextFormat;
|
||||||
|
|
||||||
class Bed extends Transparent{
|
class Bed extends Transparent{
|
||||||
public function __construct($type = 0){
|
|
||||||
parent::__construct(self::BED_BLOCK, $type, "Bed Block");
|
protected $id = self::BED_BLOCK;
|
||||||
$this->isActivable = true;
|
|
||||||
$this->isFullBlock = false;
|
public function __construct($meta = 0){
|
||||||
$this->hardness = 1;
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeActivated(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Bed Block";
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
public function onActivate(Item $item, Player $player = null){
|
||||||
@ -41,10 +65,7 @@ class Bed extends Transparent{
|
|||||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||||
|
|
||||||
if($player instanceof Player and !$isNight){
|
if($player instanceof Player and !$isNight){
|
||||||
$pk = new ChatPacket;
|
$player->sendMessage(TextFormat::GRAY . "You can only sleep at night");
|
||||||
$pk->message = "You can only sleep at night";
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,19 +76,17 @@ class Bed extends Transparent{
|
|||||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||||
$b = $this;
|
$b = $this;
|
||||||
}else{ //Bottom Part of Bed
|
}else{ //Bottom Part of Bed
|
||||||
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||||
$b = $blockNorth;
|
$b = $blockNorth;
|
||||||
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||||
$b = $blockSouth;
|
$b = $blockSouth;
|
||||||
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||||
$b = $blockEast;
|
$b = $blockEast;
|
||||||
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||||
$b = $blockWest;
|
$b = $blockWest;
|
||||||
}else{
|
}else{
|
||||||
if($player instanceof Player){
|
if($player instanceof Player){
|
||||||
$pk = new ChatPacket;
|
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||||
$pk->message = "This bed is incomplete";
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -75,9 +94,7 @@ class Bed extends Transparent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($player instanceof Player and $player->sleepOn($b) === false){
|
if($player instanceof Player and $player->sleepOn($b) === false){
|
||||||
$pk = new ChatPacket;
|
$player->sendMessage(TextFormat::GRAY . "This bed is occupied");
|
||||||
$pk->message = "This bed is occupied";
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -85,7 +102,7 @@ class Bed extends Transparent{
|
|||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->isTransparent === false){
|
if($down->isTransparent() === false){
|
||||||
$faces = [
|
$faces = [
|
||||||
0 => 3,
|
0 => 3,
|
||||||
1 => 4,
|
1 => 4,
|
||||||
@ -95,10 +112,10 @@ class Bed extends Transparent{
|
|||||||
$d = $player instanceof Player ? $player->getDirection() : 0;
|
$d = $player instanceof Player ? $player->getDirection() : 0;
|
||||||
$next = $this->getSide($faces[(($d + 3) % 4)]);
|
$next = $this->getSide($faces[(($d + 3) % 4)]);
|
||||||
$downNext = $this->getSide(0);
|
$downNext = $this->getSide(0);
|
||||||
if($next->isReplaceable === true and $downNext->isTransparent === false){
|
if($next->canBeReplaced() === true and $downNext->isTransparent() === false){
|
||||||
$meta = (($d + 3) % 4) & 0x03;
|
$meta = (($d + 3) % 4) & 0x03;
|
||||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), 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, false, true);
|
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | 0x08), true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -114,27 +131,27 @@ class Bed extends Transparent{
|
|||||||
$blockWest = $this->getSide(4);
|
$blockWest = $this->getSide(4);
|
||||||
|
|
||||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
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
|
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){
|
}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){
|
}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){
|
}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
|
}else{ //Bottom Part of Bed
|
||||||
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
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){
|
}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){
|
}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){
|
}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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,23 @@ namespace pocketmine\block;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
|
||||||
class Bedrock extends Solid{
|
class Bedrock extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::BEDROCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::BEDROCK, 0, "Bedrock");
|
|
||||||
$this->breakable = false;
|
}
|
||||||
$this->hardness = 18000000;
|
|
||||||
|
public function getName(){
|
||||||
|
return "Bedrock";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResistance(){
|
||||||
|
return 18000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isBreakable(Item $item){
|
public function isBreakable(Item $item){
|
||||||
|
@ -22,65 +22,17 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\Player;
|
|
||||||
|
|
||||||
class Beetroot extends Flowable{
|
class Beetroot extends Crops{
|
||||||
|
|
||||||
|
protected $id = self::BEETROOT_BLOCK;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::BEETROOT_BLOCK, $meta, "Beetroot Block");
|
$this->meta = $meta;
|
||||||
$this->isActivable = true;
|
|
||||||
$this->hardness = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function getName(){
|
||||||
return null;
|
return "Beetroot Block";
|
||||||
}
|
|
||||||
|
|
||||||
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){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,10 +22,18 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class BirchWoodStairs extends Stair{
|
class BirchWoodStairs extends Stair{
|
||||||
|
|
||||||
|
protected $id = self::BIRCH_WOOD_STAIRS;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::BIRCH_WOOD_STAIRS, $meta, "Birch Wood Stairs");
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Birch Wood Stairs";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
@ -33,4 +41,16 @@ class BirchWoodStairs extends Stair{
|
|||||||
[$this->id, 0, 1],
|
[$this->id, 0, 1],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResistance(){
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -22,10 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Bookshelf extends Solid{
|
class Bookshelf extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::BOOKSHELF;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::BOOKSHELF, 0, "Bookshelf");
|
|
||||||
$this->hardness = 7.5;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Bookshelf";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,9 +22,30 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class BrickStairs extends Stair{
|
class BrickStairs extends Stair{
|
||||||
|
|
||||||
|
protected $id = self::BRICK_STAIRS;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::BRICK_STAIRS, $meta, "Brick Stairs");
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResistance(){
|
||||||
|
return 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Brick Stairs";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,28 +22,30 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Bricks extends Solid{
|
class Bricks extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::BRICKS_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::BRICKS_BLOCK, 0, "Bricks");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getHardness(){
|
||||||
switch($item->isPickaxe()){
|
return 2;
|
||||||
case 5:
|
}
|
||||||
return 0.4;
|
|
||||||
case 4:
|
public function getResistance(){
|
||||||
return 0.5;
|
return 30;
|
||||||
case 3:
|
}
|
||||||
return 0.75;
|
|
||||||
case 2:
|
public function getToolType(){
|
||||||
return 0.25;
|
return Tool::TYPE_PICKAXE;
|
||||||
case 1:
|
}
|
||||||
return 1.5;
|
|
||||||
default:
|
public function getName(){
|
||||||
return 10;
|
return "Bricks";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -26,16 +26,25 @@ use pocketmine\level\Level;
|
|||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class BrownMushroom extends Flowable{
|
class BrownMushroom extends Flowable{
|
||||||
public function __construct(){
|
|
||||||
parent::__construct(self::BROWN_MUSHROOM, 0, "Brown Mushroom");
|
protected $id = self::BROWN_MUSHROOM;
|
||||||
$this->hardness = 0;
|
|
||||||
|
public function __construct($meta = 0){
|
||||||
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Brown Mushroom";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
if($this->getSide(0)->isTransparent() === true){
|
||||||
$this->getLevel()->dropItem($this, Item::get($this->id));
|
$this->getLevel()->useBreakOn($this);
|
||||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
@ -46,8 +55,8 @@ class BrownMushroom extends Flowable{
|
|||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->isTransparent === false){
|
if($down->isTransparent() === false){
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
$this->getLevel()->setBlock($block, $this, true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\Enum;
|
use pocketmine\nbt\tag\Enum;
|
||||||
@ -32,10 +33,31 @@ use pocketmine\tile\Furnace;
|
|||||||
use pocketmine\tile\Tile;
|
use pocketmine\tile\Tile;
|
||||||
|
|
||||||
class BurningFurnace extends Solid{
|
class BurningFurnace extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::BURNING_FURNACE;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::BURNING_FURNACE, $meta, "Burning Furnace");
|
$this->meta = $meta;
|
||||||
$this->isActivable = true;
|
}
|
||||||
$this->hardness = 17.5;
|
|
||||||
|
public function getName(){
|
||||||
|
return "Burning Furnace";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeActivated(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 3.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
@ -46,8 +68,8 @@ class BurningFurnace extends Solid{
|
|||||||
3 => 3,
|
3 => 3,
|
||||||
];
|
];
|
||||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
$this->getLevel()->setBlock($block, $this, true, true);
|
||||||
$nbt = new Compound(false, [
|
$nbt = new Compound("", [
|
||||||
new Enum("Items", []),
|
new Enum("Items", []),
|
||||||
new String("id", Tile::FURNACE),
|
new String("id", Tile::FURNACE),
|
||||||
new Int("x", $this->x),
|
new Int("x", $this->x),
|
||||||
@ -55,13 +77,13 @@ class BurningFurnace extends Solid{
|
|||||||
new Int("z", $this->z)
|
new Int("z", $this->z)
|
||||||
]);
|
]);
|
||||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
$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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onBreak(Item $item){
|
public function onBreak(Item $item){
|
||||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -73,7 +95,7 @@ class BurningFurnace extends Solid{
|
|||||||
if($t instanceof Furnace){
|
if($t instanceof Furnace){
|
||||||
$furnace = $t;
|
$furnace = $t;
|
||||||
}else{
|
}else{
|
||||||
$nbt = new Compound(false, [
|
$nbt = new Compound("", [
|
||||||
new Enum("Items", []),
|
new Enum("Items", []),
|
||||||
new String("id", Tile::FURNACE),
|
new String("id", Tile::FURNACE),
|
||||||
new Int("x", $this->x),
|
new Int("x", $this->x),
|
||||||
@ -81,10 +103,10 @@ class BurningFurnace extends Solid{
|
|||||||
new Int("z", $this->z)
|
new Int("z", $this->z)
|
||||||
]);
|
]);
|
||||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
$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){
|
if($player->isCreative()){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,37 +116,11 @@ class BurningFurnace extends Solid{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
|
||||||
switch($item->isPickaxe()){
|
|
||||||
case 5:
|
|
||||||
return 0.7;
|
|
||||||
case 4:
|
|
||||||
return 0.9;
|
|
||||||
case 3:
|
|
||||||
return 1.35;
|
|
||||||
case 2:
|
|
||||||
return 0.45;
|
|
||||||
case 1:
|
|
||||||
return 2.65;
|
|
||||||
default:
|
|
||||||
return 17.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
$drops = [];
|
$drops = [];
|
||||||
if($item->isPickaxe() >= 1){
|
if($item->isPickaxe() >= 1){
|
||||||
$drops[] = [Item::FURNACE, 0, 1];
|
$drops[] = [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[] = [$slot->getID(), $slot->getDamage(), $slot->getCount()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $drops;
|
return $drops;
|
||||||
}
|
}
|
||||||
|
@ -21,45 +21,85 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
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\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\math\Vector3 as Vector3;
|
use pocketmine\math\AxisAlignedBB;
|
||||||
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class Cactus extends Transparent{
|
class Cactus extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::CACTUS;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::CACTUS, $meta, "Cactus");
|
$this->meta = $meta;
|
||||||
$this->isFullBlock = false;
|
}
|
||||||
$this->hardness = 2;
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasEntityCollision(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Cactus";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function recalculateBoundingBox(){
|
||||||
|
|
||||||
|
return new AxisAlignedBB(
|
||||||
|
$this->x + 0.0625,
|
||||||
|
$this->y + 0.0625,
|
||||||
|
$this->z + 0.0625,
|
||||||
|
$this->x + 0.9375,
|
||||||
|
$this->y + 0.9375,
|
||||||
|
$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){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->getID() !== self::SAND and $down->getID() !== self::CACTUS){ //Replace with common break method
|
if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){
|
||||||
$this->getLevel()->setBlock($this, new Air(), false);
|
$this->getLevel()->useBreakOn($this);
|
||||||
$this->getLevel()->dropItem($this, Item::get($this->id));
|
}else{
|
||||||
|
for($side = 2; $side <= 5; ++$side){
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
$b = $this->getSide($side);
|
||||||
|
if(!$b->canBeFlowedInto()){
|
||||||
|
$this->getLevel()->useBreakOn($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||||
if($this->getSide(0)->getID() !== self::CACTUS){
|
if($this->getSide(0)->getId() !== self::CACTUS){
|
||||||
if($this->meta == 0x0F){
|
if($this->meta == 0x0F){
|
||||||
for($y = 1; $y < 3; ++$y){
|
for($y = 1; $y < 3; ++$y){
|
||||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||||
if($b->getID() === self::AIR){
|
if($b->getId() === self::AIR){
|
||||||
$this->getLevel()->setBlock($b, new Cactus(), true, false, true);
|
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Cactus()));
|
||||||
break;
|
if(!$ev->isCancelled()){
|
||||||
|
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->meta = 0;
|
$this->meta = 0;
|
||||||
$this->getLevel()->setBlock($this, $this, false);
|
$this->getLevel()->setBlock($this, $this);
|
||||||
}else{
|
}else{
|
||||||
++$this->meta;
|
++$this->meta;
|
||||||
$this->getLevel()->setBlock($this, $this, false);
|
$this->getLevel()->setBlock($this, $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_RANDOM;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,13 +108,13 @@ class Cactus extends Transparent{
|
|||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->getID() === self::SAND or $down->getID() === self::CACTUS){
|
if($down->getId() === self::SAND or $down->getId() === self::CACTUS){
|
||||||
$block0 = $this->getSide(2);
|
$block0 = $this->getSide(2);
|
||||||
$block1 = $this->getSide(3);
|
$block1 = $this->getSide(3);
|
||||||
$block2 = $this->getSide(4);
|
$block2 = $this->getSide(4);
|
||||||
$block3 = $this->getSide(5);
|
$block3 = $this->getSide(5);
|
||||||
if($block0->isTransparent === true and $block1->isTransparent === true and $block2->isTransparent === true and $block3->isTransparent === true){
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -21,23 +21,51 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\event\entity\EntityRegainHealthEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class Cake extends Transparent{
|
class Cake extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::CAKE_BLOCK;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::CAKE_BLOCK, 0, "Cake Block");
|
$this->meta = $meta;
|
||||||
$this->isFullBlock = false;
|
}
|
||||||
$this->isActivable = true;
|
|
||||||
$this->meta = $meta & 0x07;
|
public function canBeActivated(){
|
||||||
$this->hardness = 2.5;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Cake Block";
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->getID() !== self::AIR){
|
if($down->getId() !== self::AIR){
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
$this->getLevel()->setBlock($block, $this, true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -47,8 +75,8 @@ class Cake extends Transparent{
|
|||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
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;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
@ -62,13 +90,16 @@ class Cake extends Transparent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onActivate(Item $item, Player $player = null){
|
public function onActivate(Item $item, Player $player = null){
|
||||||
if($player instanceof Player and $player->getHealth() < 20){
|
if($player instanceof Player and $player->getHealth() < $player->getMaxHealth()){
|
||||||
++$this->meta;
|
++$this->meta;
|
||||||
$player->heal(3, "cake");
|
|
||||||
|
$ev = new EntityRegainHealthEvent($player, 3, EntityRegainHealthEvent::CAUSE_EATING);
|
||||||
|
$player->heal($ev->getAmount(), $ev);
|
||||||
|
|
||||||
if($this->meta >= 0x06){
|
if($this->meta >= 0x06){
|
||||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
$this->getLevel()->setBlock($this, new Air(), true);
|
||||||
}else{
|
}else{
|
||||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
$this->getLevel()->setBlock($this, $this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -23,12 +23,27 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class Carpet extends Flowable{
|
class Carpet extends Flowable{
|
||||||
|
|
||||||
|
protected $id = self::CARPET;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::CARPET, $meta, "Carpet");
|
$this->meta = $meta;
|
||||||
$names = [
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSolid(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
static $names = [
|
||||||
0 => "White Carpet",
|
0 => "White Carpet",
|
||||||
1 => "Orange Carpet",
|
1 => "Orange Carpet",
|
||||||
2 => "Magenta Carpet",
|
2 => "Magenta Carpet",
|
||||||
@ -46,16 +61,25 @@ class Carpet extends Flowable{
|
|||||||
14 => "Red Carpet",
|
14 => "Red Carpet",
|
||||||
15 => "Black Carpet",
|
15 => "Black Carpet",
|
||||||
];
|
];
|
||||||
$this->name = $names[$this->meta];
|
return $names[$this->meta & 0x0f];
|
||||||
$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){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->getID() !== self::AIR){
|
if($down->getId() !== self::AIR){
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
$this->getLevel()->setBlock($block, $this, true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -65,9 +89,8 @@ class Carpet extends Flowable{
|
|||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
if($this->getSide(0)->getID() === self::AIR){ //TODO: Replace with common break method
|
if($this->getSide(0)->getId() === self::AIR){
|
||||||
$this->getLevel()->dropItem($this, Item::get($this->id, $this->meta, 1));
|
$this->getLevel()->useBreakOn($this);
|
||||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
|
@ -22,67 +22,17 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\Player;
|
|
||||||
|
|
||||||
class Carrot extends Flowable{
|
class Carrot extends Crops{
|
||||||
|
|
||||||
|
protected $id = self::CARROT_BLOCK;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::CARROT_BLOCK, $meta, "Carrot Block");
|
$this->meta = $meta;
|
||||||
$this->isActivable = true;
|
|
||||||
$this->hardness = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function getName(){
|
||||||
return null;
|
return "Carrot Block";
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
use pocketmine\nbt\NBT;
|
use pocketmine\nbt\NBT;
|
||||||
use pocketmine\nbt\tag\Compound;
|
use pocketmine\nbt\tag\Compound;
|
||||||
use pocketmine\nbt\tag\Enum;
|
use pocketmine\nbt\tag\Enum;
|
||||||
@ -33,12 +35,37 @@ use pocketmine\tile\Tile;
|
|||||||
|
|
||||||
class Chest extends Transparent{
|
class Chest extends Transparent{
|
||||||
|
|
||||||
const SLOTS = 27;
|
protected $id = self::CHEST;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::CHEST, $meta, "Chest");
|
$this->meta = $meta;
|
||||||
$this->isActivable = true;
|
}
|
||||||
$this->hardness = 15;
|
|
||||||
|
public function canBeActivated(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Chest";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
@ -49,7 +76,7 @@ class Chest extends Transparent{
|
|||||||
3 => 3,
|
3 => 3,
|
||||||
];
|
];
|
||||||
|
|
||||||
$chest = false;
|
$chest = null;
|
||||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||||
|
|
||||||
for($side = 2; $side <= 5; ++$side){
|
for($side = 2; $side <= 5; ++$side){
|
||||||
@ -68,8 +95,8 @@ class Chest extends Transparent{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
$this->getLevel()->setBlock($block, $this, true, true);
|
||||||
$nbt = new Compound(false, [
|
$nbt = new Compound("", [
|
||||||
new Enum("Items", []),
|
new Enum("Items", []),
|
||||||
new String("id", Tile::CHEST),
|
new String("id", Tile::CHEST),
|
||||||
new Int("x", $this->x),
|
new Int("x", $this->x),
|
||||||
@ -77,9 +104,9 @@ class Chest extends Transparent{
|
|||||||
new Int("z", $this->z)
|
new Int("z", $this->z)
|
||||||
]);
|
]);
|
||||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
$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);
|
$chest->pairWith($tile);
|
||||||
$tile->pairWith($chest);
|
$tile->pairWith($chest);
|
||||||
}
|
}
|
||||||
@ -92,7 +119,7 @@ class Chest extends Transparent{
|
|||||||
if($t instanceof TileChest){
|
if($t instanceof TileChest){
|
||||||
$t->unpair();
|
$t->unpair();
|
||||||
}
|
}
|
||||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -100,7 +127,7 @@ class Chest extends Transparent{
|
|||||||
public function onActivate(Item $item, Player $player = null){
|
public function onActivate(Item $item, Player $player = null){
|
||||||
if($player instanceof Player){
|
if($player instanceof Player){
|
||||||
$top = $this->getSide(1);
|
$top = $this->getSide(1);
|
||||||
if($top->isTransparent !== true){
|
if($top->isTransparent() !== true){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +136,7 @@ class Chest extends Transparent{
|
|||||||
if($t instanceof TileChest){
|
if($t instanceof TileChest){
|
||||||
$chest = $t;
|
$chest = $t;
|
||||||
}else{
|
}else{
|
||||||
$nbt = new Compound(false, [
|
$nbt = new Compound("", [
|
||||||
new Enum("Items", []),
|
new Enum("Items", []),
|
||||||
new String("id", Tile::CHEST),
|
new String("id", Tile::CHEST),
|
||||||
new Int("x", $this->x),
|
new Int("x", $this->x),
|
||||||
@ -117,11 +144,11 @@ class Chest extends Transparent{
|
|||||||
new Int("z", $this->z)
|
new Int("z", $this->z)
|
||||||
]);
|
]);
|
||||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
$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;
|
return true;
|
||||||
}
|
}
|
||||||
$player->addWindow($chest->getInventory());
|
$player->addWindow($chest->getInventory());
|
||||||
@ -131,19 +158,8 @@ class Chest extends Transparent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
$drops = [
|
return [
|
||||||
[$this->id, 0, 1],
|
[$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[] = [$slot->getID(), $slot->getDamage(), $slot->getCount()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $drops;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -22,11 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Clay extends Solid{
|
class Clay extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::CLAY_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::CLAY_BLOCK, 0, "Clay Block");
|
|
||||||
$this->hardness = 3;
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SHOVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Clay Block";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,28 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Coal extends Solid{
|
class Coal extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::COAL_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::COAL_BLOCK, 0, "Coal Block");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getHardness(){
|
||||||
switch($item->isPickaxe()){
|
return 5;
|
||||||
case 5:
|
}
|
||||||
return 0.95;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 1.25;
|
return Tool::TYPE_PICKAXE;
|
||||||
case 3:
|
}
|
||||||
return 1.9;
|
|
||||||
case 2:
|
public function getName(){
|
||||||
return 0.65;
|
return "Coal Block";
|
||||||
case 1:
|
|
||||||
return 3.75;
|
|
||||||
default:
|
|
||||||
return 25;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,28 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class CoalOre extends Solid{
|
class CoalOre extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::COAL_ORE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::COAL_ORE, 0, "Coal Ore");
|
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getHardness(){
|
||||||
switch($item->isPickaxe()){
|
return 3;
|
||||||
case 5:
|
}
|
||||||
return 0.6;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 0.75;
|
return Tool::TYPE_PICKAXE;
|
||||||
case 3:
|
}
|
||||||
return 1.15;
|
|
||||||
case 2:
|
public function getName(){
|
||||||
return 0.4;
|
return "Coal Ore";
|
||||||
case 1:
|
|
||||||
return 2.25;
|
|
||||||
default:
|
|
||||||
return 15;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,28 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Cobblestone extends Solid{
|
class Cobblestone extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::COBBLESTONE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::COBBLESTONE, 0, "Cobblestone");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getToolType(){
|
||||||
switch($item->isPickaxe()){
|
return Tool::TYPE_PICKAXE;
|
||||||
case 5:
|
}
|
||||||
return 0.4;
|
|
||||||
case 4:
|
public function getName(){
|
||||||
return 0.5;
|
return "Cobblestone";
|
||||||
case 3:
|
}
|
||||||
return 0.75;
|
|
||||||
case 2:
|
public function getHardness(){
|
||||||
return 0.25;
|
return 2;
|
||||||
case 1:
|
|
||||||
return 1.5;
|
|
||||||
default:
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,9 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class CobblestoneStairs extends Stair{
|
class CobblestoneStairs extends Stair{
|
||||||
|
|
||||||
|
protected $id = self::COBBLESTONE_STAIRS;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::COBBLESTONE_STAIRS, $meta, "Cobblestone Stairs");
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Cobblestone Stairs";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -21,17 +21,40 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\entity\Entity;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Cobweb extends Flowable{
|
class Cobweb extends Flowable{
|
||||||
|
|
||||||
|
protected $id = self::COBWEB;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::COBWEB, 0, "Cobweb");
|
|
||||||
$this->isSolid = true;
|
}
|
||||||
$this->isFullBlock = false;
|
|
||||||
$this->hardness = 25;
|
public function hasEntityCollision(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Cobweb";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SWORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEntityCollide(Entity $entity){
|
||||||
|
$entity->resetFallDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
//TODO: correct drops
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
96
src/pocketmine/block/Crops.php
Normal file
96
src/pocketmine/block/Crops.php
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?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 function canBeActivated(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -26,20 +26,22 @@ use pocketmine\level\Level;
|
|||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class Dandelion extends Flowable{
|
class Dandelion extends Flowable{
|
||||||
|
|
||||||
|
protected $id = self::DANDELION;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::DANDELION, 0, "Dandelion");
|
|
||||||
$this->hardness = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function getName(){
|
||||||
return null;
|
return "Dandelion";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -49,10 +51,8 @@ class Dandelion extends Flowable{
|
|||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
if($this->getSide(0)->isTransparent() === true){
|
||||||
//TODO
|
$this->getLevel()->useBreakOn($this);
|
||||||
//Server::getInstance()->api->entity->drop($this, Item::get($this->id));
|
|
||||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,22 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class DarkOakWoodStairs extends Stair{
|
class DarkOakWoodStairs extends Stair{
|
||||||
|
|
||||||
|
protected $id = self::DARK_OAK_WOOD_STAIRS;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::DARK_OAK_WOOD_STAIRS, $meta, "Dark Oak Wood Stairs");
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Dark Oak Wood Stairs";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -24,21 +24,22 @@ namespace pocketmine\block;
|
|||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
|
||||||
class DeadBush extends Flowable{
|
class DeadBush extends Flowable{
|
||||||
public function __construct(){
|
|
||||||
parent::__construct(self::DEAD_BUSH, 0, "Dead Bush");
|
protected $id = self::DEAD_BUSH;
|
||||||
//$this->isReplaceable = true;
|
|
||||||
$this->hardness = 0;
|
public function __construct($meta = 0){
|
||||||
|
$this->meta = $meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function getName(){
|
||||||
return null;
|
return "Dead Bush";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
if($this->getSide(0)->isTransparent() === true){
|
||||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
$this->getLevel()->useBreakOn($this);
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
|
@ -22,22 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Diamond extends Solid{
|
class Diamond extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::DIAMOND_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::DIAMOND_BLOCK, 0, "Diamond Block");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getHardness(){
|
||||||
switch($item->isPickaxe()){
|
return 5;
|
||||||
case 5:
|
}
|
||||||
return 0.95;
|
|
||||||
case 4:
|
public function getName(){
|
||||||
return 1.25;
|
return "Diamond Block";
|
||||||
default:
|
}
|
||||||
return 25;
|
|
||||||
}
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,22 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class DiamondOre extends Solid{
|
class DiamondOre extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::DIAMOND_ORE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::DIAMOND_ORE, 0, "Diamond Ore");
|
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getHardness(){
|
||||||
switch($item->isPickaxe()){
|
return 3;
|
||||||
case 5:
|
}
|
||||||
return 0.6;
|
|
||||||
case 4:
|
public function getName(){
|
||||||
return 0.75;
|
return "Diamond Ore";
|
||||||
default:
|
}
|
||||||
return 15;
|
|
||||||
}
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,24 +22,37 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class Dirt extends Solid{
|
class Dirt extends Solid{
|
||||||
|
|
||||||
public $isActivable = true;
|
|
||||||
protected $hardness = 2.5;
|
|
||||||
protected $id = self::DIRT;
|
protected $id = self::DIRT;
|
||||||
protected $meta = 0;
|
|
||||||
protected $name = "Dirt";
|
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canBeActivated(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SHOVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Dirt";
|
||||||
|
}
|
||||||
|
|
||||||
public function onActivate(Item $item, Player $player = null){
|
public function onActivate(Item $item, Player $player = null){
|
||||||
if($item->isHoe()){
|
if($item->isHoe()){
|
||||||
$item->useOn($this);
|
$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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -23,20 +23,191 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\level\sound\DoorSound;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\network\protocol\LevelEventPacket;
|
use pocketmine\network\protocol\LevelEventPacket;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
|
|
||||||
|
|
||||||
abstract class Door extends Transparent{
|
abstract class Door extends Transparent{
|
||||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
|
||||||
parent::__construct($id, $meta, $name);
|
public function canBeActivated(){
|
||||||
$this->isSolid = false;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSolid(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getFullDamage(){
|
||||||
|
$damage = $this->getDamage();
|
||||||
|
$isUp = ($damage & 0x08) > 0;
|
||||||
|
|
||||||
|
if($isUp){
|
||||||
|
$down = $this->getSide(Vector3::SIDE_DOWN)->getDamage();
|
||||||
|
$up = $damage;
|
||||||
|
}else{
|
||||||
|
$down = $damage;
|
||||||
|
$up = $this->getSide(Vector3::SIDE_UP)->getDamage();
|
||||||
|
}
|
||||||
|
|
||||||
|
$isRight = ($up & 0x01) > 0;
|
||||||
|
|
||||||
|
return $down & 0x07 | ($isUp ? 8 : 0) | ($isRight ? 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;
|
||||||
|
$isOpen = (($damage & 0x04) > 0);
|
||||||
|
$isRight = (($damage & 0x10) > 0);
|
||||||
|
|
||||||
|
if($j === 0){
|
||||||
|
if($isOpen){
|
||||||
|
if(!$isRight){
|
||||||
|
$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($isOpen){
|
||||||
|
if(!$isRight){
|
||||||
|
$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($isOpen){
|
||||||
|
if(!$isRight){
|
||||||
|
$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($isOpen){
|
||||||
|
if(!$isRight){
|
||||||
|
$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){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||||
$this->getLevel()->setBlock($this, new Air(), false);
|
$this->getLevel()->setBlock($this, new Air(), false);
|
||||||
if($this->getSide(1) instanceof Door){
|
if($this->getSide(1) instanceof Door){
|
||||||
$this->getLevel()->setBlock($this->getSide(1), new Air(), false);
|
$this->getLevel()->setBlock($this->getSide(1), new Air(), false);
|
||||||
@ -53,7 +224,7 @@ abstract class Door extends Transparent{
|
|||||||
if($face === 1){
|
if($face === 1){
|
||||||
$blockUp = $this->getSide(1);
|
$blockUp = $this->getSide(1);
|
||||||
$blockDown = $this->getSide(0);
|
$blockDown = $this->getSide(0);
|
||||||
if($blockUp->isReplaceable === false or $blockDown->isTransparent === true){
|
if($blockUp->canBeReplaced() === false or $blockDown->isTransparent() === true){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$direction = $player instanceof Player ? $player->getDirection() : 0;
|
$direction = $player instanceof Player ? $player->getDirection() : 0;
|
||||||
@ -66,13 +237,13 @@ abstract class Door extends Transparent{
|
|||||||
$next = $this->getSide($face[(($direction + 2) % 4)]);
|
$next = $this->getSide($face[(($direction + 2) % 4)]);
|
||||||
$next2 = $this->getSide($face[$direction]);
|
$next2 = $this->getSide($face[$direction]);
|
||||||
$metaUp = 0x08;
|
$metaUp = 0x08;
|
||||||
if($next->getID() === $this->id or ($next2->isTransparent === false and $next->isTransparent === true)){ //Door hinge
|
if($next->getId() === $this->getId() or ($next2->isTransparent() === false and $next->isTransparent() === true)){ //Door hinge
|
||||||
$metaUp |= 0x01;
|
$metaUp |= 0x01;
|
||||||
}
|
}
|
||||||
$this->getLevel()->setBlock($blockUp, Block::get($this->id, $metaUp), true, false, true); //Top
|
|
||||||
|
|
||||||
$this->meta = $player->getDirection() & 0x03;
|
$this->setDamage($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->getId(), $metaUp), true); //Top
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,58 +251,46 @@ abstract class Door extends Transparent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function onBreak(Item $item){
|
public function onBreak(Item $item){
|
||||||
if(($this->meta & 0x08) === 0x08){
|
if(($this->getDamage() & 0x08) === 0x08){
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->getID() === $this->id){
|
if($down->getId() === $this->getId()){
|
||||||
$this->getLevel()->setBlock($down, new Air(), true, false, true);
|
$this->getLevel()->setBlock($down, new Air(), true);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
$up = $this->getSide(1);
|
$up = $this->getSide(1);
|
||||||
if($up->getID() === $this->id){
|
if($up->getId() === $this->getId()){
|
||||||
$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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onActivate(Item $item, Player $player = null){
|
public function onActivate(Item $item, Player $player = null){
|
||||||
if(($this->meta & 0x08) === 0x08){ //Top
|
if(($this->getDamage() & 0x08) === 0x08){ //Top
|
||||||
$down = $this->getSide(0);
|
$down = $this->getSide(0);
|
||||||
if($down->getID() === $this->id){
|
if($down->getId() === $this->getId()){
|
||||||
$meta = $down->getDamage() ^ 0x04;
|
$meta = $down->getDamage() ^ 0x04;
|
||||||
$this->getLevel()->setBlock($down, Block::get($this->id, $meta), true, false, true);
|
$this->getLevel()->setBlock($down, Block::get($this->getId(), $meta), true);
|
||||||
$players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
|
$players = $this->getLevel()->getChunkPlayers($this->x >> 4, $this->z >> 4);
|
||||||
if($player instanceof Player){
|
if($player instanceof Player){
|
||||||
unset($players[$player->getID()]);
|
unset($players[$player->getLoaderId()]);
|
||||||
}
|
}
|
||||||
$pk = new LevelEventPacket;
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$pk->evid = 1003;
|
|
||||||
$pk->data = 0;
|
|
||||||
Server::broadcastPacket($players, $pk);
|
|
||||||
|
|
||||||
|
$this->level->addSound(new DoorSound($this));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}else{
|
}else{
|
||||||
$this->meta ^= 0x04;
|
$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);
|
$players = $this->getLevel()->getChunkPlayers($this->x >> 4, $this->z >> 4);
|
||||||
if($player instanceof Player){
|
if($player instanceof Player){
|
||||||
unset($players[$player->getID()]);
|
unset($players[$player->getLoaderId()]);
|
||||||
}
|
}
|
||||||
$pk = new LevelEventPacket;
|
$this->level->addSound(new DoorSound($this));
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$pk->evid = 1003;
|
|
||||||
$pk->data = 0;
|
|
||||||
Server::broadcastPacket($players, $pk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -23,34 +23,35 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\Player;
|
|
||||||
|
|
||||||
class CyanFlower extends Flowable{
|
class DoublePlant extends Flowable{
|
||||||
public function __construct(){
|
|
||||||
parent::__construct(self::POPPY, 0, "Cyan Flower");
|
protected $id = self::DOUBLE_PLANT;
|
||||||
$this->hardness = 0;
|
|
||||||
|
public function __construct($meta = 0){
|
||||||
|
$this->meta = $meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function canBeReplaced(){
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
static $names = [
|
||||||
$down = $this->getSide(0);
|
0 => "Sunflower",
|
||||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
1 => "Lilac",
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
2 => "Double Tallgrass",
|
||||||
|
3 => "Large Fern",
|
||||||
return true;
|
4 => "Rose Bush",
|
||||||
}
|
5 => "Peony"
|
||||||
|
];
|
||||||
return false;
|
return $names[$this->meta & 0x07];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
if($this->getSide(0)->isTransparent === true){ //TODO: Replace with common break method
|
if($this->getSide(0)->isTransparent() === true){ //Replace with common break method
|
||||||
$this->getLevel()->dropItem($this, Item::get($this->id, 0, 1));
|
|
||||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
@ -59,4 +60,11 @@ class CyanFlower extends Flowable{
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDrops(Item $item){
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,11 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class DoubleSlab extends Solid{
|
class DoubleSlab extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::DOUBLE_SLAB;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::DOUBLE_SLAB, $meta, "Double Slab");
|
$this->meta = $meta;
|
||||||
$names = [
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
static $names = [
|
||||||
0 => "Stone",
|
0 => "Stone",
|
||||||
1 => "Sandstone",
|
1 => "Sandstone",
|
||||||
2 => "Wooden",
|
2 => "Wooden",
|
||||||
@ -34,26 +49,9 @@ class DoubleSlab extends Solid{
|
|||||||
4 => "Brick",
|
4 => "Brick",
|
||||||
5 => "Stone Brick",
|
5 => "Stone Brick",
|
||||||
6 => "Quartz",
|
6 => "Quartz",
|
||||||
|
7 => "",
|
||||||
];
|
];
|
||||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Slab";
|
return "Double " . $names[$this->meta & 0x07] . " Slab";
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
|
||||||
switch($item->isPickaxe()){
|
|
||||||
case 5:
|
|
||||||
return 0.4;
|
|
||||||
case 4:
|
|
||||||
return 0.5;
|
|
||||||
case 3:
|
|
||||||
return 0.75;
|
|
||||||
case 2:
|
|
||||||
return 0.25;
|
|
||||||
case 1:
|
|
||||||
return 1.5;
|
|
||||||
default:
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -24,35 +24,33 @@ namespace pocketmine\block;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
|
||||||
class DoubleWoodSlab extends Solid{
|
class DoubleWoodSlab extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::DOUBLE_WOOD_SLAB;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::DOUBLE_WOOD_SLAB, $meta, "Double Wooden Slab");
|
$this->meta = $meta;
|
||||||
$names = [
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
static $names = [
|
||||||
0 => "Oak",
|
0 => "Oak",
|
||||||
1 => "Spruce",
|
1 => "Spruce",
|
||||||
2 => "Birch",
|
2 => "Birch",
|
||||||
3 => "Jungle",
|
3 => "Jungle",
|
||||||
4 => "Acacia",
|
4 => "Acacia",
|
||||||
5 => "Dark Oak",
|
5 => "Dark Oak",
|
||||||
|
6 => "",
|
||||||
|
7 => ""
|
||||||
];
|
];
|
||||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
|
return "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
|
||||||
switch($item->isAxe()){
|
|
||||||
case 5:
|
|
||||||
return 0.4;
|
|
||||||
case 4:
|
|
||||||
return 0.5;
|
|
||||||
case 3:
|
|
||||||
return 0.75;
|
|
||||||
case 2:
|
|
||||||
return 0.25;
|
|
||||||
case 1:
|
|
||||||
return 1.5;
|
|
||||||
default:
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,22 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Emerald extends Solid{
|
class Emerald extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::EMERALD_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::EMERALD_BLOCK, 0, "Emerald Block");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getHardness(){
|
||||||
switch($item->isPickaxe()){
|
return 5;
|
||||||
case 5:
|
}
|
||||||
return 0.95;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 1.25;
|
return Tool::TYPE_PICKAXE;
|
||||||
default:
|
}
|
||||||
return 25;
|
|
||||||
}
|
public function getName(){
|
||||||
|
return "Emerald Block";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,22 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class EmeraldOre extends Solid{
|
class EmeraldOre extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::EMERALD_ORE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::EMERALD_ORE, 0, "Emerald Ore");
|
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "Emerald Ore";
|
||||||
case 5:
|
}
|
||||||
return 0.6;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 0.75;
|
return Tool::TYPE_PICKAXE;
|
||||||
default:
|
}
|
||||||
return 15;
|
|
||||||
}
|
public function getHardness(){
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
66
src/pocketmine/block/EndPortalFrame.php
Normal file
66
src/pocketmine/block/EndPortalFrame.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?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\math\AxisAlignedBB;
|
||||||
|
|
||||||
|
class EndPortalFrame extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::END_PORTAL_FRAME;
|
||||||
|
|
||||||
|
public function __construct($meta = 0){
|
||||||
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "End Portal Frame";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResistance(){
|
||||||
|
return 18000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBreakable(Item $item){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -22,27 +22,25 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class EndStone extends Solid{
|
class EndStone extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::END_STONE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::END_STONE, 0, "End Stone");
|
|
||||||
$this->hardness = 45;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "End Stone";
|
||||||
case 5:
|
}
|
||||||
return 0.6;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 0.75;
|
return Tool::TYPE_PICKAXE;
|
||||||
case 3:
|
}
|
||||||
return 1.15;
|
|
||||||
case 2:
|
public function getHardness(){
|
||||||
return 0.4;
|
return 3;
|
||||||
case 1:
|
|
||||||
return 2.25;
|
|
||||||
default:
|
|
||||||
return 15;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,16 +21,51 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\entity\Entity;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\math\Vector3;
|
||||||
|
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;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class Fallable extends Solid{
|
abstract class Fallable extends Solid{
|
||||||
|
|
||||||
public $hasPhysics = true;
|
|
||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
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;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onUpdate($type){
|
||||||
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
|
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||||
|
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,11 +22,38 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
|
|
||||||
class Farmland extends Solid{
|
class Farmland extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::FARMLAND;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::FARMLAND, $meta, "Farmland");
|
$this->meta = $meta;
|
||||||
$this->hardness = 3;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Farmland";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SHOVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
public function getDrops(Item $item){
|
||||||
|
@ -21,12 +21,65 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
|
use pocketmine\math\Vector3;
|
||||||
|
|
||||||
class Fence extends Transparent{
|
class Fence extends Transparent{
|
||||||
public function __construct(){
|
|
||||||
parent::__construct(self::FENCE, 0, "Fence");
|
protected $id = self::FENCE;
|
||||||
$this->isFullBlock = false;
|
|
||||||
$this->hardness = 15;
|
public function __construct($meta = 0){
|
||||||
|
$this->meta = $meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
static $names = [
|
||||||
|
0 => "Oak Fence",
|
||||||
|
1 => "Spruce Fence",
|
||||||
|
2 => "Birch Fence",
|
||||||
|
3 => "Jungle Fence",
|
||||||
|
4 => "Acacia Fence",
|
||||||
|
5 => "Dark Oak Fence",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
];
|
||||||
|
return $names[$this->meta & 0x07];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function recalculateBoundingBox(){
|
||||||
|
|
||||||
|
$north = $this->canConnect($this->getSide(Vector3::SIDE_NORTH));
|
||||||
|
$south = $this->canConnect($this->getSide(Vector3::SIDE_SOUTH));
|
||||||
|
$west = $this->canConnect($this->getSide(Vector3::SIDE_WEST));
|
||||||
|
$east = $this->canConnect($this->getSide(Vector3::SIDE_EAST));
|
||||||
|
|
||||||
|
$n = $north ? 0 : 0.375;
|
||||||
|
$s = $south ? 1 : 0.625;
|
||||||
|
$w = $west ? 0 : 0.375;
|
||||||
|
$e = $east ? 1 : 0.625;
|
||||||
|
|
||||||
|
return new AxisAlignedBB(
|
||||||
|
$this->x + $w,
|
||||||
|
$this->y,
|
||||||
|
$this->z + $n,
|
||||||
|
$this->x + $e,
|
||||||
|
$this->y + 1.5,
|
||||||
|
$this->z + $s
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canConnect(Block $block){
|
||||||
|
return ($block instanceof Fence or $block instanceof FenceGate) ? true : $block->isSolid() and !$block->isTransparent();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -22,18 +22,61 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class FenceGate extends Transparent{
|
class FenceGate extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::FENCE_GATE;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::FENCE_GATE, $meta, "Fence Gate");
|
$this->meta = $meta;
|
||||||
$this->isActivable = true;
|
}
|
||||||
if(($this->meta & 0x04) === 0x04){
|
|
||||||
$this->isFullBlock = true;
|
public function getName(){
|
||||||
}else{
|
return "Oak Fence Gate";
|
||||||
$this->isFullBlock = false;
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeActivated(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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.5,
|
||||||
|
$this->z + 0.625
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
return new AxisAlignedBB(
|
||||||
|
$this->x + 0.375,
|
||||||
|
$this->y,
|
||||||
|
$this->z,
|
||||||
|
$this->x + 0.625,
|
||||||
|
$this->y + 1.5,
|
||||||
|
$this->z + 1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
@ -44,7 +87,7 @@ class FenceGate extends Transparent{
|
|||||||
3 => 2,
|
3 => 2,
|
||||||
];
|
];
|
||||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03;
|
$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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -63,12 +106,7 @@ class FenceGate extends Transparent{
|
|||||||
3 => 2,
|
3 => 2,
|
||||||
];
|
];
|
||||||
$this->meta = ($faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03) | ((~$this->meta) & 0x04);
|
$this->meta = ($faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03) | ((~$this->meta) & 0x04);
|
||||||
if(($this->meta & 0x04) === 0x04){
|
$this->getLevel()->setBlock($this, $this, true);
|
||||||
$this->isFullBlock = true;
|
|
||||||
}else{
|
|
||||||
$this->isFullBlock = false;
|
|
||||||
}
|
|
||||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,12 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
class EndPortal extends Solid{
|
|
||||||
public function __construct($meta = 0){
|
class FenceGateAcacia extends FenceGate{
|
||||||
parent::__construct(self::END_PORTAL, $meta, "End Portal");
|
|
||||||
$this->hardness = 18000000;
|
protected $id = self::FENCE_GATE_ACACIA;
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Acacia Fence Gate";
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,23 +19,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
namespace pocketmine\block;
|
||||||
namespace pocketmine\network\protocol;
|
|
||||||
|
|
||||||
|
|
||||||
class UnknownPacket extends DataPacket{
|
class FenceGateBirch extends FenceGate{
|
||||||
public $packetID = -1;
|
|
||||||
|
|
||||||
public function pid(){
|
protected $id = self::FENCE_GATE_BIRCH;
|
||||||
return $this->packetID;
|
|
||||||
|
public function getName(){
|
||||||
|
return "Birch Fence Gate";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function decode(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encode(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
32
src/pocketmine/block/FenceGateDarkOak.php
Normal file
32
src/pocketmine/block/FenceGateDarkOak.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?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{
|
||||||
|
|
||||||
|
protected $id = self::FENCE_GATE_DARK_OAK;
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Dark Oak Fence Gate";
|
||||||
|
}
|
||||||
|
}
|
32
src/pocketmine/block/FenceGateJungle.php
Normal file
32
src/pocketmine/block/FenceGateJungle.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?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{
|
||||||
|
|
||||||
|
protected $id = self::FENCE_GATE_JUNGLE;
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Jungle Fence Gate";
|
||||||
|
}
|
||||||
|
}
|
32
src/pocketmine/block/FenceGateSpruce.php
Normal file
32
src/pocketmine/block/FenceGateSpruce.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?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{
|
||||||
|
|
||||||
|
protected $id = self::FENCE_GATE_SPRUCE;
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Spruce Fence Gate";
|
||||||
|
}
|
||||||
|
}
|
@ -21,22 +21,55 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\entity\Effect;
|
||||||
|
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\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class Fire extends Flowable{
|
class Fire extends Flowable{
|
||||||
|
|
||||||
|
protected $id = self::FIRE;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::FIRE, $meta, "Fire");
|
$this->meta = $meta;
|
||||||
$this->isReplaceable = true;
|
|
||||||
$this->breakable = false;
|
|
||||||
$this->isFullBlock = true;
|
|
||||||
$this->hardness = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function hasEntityCollision(){
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Fire Block";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBreakable(Item $item){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeReplaced(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEntityCollide(Entity $entity){
|
||||||
|
if(!$entity->hasEffect(Effect::FIRE_RESISTANCE)){
|
||||||
|
$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){
|
public function getDrops(Item $item){
|
||||||
return [];
|
return [];
|
||||||
@ -46,16 +79,16 @@ class Fire extends Flowable{
|
|||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
for($s = 0; $s <= 5; ++$s){
|
for($s = 0; $s <= 5; ++$s){
|
||||||
$side = $this->getSide($s);
|
$side = $this->getSide($s);
|
||||||
if($side->getID() !== self::AIR and !($side instanceof Liquid)){
|
if($side->getId() !== self::AIR and !($side instanceof Liquid)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->getLevel()->setBlock($this, new Air(), true, false, true);
|
$this->getLevel()->setBlock($this, new Air(), true);
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||||
if($this->getSide(0)->getID() !== self::NETHERRACK){
|
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;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,27 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
|
||||||
class Flowable extends Transparent{
|
use pocketmine\item\Item;
|
||||||
|
|
||||||
public $isFlowable = true;
|
abstract class Flowable extends Transparent{
|
||||||
public $isFullBlock = false;
|
|
||||||
public $isSolid = false;
|
|
||||||
|
|
||||||
|
public function canBeFlowedInto(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getResistance(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSolid(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBoundingBox(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
91
src/pocketmine/block/Flower.php
Normal file
91
src/pocketmine/block/Flower.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?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\math\Vector3;
|
||||||
|
use pocketmine\Player;
|
||||||
|
|
||||||
|
class Flower extends Flowable{
|
||||||
|
const TYPE_POPPY = 0;
|
||||||
|
const TYPE_BLUE_ORCHID = 1;
|
||||||
|
const TYPE_ALLIUM = 2;
|
||||||
|
const TYPE_AZURE_BLUET = 3;
|
||||||
|
const TYPE_RED_TULIP = 4;
|
||||||
|
const TYPE_ORANGE_TULIP = 5;
|
||||||
|
const TYPE_WHITE_TULIP = 6;
|
||||||
|
const TYPE_PINK_TULIP = 7;
|
||||||
|
const TYPE_OXEYE_DAISY = 8;
|
||||||
|
|
||||||
|
protected $id = self::RED_FLOWER;
|
||||||
|
|
||||||
|
public function __construct($meta = 0){
|
||||||
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
static $names = [
|
||||||
|
self::TYPE_POPPY => "Poppy",
|
||||||
|
self::TYPE_BLUE_ORCHID => "Blue Orchid",
|
||||||
|
self::TYPE_ALLIUM => "Allium",
|
||||||
|
self::TYPE_AZURE_BLUET => "Azure Bluet",
|
||||||
|
self::TYPE_RED_TULIP => "Red Tulip",
|
||||||
|
self::TYPE_ORANGE_TULIP => "Orange Tulip",
|
||||||
|
self::TYPE_WHITE_TULIP => "White Tulip",
|
||||||
|
self::TYPE_PINK_TULIP => "Pink Tulip",
|
||||||
|
self::TYPE_OXEYE_DAISY => "Oxeye Daisy",
|
||||||
|
9 => "Unknown",
|
||||||
|
10 => "Unknown",
|
||||||
|
11 => "Unknown",
|
||||||
|
12 => "Unknown",
|
||||||
|
13 => "Unknown",
|
||||||
|
14 => "Unknown",
|
||||||
|
15 => "Unknown"
|
||||||
|
];
|
||||||
|
return $names[$this->meta];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
|
$down = $this->getSide(0);
|
||||||
|
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){
|
||||||
|
$this->getLevel()->setBlock($block, $this, true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onUpdate($type){
|
||||||
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
|
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||||
|
$this->getLevel()->useBreakOn($this);
|
||||||
|
|
||||||
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -23,10 +23,10 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
|
|
||||||
class Furnace extends BurningFurnace{
|
class Furnace extends BurningFurnace{
|
||||||
public function __construct($meta = 0){
|
|
||||||
parent::__construct($meta);
|
protected $id = self::FURNACE;
|
||||||
$this->id = self::FURNACE;
|
|
||||||
$this->name = "Furnace";
|
public function getName(){
|
||||||
$this->isActivable = true;
|
return "Furnace";
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,68 +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;
|
|
||||||
|
|
||||||
class Generic extends Block{
|
|
||||||
|
|
||||||
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 = [
|
|
||||||
"x" => $this->x + 0.5,
|
|
||||||
"y" => $this->y + 0.5,
|
|
||||||
"z" => $this->z + 0.5,
|
|
||||||
"Tile" => $this->id,
|
|
||||||
];
|
|
||||||
/*$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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
|
||||||
class Glass extends Transparent{
|
class Glass extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::GLASS;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::GLASS, 0, "Glass");
|
|
||||||
$this->hardness = 1.5;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Glass";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,11 +22,25 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
|
||||||
class GlassPane extends Transparent{
|
use pocketmine\item\Item;
|
||||||
|
|
||||||
|
class GlassPane extends Thin{
|
||||||
|
|
||||||
|
protected $id = self::GLASS_PANE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::GLASS_PANE, 0, "Glass Pane");
|
|
||||||
$this->isFullBlock = false;
|
|
||||||
$this->isSolid = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Glass Pane";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDrops(Item $item){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
@ -23,8 +23,19 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
|
|
||||||
class GlowingObsidian extends Solid{
|
class GlowingObsidian extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::GLOWING_OBSIDIAN;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::GLOWING_OBSIDIAN, $meta, "Glowing Obsidian");
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Glowing Obsidian";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,12 +22,31 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
|
||||||
class GlowingRedstoneOre extends Solid{
|
class GlowingRedstoneOre extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::GLOWING_REDSTONE_ORE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
|
|
||||||
$this->hardness = 15;
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Glowing Redstone Ore";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
@ -40,18 +59,6 @@ class GlowingRedstoneOre extends Solid{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
|
||||||
switch($item->isPickaxe()){
|
|
||||||
case 5:
|
|
||||||
return 0.6;
|
|
||||||
case 4:
|
|
||||||
return 0.75;
|
|
||||||
default:
|
|
||||||
return 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
if($item->isPickaxe() >= 4){
|
if($item->isPickaxe() >= 4){
|
||||||
return [
|
return [
|
||||||
|
@ -22,11 +22,30 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Glowstone extends Transparent{
|
class Glowstone extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::GLOWSTONE_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::GLOWSTONE_BLOCK, 0, "Glowstone");
|
|
||||||
$this->hardness = 1.5;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Glowstone";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,22 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Gold extends Solid{
|
class Gold extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::GOLD_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::GOLD_BLOCK, 0, "Gold Block");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "Gold Block";
|
||||||
case 5:
|
}
|
||||||
return 0.6;
|
|
||||||
case 4:
|
public function getHardness(){
|
||||||
return 0.75;
|
return 3;
|
||||||
default:
|
}
|
||||||
return 15;
|
|
||||||
}
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,22 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class GoldOre extends Solid{
|
class GoldOre extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::GOLD_ORE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::GOLD_ORE, 0, "Gold Ore");
|
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "Gold Ore";
|
||||||
case 5:
|
}
|
||||||
return 0.6;
|
|
||||||
case 4:
|
public function getHardness(){
|
||||||
return 0.75;
|
return 3;
|
||||||
default:
|
}
|
||||||
return 15;
|
|
||||||
}
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -21,25 +21,40 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\event\block\BlockSpreadEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\generator\object\TallGrass;
|
use pocketmine\item\Tool;
|
||||||
|
use pocketmine\level\generator\object\TallGrass as TallGrassObject;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\level\Position;
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\Random;
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
class Grass extends Solid{
|
class Grass extends Solid{
|
||||||
|
|
||||||
public $isActivable = true;
|
|
||||||
protected $hardness = 3;
|
|
||||||
protected $id = self::GRASS;
|
protected $id = self::GRASS;
|
||||||
protected $meta = 0;
|
|
||||||
protected $name = "Grass";
|
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canBeActivated(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Grass";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SHOVEL;
|
||||||
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
return [
|
return [
|
||||||
[Item::DIRT, 0, 1],
|
[Item::DIRT, 0, 1],
|
||||||
@ -52,26 +67,33 @@ class Grass extends Solid{
|
|||||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||||
$block = $this->getLevel()->getBlockIdAt($x, $y, $z);
|
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||||
if($block === Block::DIRT){
|
if($block->getId() === Block::DIRT){
|
||||||
$block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), new Position($x, $y, $z, $this->getLevel()));
|
|
||||||
if($block->getSide(1) instanceof Transparent){
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onActivate(Item $item, Player $player = null){
|
public function onActivate(Item $item, Player $player = null){
|
||||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){
|
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){
|
||||||
$item->count--;
|
$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;
|
return true;
|
||||||
}elseif($item->isHoe()){
|
}elseif($item->isHoe()){
|
||||||
$item->useOn($this);
|
$item->useOn($this);
|
||||||
$this->getLevel()->setBlock($this, new Farmland());
|
$this->getLevel()->setBlock($this, new Farmland());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}elseif($item->isShovel() and $this->getSide(1)->getId() === Block::AIR){
|
||||||
|
$item->useOn($this);
|
||||||
|
$this->getLevel()->setBlock($this, new GrassPath());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
71
src/pocketmine/block/GrassPath.php
Normal file
71
src/pocketmine/block/GrassPath.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?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\item\Tool;
|
||||||
|
use pocketmine\level\generator\object\TallGrass as TallGrassObject;
|
||||||
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
|
use pocketmine\math\Vector3;
|
||||||
|
use pocketmine\Player;
|
||||||
|
use pocketmine\Server;
|
||||||
|
use pocketmine\utils\Random;
|
||||||
|
|
||||||
|
class GrassPath extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::GRASS_PATH;
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Grass Path";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SHOVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function recalculateBoundingBox(){
|
||||||
|
return new AxisAlignedBB(
|
||||||
|
$this->x,
|
||||||
|
$this->y,
|
||||||
|
$this->z,
|
||||||
|
$this->x + 1,
|
||||||
|
$this->y + 0.9375,
|
||||||
|
$this->z + 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDrops(Item $item){
|
||||||
|
return [
|
||||||
|
[Item::DIRT, 0, 1],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -22,11 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Gravel extends Fallable{
|
class Gravel extends Fallable{
|
||||||
|
|
||||||
|
protected $id = self::GRAVEL;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::GRAVEL, 0, "Gravel");
|
|
||||||
$this->hardness = 3;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Gravel";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SHOVEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,28 +22,25 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class HardenedClay extends Solid{
|
class HardenedClay extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::HARDENED_CLAY;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::HARDENED_CLAY, 0, "Hardened Clay");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "Hardened Clay";
|
||||||
case 5:
|
|
||||||
return 0.25;
|
|
||||||
case 4:
|
|
||||||
return 0.35;
|
|
||||||
case 3:
|
|
||||||
return 0.5;
|
|
||||||
case 2:
|
|
||||||
return 0.2;
|
|
||||||
case 1:
|
|
||||||
return 0.95;
|
|
||||||
default:
|
|
||||||
return 6.25;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 1.25;
|
||||||
|
}
|
||||||
}
|
}
|
@ -25,9 +25,19 @@ use pocketmine\item\Item;
|
|||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class HayBale extends Solid{
|
class HayBale extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::HAY_BALE;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::HAY_BALE, $meta, "Hay Bale");
|
$this->meta = $meta;
|
||||||
$this->hardness = 10;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Hay Bale";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
@ -41,7 +51,7 @@ class HayBale extends Solid{
|
|||||||
];
|
];
|
||||||
|
|
||||||
$this->meta = ($this->meta & 0x03) | $faces[$face];
|
$this->meta = ($this->meta & 0x03) | $faces[$face];
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
$this->getLevel()->setBlock($block, $this, true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -22,36 +22,34 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Ice extends Transparent{
|
class Ice extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::ICE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::ICE, 0, "Ice");
|
|
||||||
$this->hardness = 2.5;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Ice";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onBreak(Item $item){
|
public function onBreak(Item $item){
|
||||||
$this->getLevel()->setBlock($this, new Water(), true, false, true);
|
$this->getLevel()->setBlock($this, new Water(), true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
|
||||||
switch($item->isPickaxe()){
|
|
||||||
case 5:
|
|
||||||
return 0.1;
|
|
||||||
case 4:
|
|
||||||
return 0.15;
|
|
||||||
case 3:
|
|
||||||
return 0.2;
|
|
||||||
case 2:
|
|
||||||
return 0.1;
|
|
||||||
case 1:
|
|
||||||
return 0.4;
|
|
||||||
default:
|
|
||||||
return 0.75;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -22,24 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Iron extends Solid{
|
class Iron extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::IRON_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::IRON_BLOCK, 0, "Iron Block");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "Iron Block";
|
||||||
case 5:
|
}
|
||||||
return 0.95;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 1.25;
|
return Tool::TYPE_PICKAXE;
|
||||||
case 3:
|
}
|
||||||
return 1.9;
|
|
||||||
default:
|
public function getHardness(){
|
||||||
return 25;
|
return 5;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -21,12 +21,38 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
|
class IronBars extends Thin{
|
||||||
|
|
||||||
|
protected $id = self::IRON_BARS;
|
||||||
|
|
||||||
class IronBars extends Transparent{
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::IRON_BARS, 0, "Iron Bars");
|
|
||||||
$this->isFullBlock = false;
|
|
||||||
$this->isSolid = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public function getName(){
|
||||||
|
return "Iron Bars";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDrops(Item $item){
|
||||||
|
if($item->isPickaxe() >= 1){
|
||||||
|
return [
|
||||||
|
[Item::IRON_BARS, 0, 1],
|
||||||
|
];
|
||||||
|
}else{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -22,29 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class IronDoor extends Door{
|
class IronDoor extends Door{
|
||||||
|
|
||||||
|
protected $id = self::IRON_DOOR_BLOCK;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::IRON_DOOR_BLOCK, $meta, "Iron Door Block");
|
$this->meta = $meta;
|
||||||
//$this->isActivable = true;
|
|
||||||
$this->hardness = 25;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "Iron Door Block";
|
||||||
case 5:
|
}
|
||||||
return 0.95;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 1.25;
|
return Tool::TYPE_PICKAXE;
|
||||||
case 3:
|
}
|
||||||
return 1.9;
|
|
||||||
case 2:
|
public function getHardness(){
|
||||||
return 0.65;
|
return 5;
|
||||||
case 1:
|
|
||||||
return 3.75;
|
|
||||||
default:
|
|
||||||
return 25;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,24 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class IronOre extends Solid{
|
class IronOre extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::IRON_ORE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::IRON_ORE, 0, "Iron Ore");
|
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "Iron Ore";
|
||||||
case 5:
|
}
|
||||||
return 0.6;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 0.75;
|
return Tool::TYPE_PICKAXE;
|
||||||
case 3:
|
}
|
||||||
return 1.15;
|
|
||||||
default:
|
public function getHardness(){
|
||||||
return 15;
|
return 3;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,10 +22,22 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class JungleWoodStairs extends Stair{
|
class JungleWoodStairs extends Stair{
|
||||||
|
|
||||||
|
protected $id = self::JUNGLE_WOOD_STAIRS;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::JUNGLE_WOOD_STAIRS, $meta, "Jungle Wood Stairs");
|
$this->meta = $meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Jungle Wood Stairs";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -21,25 +21,90 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\entity\Entity;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
|
use pocketmine\math\AxisAlignedBB;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class Ladder extends Transparent{
|
class Ladder extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::LADDER;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::LADDER, $meta, "Ladder");
|
$this->meta = $meta;
|
||||||
$this->isSolid = false;
|
|
||||||
$this->isFullBlock = false;
|
|
||||||
$this->hardness = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function getName(){
|
||||||
|
return "Ladder";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasEntityCollision(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSolid(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEntityCollide(Entity $entity){
|
||||||
|
$entity->resetFallDistance();
|
||||||
|
$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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
if($target->isTransparent === false){
|
if($target->isTransparent() === false){
|
||||||
$faces = [
|
$faces = [
|
||||||
2 => 2,
|
2 => 2,
|
||||||
3 => 3,
|
3 => 3,
|
||||||
@ -48,7 +113,7 @@ class Ladder extends Transparent{
|
|||||||
];
|
];
|
||||||
if(isset($faces[$face])){
|
if(isset($faces[$face])){
|
||||||
$this->meta = $faces[$face];
|
$this->meta = $faces[$face];
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
$this->getLevel()->setBlock($block, $this, true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -59,7 +124,7 @@ class Ladder extends Transparent{
|
|||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
/*if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
/*if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||||
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
|
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
|
||||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
@ -69,6 +134,10 @@ class Ladder extends Transparent{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
return [
|
return [
|
||||||
[$this->id, 0, 1],
|
[$this->id, 0, 1],
|
||||||
|
@ -22,24 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Lapis extends Solid{
|
class Lapis extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::LAPIS_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::LAPIS_BLOCK, 0, "Lapis Block");
|
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
switch($item->isPickaxe()){
|
return "Lapis Lazuli Block";
|
||||||
case 5:
|
}
|
||||||
return 0.6;
|
|
||||||
case 4:
|
public function getToolType(){
|
||||||
return 0.75;
|
return Tool::TYPE_PICKAXE;
|
||||||
case 3:
|
}
|
||||||
return 1.15;
|
|
||||||
default:
|
public function getHardness(){
|
||||||
return 15;
|
return 3;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,25 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class LapisOre extends Solid{
|
class LapisOre extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::LAPIS_ORE;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::LAPIS_ORE, 0, "Lapis Ore");
|
|
||||||
$this->hardness = 15;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getHardness(){
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
switch($item->isPickaxe()){
|
public function getToolType(){
|
||||||
case 5:
|
return Tool::TYPE_PICKAXE;
|
||||||
return 0.6;
|
}
|
||||||
case 4:
|
|
||||||
return 0.75;
|
public function getName(){
|
||||||
case 3:
|
return "Lapis Lazuli Ore";
|
||||||
return 1.15;
|
|
||||||
default:
|
|
||||||
return 15;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -21,139 +21,52 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\entity\Effect;
|
||||||
|
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\item\Item;
|
||||||
use pocketmine\level\Level;
|
|
||||||
use pocketmine\level\Position;
|
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
|
|
||||||
class Lava extends Liquid{
|
class Lava extends Liquid{
|
||||||
|
|
||||||
|
protected $id = self::LAVA;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::LAVA, $meta, "Lava");
|
$this->meta = $meta;
|
||||||
$this->hardness = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function getLightLevel(){
|
||||||
return null;
|
return 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Lava";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEntityCollide(Entity $entity){
|
||||||
|
$entity->fallDistance *= 0.5;
|
||||||
|
if(!$entity->hasEffect(Effect::FIRE_RESISTANCE)){
|
||||||
|
$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());
|
||||||
|
}
|
||||||
|
|
||||||
|
$entity->resetFallDistance();
|
||||||
|
}
|
||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
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, false);
|
||||||
$this->getLevel()->scheduleUpdate(clone $this, 40);
|
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||||
|
|
||||||
return $ret;
|
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,12 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\event\block\LeavesDecayEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class Leaves extends Transparent{
|
class Leaves extends Transparent{
|
||||||
const OAK = 0;
|
const OAK = 0;
|
||||||
@ -33,16 +36,28 @@ class Leaves extends Transparent{
|
|||||||
const ACACIA = 0;
|
const ACACIA = 0;
|
||||||
const DARK_OAK = 1;
|
const DARK_OAK = 1;
|
||||||
|
|
||||||
|
protected $id = self::LEAVES;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::LEAVES, $meta, "Leaves");
|
$this->meta = $meta;
|
||||||
$names = [
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SHEARS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
static $names = [
|
||||||
self::OAK => "Oak Leaves",
|
self::OAK => "Oak Leaves",
|
||||||
self::SPRUCE => "Spruce Leaves",
|
self::SPRUCE => "Spruce Leaves",
|
||||||
self::BIRCH => "Birch Leaves",
|
self::BIRCH => "Birch Leaves",
|
||||||
self::JUNGLE => "Jungle Leaves",
|
self::JUNGLE => "Jungle Leaves",
|
||||||
];
|
];
|
||||||
$this->name = $names[$this->meta & 0x03];
|
return $names[$this->meta & 0x03];
|
||||||
$this->hardness = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){
|
private function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){
|
||||||
@ -51,11 +66,11 @@ class Leaves extends Transparent{
|
|||||||
if(isset($visited[$index])){
|
if(isset($visited[$index])){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if($pos->getID() === self::WOOD){
|
if($pos->getId() === self::WOOD){
|
||||||
return true;
|
return true;
|
||||||
}elseif($pos->getID() === self::LEAVES and $distance < 3){
|
}elseif($pos->getId() === self::LEAVES and $distance < 3){
|
||||||
$visited[$index] = true;
|
$visited[$index] = true;
|
||||||
$down = $pos->getSide(0)->getID();
|
$down = $pos->getSide(0)->getId();
|
||||||
if($down === Item::WOOD){
|
if($down === Item::WOOD){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -121,16 +136,13 @@ class Leaves extends Transparent{
|
|||||||
$this->meta &= 0x03;
|
$this->meta &= 0x03;
|
||||||
$visited = [];
|
$visited = [];
|
||||||
$check = 0;
|
$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{
|
}else{
|
||||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
$this->getLevel()->useBreakOn($this);
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
@ -142,7 +154,7 @@ class Leaves extends Transparent{
|
|||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$this->meta |= 0x04;
|
$this->meta |= 0x04;
|
||||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
$this->getLevel()->setBlock($this, $this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -21,20 +21,26 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\event\block\LeavesDecayEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class Leaves2 extends Leaves{
|
class Leaves2 extends Leaves{
|
||||||
|
|
||||||
|
protected $id = self::LEAVES2;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
Transparent::__construct(self::LEAVES, $meta, "Leaves");
|
$this->meta = $meta;
|
||||||
$names = [
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
static $names = [
|
||||||
self::ACACIA => "Acacia Leaves",
|
self::ACACIA => "Acacia Leaves",
|
||||||
self::DARK_OAK => "Dark Oak Leaves",
|
self::DARK_OAK => "Dark Oak Leaves",
|
||||||
];
|
];
|
||||||
$this->name = $names[$this->meta & 0x03];
|
return $names[$this->meta & 0x01];
|
||||||
$this->hardness = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){
|
private function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){
|
||||||
@ -43,11 +49,11 @@ class Leaves2 extends Leaves{
|
|||||||
if(isset($visited[$index])){
|
if(isset($visited[$index])){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if($pos->getID() === self::WOOD2){
|
if($pos->getId() === self::WOOD2){
|
||||||
return true;
|
return true;
|
||||||
}elseif($pos->getID() === self::LEAVES2 and $distance < 3){
|
}elseif($pos->getId() === self::LEAVES2 and $distance < 3){
|
||||||
$visited[$index] = true;
|
$visited[$index] = true;
|
||||||
$down = $pos->getSide(0)->getID();
|
$down = $pos->getSide(0)->getId();
|
||||||
if($down === Item::WOOD2){
|
if($down === Item::WOOD2){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -113,13 +119,13 @@ class Leaves2 extends Leaves{
|
|||||||
$this->meta &= 0x03;
|
$this->meta &= 0x03;
|
||||||
$visited = [];
|
$visited = [];
|
||||||
$check = 0;
|
$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{
|
}else{
|
||||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
$this->getLevel()->useBreakOn($this);
|
||||||
if(mt_rand(1, 20) === 1){ //Saplings
|
|
||||||
$this->getLevel()->dropItem($this, Item::get($this->id, $this->meta & 0x03, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
@ -131,7 +137,7 @@ class Leaves2 extends Leaves{
|
|||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
$this->meta |= 0x04;
|
$this->meta |= 0x04;
|
||||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
$this->getLevel()->setBlock($this, $this, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,10 +22,436 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
|
||||||
class Liquid extends Transparent{
|
use pocketmine\entity\Entity;
|
||||||
public $isLiquid = true;
|
use pocketmine\item\Item;
|
||||||
public $breakable = false;
|
use pocketmine\level\Level;
|
||||||
public $isReplaceable = true;
|
use pocketmine\math\Vector3;
|
||||||
public $isSolid = false;
|
|
||||||
public $isFullBlock = true;
|
abstract class Liquid extends Transparent{
|
||||||
|
|
||||||
|
/** @var Vector3 */
|
||||||
|
private $temporalVector = null;
|
||||||
|
|
||||||
|
public function hasEntityCollision(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isBreakable(Item $item){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeReplaced(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isSolid(){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if($this->temporalVector === null){
|
||||||
|
$this->temporalVector = 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($this->temporalVector->setComponents($x, $y, $z));
|
||||||
|
$blockDecay = $this->getEffectiveFlowDecay($sideBlock);
|
||||||
|
|
||||||
|
if($blockDecay < 0){
|
||||||
|
if(!$sideBlock->canBeFlowedInto()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$blockDecay = $this->getEffectiveFlowDecay($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z)));
|
||||||
|
|
||||||
|
if($blockDecay >= 0){
|
||||||
|
$realDecay = $blockDecay - ($decay - 8);
|
||||||
|
$vector->x += ($sideBlock->x - $this->x) * $realDecay;
|
||||||
|
$vector->y += ($sideBlock->y - $this->y) * $realDecay;
|
||||||
|
$vector->z += ($sideBlock->z - $this->z) * $realDecay;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}else{
|
||||||
|
$realDecay = $blockDecay - $decay;
|
||||||
|
$vector->x += ($sideBlock->x - $this->x) * $realDecay;
|
||||||
|
$vector->y += ($sideBlock->y - $this->y) * $realDecay;
|
||||||
|
$vector->z += ($sideBlock->z - $this->z) * $realDecay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->getDamage() >= 8){
|
||||||
|
$falling = false;
|
||||||
|
|
||||||
|
if(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1))->canBeFlowedInto()){
|
||||||
|
$falling = true;
|
||||||
|
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1))->canBeFlowedInto()){
|
||||||
|
$falling = true;
|
||||||
|
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z))->canBeFlowedInto()){
|
||||||
|
$falling = true;
|
||||||
|
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z))->canBeFlowedInto()){
|
||||||
|
$falling = true;
|
||||||
|
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z - 1))->canBeFlowedInto()){
|
||||||
|
$falling = true;
|
||||||
|
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z + 1))->canBeFlowedInto()){
|
||||||
|
$falling = true;
|
||||||
|
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y + 1, $this->z))->canBeFlowedInto()){
|
||||||
|
$falling = true;
|
||||||
|
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y + 1, $this->z))->canBeFlowedInto()){
|
||||||
|
$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){
|
||||||
|
if($this->temporalVector === null){
|
||||||
|
$this->temporalVector = new Vector3(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$decay = $this->getFlowDecay($this);
|
||||||
|
$multiplier = $this instanceof Lava ? 2 : 1;
|
||||||
|
|
||||||
|
$flag = true;
|
||||||
|
|
||||||
|
if($decay > 0){
|
||||||
|
$smallestFlowDecay = -100;
|
||||||
|
$this->adjacentSources = 0;
|
||||||
|
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1)), $smallestFlowDecay);
|
||||||
|
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1)), $smallestFlowDecay);
|
||||||
|
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z)), $smallestFlowDecay);
|
||||||
|
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z)), $smallestFlowDecay);
|
||||||
|
|
||||||
|
$k = $smallestFlowDecay + $multiplier;
|
||||||
|
|
||||||
|
if($k >= 8 or $smallestFlowDecay < 0){
|
||||||
|
$k = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(($topFlowDecay = $this->getFlowDecay($this->level->getBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z))))) >= 0){
|
||||||
|
if($topFlowDecay >= 8){
|
||||||
|
$k = $topFlowDecay;
|
||||||
|
}else{
|
||||||
|
$k = $topFlowDecay | 0x08;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->adjacentSources >= 2 and $this instanceof Water){
|
||||||
|
$bottomBlock = $this->level->getBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y - 1, $this->z)));
|
||||||
|
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, new 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->level->getBlock($this->temporalVector->setComponents($this->x, $this->y - 1, $this->z));
|
||||||
|
|
||||||
|
if($bottomBlock->canBeFlowedInto() 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->canBeFlowedInto())){
|
||||||
|
$flags = $this->getOptimalFlowDirections();
|
||||||
|
|
||||||
|
$l = $decay + $multiplier;
|
||||||
|
|
||||||
|
if($decay >= 8){
|
||||||
|
$l = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($l >= 8){
|
||||||
|
$this->checkForHarden();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($flags[0]){
|
||||||
|
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z)), $l);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($flags[1]){
|
||||||
|
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z)), $l);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($flags[2]){
|
||||||
|
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1)), $l);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($flags[3]){
|
||||||
|
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1)), $l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->checkForHarden();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function flowIntoBlock(Block $block, $newFlowDecay){
|
||||||
|
if($block->canBeFlowedInto()){
|
||||||
|
if($block->getId() > 0){
|
||||||
|
$this->getLevel()->useBreakOn($block);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getLevel()->setBlock($block, Block::get($this->getId(), $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($this->temporalVector->setComponents($x, $y, $z));
|
||||||
|
|
||||||
|
if(!$blockSide->canBeFlowedInto() and !($blockSide instanceof Liquid)){
|
||||||
|
continue;
|
||||||
|
}elseif($blockSide instanceof Liquid and $blockSide->getDamage() === 0){
|
||||||
|
continue;
|
||||||
|
}elseif($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z))->canBeFlowedInto()){
|
||||||
|
return $accumulatedCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($accumulatedCost >= 4){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$realCost = $this->calculateFlowCost($blockSide, $accumulatedCost + 1, $j);
|
||||||
|
|
||||||
|
if($realCost < $cost){
|
||||||
|
$cost = $realCost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getOptimalFlowDirections(){
|
||||||
|
if($this->temporalVector === null){
|
||||||
|
$this->temporalVector = new Vector3(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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($this->temporalVector->setComponents($x, $y, $z));
|
||||||
|
|
||||||
|
if(!$block->canBeFlowedInto() and !($block instanceof Liquid)){
|
||||||
|
continue;
|
||||||
|
}elseif($block instanceof Liquid and $block->getDamage() === 0){
|
||||||
|
continue;
|
||||||
|
}elseif($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z))->canBeFlowedInto()){
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDrops(Item $item){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,19 +22,38 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
|
||||||
class LitPumpkin extends Solid{
|
class LitPumpkin extends Solid{
|
||||||
public function __construct(){
|
|
||||||
parent::__construct(self::LIT_PUMPKIN, "Jack o'Lantern");
|
protected $id = self::LIT_PUMPKIN;
|
||||||
$this->hardness = 5;
|
|
||||||
|
public function getLightLevel(){
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Jack o'Lantern";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct($meta = 0){
|
||||||
|
$this->meta = $meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||||
if($player instanceof Player){
|
if($player instanceof Player){
|
||||||
$this->meta = (int) $player->getDirection();
|
$this->meta = ((int) $player->getDirection() + 5) % 4;
|
||||||
}
|
}
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
$this->getLevel()->setBlock($block, $this, true, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Melon extends Transparent{
|
class Melon extends Transparent{
|
||||||
|
|
||||||
|
protected $id = self::MELON_BLOCK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::MELON_BLOCK, 0, "Melon Block");
|
|
||||||
$this->hardness = 5;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Melon Block";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_AXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -21,59 +21,54 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\event\block\BlockGrowEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\Player;
|
use pocketmine\Server;
|
||||||
|
|
||||||
|
class MelonStem extends Crops{
|
||||||
|
|
||||||
|
protected $id = self::MELON_STEM;
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Melon Stem";
|
||||||
|
}
|
||||||
|
|
||||||
class MelonStem extends Flowable{
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::MELON_STEM, $meta, "Melon Stem");
|
$this->meta = $meta;
|
||||||
$this->isActivable = true;
|
|
||||||
$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() === self::FARMLAND){
|
|
||||||
$this->getLevel()->setBlock($block, $this, true, false, true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onUpdate($type){
|
public function onUpdate($type){
|
||||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||||
if($this->getSide(0)->isTransparent === true){ //TODO: Replace with common break method
|
if($this->getSide(0)->isTransparent() === true){
|
||||||
$this->getLevel()->dropItem($this, Item::get(Item::MELON_SEEDS, 0, mt_rand(0, 2)));
|
$this->getLevel()->useBreakOn($this);
|
||||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
|
||||||
|
|
||||||
return Level::BLOCK_UPDATE_NORMAL;
|
return Level::BLOCK_UPDATE_NORMAL;
|
||||||
}
|
}
|
||||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||||
if(mt_rand(0, 2) == 1){
|
if(mt_rand(0, 2) == 1){
|
||||||
if($this->meta < 0x07){
|
if($this->meta < 0x07){
|
||||||
++$this->meta;
|
$block = clone $this;
|
||||||
$this->getLevel()->setBlock($this, $this, true, false, true);
|
++$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;
|
return Level::BLOCK_UPDATE_RANDOM;
|
||||||
}else{
|
}else{
|
||||||
for($side = 2; $side <= 5; ++$side){
|
for($side = 2; $side <= 5; ++$side){
|
||||||
$b = $this->getSide($side);
|
$b = $this->getSide($side);
|
||||||
if($b->getID() === self::MELON_BLOCK){
|
if($b->getId() === self::MELON_BLOCK){
|
||||||
return Level::BLOCK_UPDATE_RANDOM;
|
return Level::BLOCK_UPDATE_RANDOM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$side = $this->getSide(mt_rand(2, 5));
|
$side = $this->getSide(mt_rand(2, 5));
|
||||||
$d = $side->getSide(0);
|
$d = $side->getSide(0);
|
||||||
if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,20 +79,6 @@ class MelonStem extends Flowable{
|
|||||||
return false;
|
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){
|
public function getDrops(Item $item){
|
||||||
return [
|
return [
|
||||||
[Item::MELON_SEEDS, 0, mt_rand(0, 2)],
|
[Item::MELON_SEEDS, 0, mt_rand(0, 2)],
|
||||||
|
@ -22,31 +22,29 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class MonsterSpawner extends Solid{
|
class MonsterSpawner extends Solid{
|
||||||
public function __construct(){
|
|
||||||
parent::__construct(self::MONSTER_SPAWNER, 0, "Monster Spawner");
|
protected $id = self::MONSTER_SPAWNER;
|
||||||
$this->hardness = 25;
|
|
||||||
|
public function __construct($meta = 0){
|
||||||
|
$this->meta = $meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getHardness(){
|
||||||
switch($item->isPickaxe()){
|
return 5;
|
||||||
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){
|
public function getToolType(){
|
||||||
return [];
|
return Tool::TYPE_PICKAXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Monster Spawner";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDrops(Item $item){
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,29 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class MossStone extends Solid{
|
class MossStone extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::MOSS_STONE;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::MOSS_STONE, $meta, "Moss Stone");
|
$this->meta = $meta;
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
|
return "Moss Stone";
|
||||||
|
}
|
||||||
|
|
||||||
switch($item->isPickaxe()){
|
public function getHardness(){
|
||||||
case 5:
|
return 2;
|
||||||
return 0.4;
|
}
|
||||||
case 4:
|
|
||||||
return 0.5;
|
public function getToolType(){
|
||||||
case 3:
|
return Tool::TYPE_PICKAXE;
|
||||||
return 0.75;
|
|
||||||
case 2:
|
|
||||||
return 0.25;
|
|
||||||
case 1:
|
|
||||||
return 1.5;
|
|
||||||
default:
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -21,14 +21,31 @@
|
|||||||
|
|
||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
use pocketmine\event\block\BlockSpreadEvent;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
use pocketmine\level\Level;
|
use pocketmine\level\Level;
|
||||||
use pocketmine\level\Position;
|
use pocketmine\math\Vector3;
|
||||||
|
use pocketmine\Server;
|
||||||
|
|
||||||
class Mycelium extends Solid{
|
class Mycelium extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::MYCELIUM;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::MYCELIUM, 0, "Mycelium");
|
|
||||||
$this->hardness = 2.5;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Mycelium";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_SHOVEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
@ -43,11 +60,13 @@ class Mycelium extends Solid{
|
|||||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||||
$block = $this->getLevel()->getBlockIdAt($x, $y, $z);
|
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||||
if($block === Block::DIRT){
|
if($block->getId() === Block::DIRT){
|
||||||
$block = Block::get($block, $this->getLevel()->getBlockDataAt($x, $y, $z), new Position($x, $y, $z, $this->getLevel()));
|
|
||||||
if($block->getSide(1) instanceof Transparent){
|
if($block->getSide(1) instanceof Transparent){
|
||||||
$this->getLevel()->setBlock($block, new Mycelium());
|
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Mycelium()));
|
||||||
|
if(!$ev->isCancelled()){
|
||||||
|
$this->getLevel()->setBlock($block, $ev->getNewState());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,29 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class NetherBrick extends Solid{
|
class NetherBrick extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::NETHER_BRICKS;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::NETHER_BRICKS, 0, "Nether Bricks");
|
|
||||||
$this->hardness = 30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
switch($item->isPickaxe()){
|
public function getName(){
|
||||||
case 5:
|
return "Nether Bricks";
|
||||||
return 0.4;
|
}
|
||||||
case 4:
|
|
||||||
return 0.5;
|
public function getHardness(){
|
||||||
case 3:
|
return 2;
|
||||||
return 0.75;
|
|
||||||
case 2:
|
|
||||||
return 0.25;
|
|
||||||
case 1:
|
|
||||||
return 1.5;
|
|
||||||
default:
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
@ -22,9 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
|
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class NetherBrickStairs extends Stair{
|
class NetherBrickStairs extends Stair{
|
||||||
|
|
||||||
|
protected $id = self::NETHER_BRICKS_STAIRS;
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Nether Bricks Stairs";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHardness(){
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getToolType(){
|
||||||
|
return Tool::TYPE_PICKAXE;
|
||||||
|
}
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::NETHER_BRICKS_STAIRS, $meta, "Nether Bricks Stairs");
|
$this->meta = $meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -23,9 +23,19 @@ namespace pocketmine\block;
|
|||||||
|
|
||||||
|
|
||||||
class NetherReactor extends Solid{
|
class NetherReactor extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::NETHER_REACTOR;
|
||||||
|
|
||||||
public function __construct($meta = 0){
|
public function __construct($meta = 0){
|
||||||
parent::__construct(self::NETHER_REACTOR, $meta, "Nether Reactor");
|
$this->meta = $meta;
|
||||||
$this->isActivable = true;
|
}
|
||||||
|
|
||||||
|
public function getName(){
|
||||||
|
return "Nether Reactor";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeActivated(){
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -22,29 +22,26 @@
|
|||||||
namespace pocketmine\block;
|
namespace pocketmine\block;
|
||||||
|
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\item\Tool;
|
||||||
|
|
||||||
class Netherrack extends Solid{
|
class Netherrack extends Solid{
|
||||||
|
|
||||||
|
protected $id = self::NETHERRACK;
|
||||||
|
|
||||||
public function __construct(){
|
public function __construct(){
|
||||||
parent::__construct(self::NETHERRACK, 0, "Netherrack");
|
|
||||||
$this->hardness = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBreakTime(Item $item){
|
public function getName(){
|
||||||
|
return "Netherrack";
|
||||||
|
}
|
||||||
|
|
||||||
switch($item->isPickaxe()){
|
public function getHardness(){
|
||||||
case 5:
|
return 2;
|
||||||
return 0.1;
|
}
|
||||||
case 4:
|
|
||||||
return 0.1;
|
public function getToolType(){
|
||||||
case 3:
|
return Tool::TYPE_PICKAXE;
|
||||||
return 0.15;
|
|
||||||
case 2:
|
|
||||||
return 0.05;
|
|
||||||
case 1:
|
|
||||||
return 0.3;
|
|
||||||
default:
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDrops(Item $item){
|
public function getDrops(Item $item){
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user