mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 19:02:59 +00:00
Compare commits
639 Commits
4.23.4
...
5.0.0-ALPH
Author | SHA1 | Date | |
---|---|---|---|
9a67fbf27a | |||
94ffef1a99 | |||
2feb9ca903 | |||
50b8d39aba | |||
42df1a5c70 | |||
0e0f5e85eb | |||
55a48e0c84 | |||
c2f6d8139a | |||
ceff230d73 | |||
e6f1cb69d1 | |||
4c3892b2d6 | |||
75f74454c6 | |||
7611155ff9 | |||
c0f3dbdd70 | |||
aacd92bf08 | |||
caebe14dab | |||
cb10360c20 | |||
082f9e1647 | |||
d891646d0a | |||
886b40a455 | |||
525f62e1e4 | |||
2d56aa50b9 | |||
5d0388e747 | |||
074e7586cb | |||
2f12bb9943 | |||
433b0ca6cc | |||
da5302ca86 | |||
6b7a4e2c41 | |||
e9b994cbc3 | |||
0e15a8698a | |||
d3fff4e0b2 | |||
aeb26141b2 | |||
2f283678c7 | |||
5226300b99 | |||
0f81b7be15 | |||
2b987b450b | |||
0975da57d6 | |||
f56339c306 | |||
2cd8e4d270 | |||
0a3ecfdae9 | |||
2f469ef4a0 | |||
cbaff1caec | |||
92896c78da | |||
5aa8b953a8 | |||
375ec8e00c | |||
002f7d6826 | |||
06ad1a2d2b | |||
222415859a | |||
14b250c63f | |||
07a30ea1f9 | |||
b8f6b66e42 | |||
365cce9d0c | |||
41e60cb62c | |||
5d2ac214a8 | |||
023010370b | |||
de3ba00684 | |||
072a9202ef | |||
7314151c47 | |||
7abfc46567 | |||
3a13f5cf5f | |||
d9b8251f7b | |||
c55e23a2c6 | |||
5c2ed210fc | |||
950eddf405 | |||
69967a0e55 | |||
0132ff47cb | |||
8909aa6a18 | |||
a14346e98c | |||
b76265cd37 | |||
6dd006e730 | |||
b57fcb52d4 | |||
2c20b20ad2 | |||
a4494a2133 | |||
ecd8f151f1 | |||
c671d8a80b | |||
ca1f1bf09f | |||
9c391a6809 | |||
545d18eea7 | |||
9b4b960eb2 | |||
c5ca0857ee | |||
c2918709a3 | |||
85231215e7 | |||
42db3abf5e | |||
2da9b76452 | |||
c79806eaf0 | |||
7ac6bd79a9 | |||
6b8b7311f0 | |||
f173b91ca1 | |||
9796dfd4d9 | |||
c1ba735c9e | |||
8fd4918429 | |||
c89df7eb1c | |||
a8edb92565 | |||
133884da72 | |||
b4c7d33388 | |||
d37841c214 | |||
2a81a421f3 | |||
f8cc015c51 | |||
b3473960b4 | |||
044d35956e | |||
da4315df05 | |||
83bfe790fa | |||
16f90f4120 | |||
ec59dc1c80 | |||
973b8130db | |||
f38b15cf83 | |||
0efd928db6 | |||
9809909072 | |||
de3af9e660 | |||
a30c649607 | |||
d7ebabd771 | |||
be1087c071 | |||
b27c47335c | |||
58eec637c1 | |||
4f86ea9933 | |||
6e2685cbbb | |||
44e288554a | |||
ffa88aff67 | |||
1785cbb6b5 | |||
3d75094874 | |||
ba4d038972 | |||
4d79aced07 | |||
84f9136b95 | |||
8e600b4a78 | |||
18c2e90574 | |||
142ccc7e87 | |||
ca3b5c38b7 | |||
bc8def3be1 | |||
28d8526d8d | |||
8f20b9da91 | |||
b0c6e8d8e0 | |||
d03caafc2b | |||
b6982a84ef | |||
d634b3de18 | |||
fdb07cdbcd | |||
3b6ff3c42b | |||
23ae0c7cac | |||
1bc5e225ab | |||
858d3dce8e | |||
34839da757 | |||
b3b8516661 | |||
90305a0b92 | |||
613ce251c5 | |||
a205d64732 | |||
1a5cc8212c | |||
68e862b6fa | |||
c915334c2b | |||
01bad344a0 | |||
d9638cef96 | |||
fba4895a17 | |||
d1d5020c53 | |||
9f6c6b2b71 | |||
bd01a919e5 | |||
53cae8911d | |||
b70f7afbd6 | |||
92783a6db9 | |||
e1b0e00c6f | |||
774df0fa4c | |||
f88ae93897 | |||
8dc0d506f4 | |||
8c651ce4b4 | |||
db7cee6f22 | |||
1c6a2b66f7 | |||
0edf2ea6a4 | |||
1366a43c22 | |||
383dc2a2b9 | |||
4b41b2f9ae | |||
a6cc611e9f | |||
6f4ea886b0 | |||
ab0202ba29 | |||
9295afe8b9 | |||
1bc8fb1851 | |||
f6a9949942 | |||
18c9ccb01c | |||
b6289e5807 | |||
24ac543313 | |||
1609b11c8e | |||
cf9610c710 | |||
590eb74703 | |||
c24370b8ac | |||
b39eaaf91f | |||
2a982d48ad | |||
f80ffd8de0 | |||
d5762d3f44 | |||
5c5d96d00b | |||
4dabac8420 | |||
7fd4c12ea1 | |||
4bd2325828 | |||
64ac20173b | |||
ca3612e4ff | |||
6799dcff51 | |||
d4c4ae3d7a | |||
fedd541663 | |||
1ecb10acba | |||
6e8f11d5e8 | |||
b65e0f64f6 | |||
223de3ad23 | |||
8e97e9dcda | |||
304bb84af2 | |||
cb020988d4 | |||
eeb95872ea | |||
1b0d353fa3 | |||
d4f96a155a | |||
43a3151de3 | |||
bf4f6e5d53 | |||
f1c571a528 | |||
723ae9eca0 | |||
79125b8426 | |||
6ba3b39541 | |||
f4de4bd971 | |||
c8a8e33fc1 | |||
e3640907ba | |||
d9b050fb68 | |||
817591910b | |||
6a2315a63d | |||
89b784734e | |||
b751207969 | |||
cffa3b8a72 | |||
91e91b1d9f | |||
102406ee79 | |||
4419161a49 | |||
38e495babf | |||
17635e770b | |||
b13f333b2e | |||
a7313ed9d9 | |||
bedf79e2cd | |||
f6c9bf5cd1 | |||
2d2df22ee7 | |||
47adcf763d | |||
67682cbf27 | |||
c1acf44337 | |||
466307a43f | |||
44c4118080 | |||
2fa92e5e02 | |||
fa201b081c | |||
de3bbb71fa | |||
eccfb3bbe2 | |||
87b840ff97 | |||
f64e306fb8 | |||
9a8902d1fe | |||
b36b65927c | |||
afaf9dbc88 | |||
b0a492c063 | |||
6d4279671e | |||
cf34f88a67 | |||
b8d1b00985 | |||
8660dfe576 | |||
172bd9a129 | |||
012b668537 | |||
4f2f9b4352 | |||
b3f8b5ff37 | |||
81edb1bed4 | |||
d0ff6d2e36 | |||
4afd3dcabf | |||
c7f5215a51 | |||
66f2116e57 | |||
c15c59ae0d | |||
07786dc4bc | |||
259f44e57c | |||
e5804df24b | |||
c8320fe849 | |||
21ed5a450f | |||
ba2baba7cc | |||
d4f4fda442 | |||
b4ce5ed515 | |||
eb8fb63409 | |||
91719051e2 | |||
d321094081 | |||
323d31005f | |||
0c7370e564 | |||
3dd4c42fd3 | |||
7dd8876515 | |||
d0067cfac5 | |||
eafc23c756 | |||
20cb67461f | |||
8b2d941502 | |||
dea0207e4e | |||
32f9fcd4e9 | |||
2ba51567d8 | |||
14933a731b | |||
a22276e679 | |||
260e54e4b1 | |||
a44c089f98 | |||
5e70ae2066 | |||
ad7528e3f3 | |||
99ff78a8a5 | |||
9ffee7cfc3 | |||
ccb3c3cb05 | |||
151f2c3f3a | |||
66d655731a | |||
54a773be0c | |||
d894c5e97f | |||
419b21281d | |||
56e6a55645 | |||
c67e42a723 | |||
3e4f01d85e | |||
da9937933b | |||
2142eb3cc9 | |||
690efb09e3 | |||
e4d24e1edd | |||
4d6fb2b925 | |||
976502e3db | |||
b0c76f4db5 | |||
8886a023f1 | |||
ae70c63798 | |||
986daab511 | |||
eb404bddb4 | |||
30079f6fd0 | |||
ce87424336 | |||
06d3fc2880 | |||
d40e864821 | |||
88a5a95479 | |||
00db73a5b2 | |||
a377795db9 | |||
a8728a02f6 | |||
dc8f65c0dd | |||
5c4288de01 | |||
46b79fbe85 | |||
494cb580f3 | |||
64e93ae4e1 | |||
fe93609c8d | |||
ebe6782295 | |||
638d03846c | |||
f57cd95ad5 | |||
d725ded7b6 | |||
a8dae96bb0 | |||
e5b038ebcd | |||
a005cd6e33 | |||
5536672e4b | |||
a42bb9626d | |||
3c017af6a0 | |||
412dcaa744 | |||
51ce358734 | |||
d09c45e362 | |||
86d2ecfaff | |||
68cbe46600 | |||
c5282b059b | |||
4e71cc7d79 | |||
6be92ea6f7 | |||
325f1cf82e | |||
1714e2fd35 | |||
0a23e91329 | |||
a059d03b37 | |||
bd773c2f84 | |||
d9544b5d0e | |||
4909c0f257 | |||
56cf59355f | |||
9f0b32e748 | |||
59c5770cf2 | |||
45be6e19f3 | |||
405e552efd | |||
e44a291697 | |||
d9c61f0492 | |||
afd37ca892 | |||
03b8077054 | |||
17abd50f69 | |||
2c33d8429e | |||
cbebb70af6 | |||
6604d22ceb | |||
ce59228688 | |||
386c385a08 | |||
dd615c775d | |||
6176f0d9df | |||
33eef99d1f | |||
3e7d34c8ad | |||
e302e5a85f | |||
4acf7aadbd | |||
227a481473 | |||
a3016abf53 | |||
89632f3514 | |||
c7ba791ff8 | |||
db9c7de35c | |||
017ebb9b47 | |||
3f937605ac | |||
b818ed0d08 | |||
0e0b858b69 | |||
0d0296d535 | |||
2a0fade893 | |||
30149c6ed4 | |||
c84033213f | |||
c4fc352db1 | |||
172214386a | |||
b661c94915 | |||
7750f9581a | |||
451971b866 | |||
d49597fe5f | |||
bcdbb09c2c | |||
ff90c83d66 | |||
248eacd042 | |||
7430e1fbc0 | |||
b125d4d25f | |||
323c563684 | |||
9740891a2f | |||
b5914f4587 | |||
3792ef5a50 | |||
7994da07be | |||
8858b16a25 | |||
a64adbfffe | |||
ba079bd9aa | |||
db2b523762 | |||
4bd087fc83 | |||
af8f2c47f3 | |||
2a0b500010 | |||
c22a840d27 | |||
f8547ad57c | |||
cab56b0479 | |||
ff96f1b93c | |||
09c1e161e0 | |||
66c09fdc3b | |||
4d9f2bc9b1 | |||
de917afc6f | |||
5e4e5147d9 | |||
8831dff61b | |||
83c46a4b54 | |||
ea3d5ac563 | |||
ce6b09291a | |||
2cb722b674 | |||
dd63681f94 | |||
56428e8a4e | |||
6058032807 | |||
c0e178c19c | |||
541a624d48 | |||
2fd9b751b6 | |||
7deee31502 | |||
0afb67be7d | |||
bedc9cf518 | |||
b61a934c9f | |||
65ed7d7794 | |||
55cb68e5b5 | |||
bc5a600d59 | |||
3d61345543 | |||
b56d049103 | |||
27d7672273 | |||
db8bf672f0 | |||
f57e02849a | |||
03fdbd9f7b | |||
1da4c45979 | |||
b9542b4908 | |||
00b4e4016c | |||
cac72d73fb | |||
b268818eda | |||
e3a9324e8d | |||
8e002fc1ca | |||
61da920db0 | |||
1bce583cf3 | |||
5f7521027e | |||
f24f2d9ca9 | |||
be2fe160b3 | |||
8b80c70b9c | |||
9cc24c2c39 | |||
04b855235a | |||
72d8b54188 | |||
1c689b10b9 | |||
82f9a25d88 | |||
8822bdbefa | |||
21cf3813be | |||
adf8a61814 | |||
6964012464 | |||
5ed75731f2 | |||
d8bba6ed3d | |||
0da174842e | |||
1533fcf8f6 | |||
301b0aba82 | |||
c8e318df8c | |||
4aa1a3da8b | |||
680615eed8 | |||
1da6202e6e | |||
831738b29c | |||
e78f20391e | |||
0a22e4606d | |||
0bb30b6201 | |||
bd2516eded | |||
e956cfed1c | |||
cf7d42b3ea | |||
1ff69136a3 | |||
aa9f8781ff | |||
1f8009954c | |||
3a9e4bc357 | |||
3ce1be2a23 | |||
fe4ff3325b | |||
c29e23b2f1 | |||
57132204ec | |||
860fa719b2 | |||
c89f7f8e5e | |||
13bb1c26fb | |||
86e7ae341f | |||
93124c79ea | |||
08fbf92d8d | |||
f08f82edfd | |||
b57f0a2b7e | |||
5c85aa6e58 | |||
02568bb049 | |||
d2613039ed | |||
f97c22c341 | |||
2a24982bc4 | |||
f2dc9187f0 | |||
5a43db1c6d | |||
dab7686656 | |||
38cf9fc6e6 | |||
083a35f970 | |||
01af70f671 | |||
23695fb900 | |||
2bb99fa677 | |||
7b8eeb42f6 | |||
2029e3be20 | |||
6ee551c5e1 | |||
b7e2b3e94a | |||
f3c9b59856 | |||
ef15dc883a | |||
bf199d3a74 | |||
bd8dd48dee | |||
adfabca684 | |||
776b8d2f95 | |||
2b27b8a230 | |||
383be5426e | |||
81b51c0791 | |||
d8dc32ec4b | |||
0fc24c94cd | |||
24bd403e23 | |||
81eafde074 | |||
a2ea0cea86 | |||
5ce5e1d2b0 | |||
901a51a9dd | |||
567bd8e330 | |||
03c505aaa7 | |||
f67104c81e | |||
68491be847 | |||
d807840d57 | |||
2f2ffe0aa4 | |||
4430f6c5fd | |||
a75bc5d537 | |||
643556a366 | |||
1a598bdfd8 | |||
e27f80fd85 | |||
d922f003f6 | |||
d17032dd8c | |||
4c03aabe0f | |||
3ae9341c52 | |||
d10d660a4d | |||
107b0e1728 | |||
7769857f6a | |||
cb97f37d13 | |||
6c92e73b46 | |||
c1a01e91bf | |||
60d3bddfbc | |||
0326c4964b | |||
37f0ccdb7e | |||
43e61336cf | |||
e383f6d8f8 | |||
6dbfdd970f | |||
cfea0dac76 | |||
be863015bf | |||
8edf2c4507 | |||
42474c14aa | |||
63b2e7cc4f | |||
3edb735850 | |||
eafbc3a468 | |||
c1c3475e5a | |||
ede9e78fbd | |||
4c433fd75b | |||
53c2c4939e | |||
993adc8c82 | |||
9f4418e01d | |||
8bf1fb7b1d | |||
3c5300556a | |||
334c9daa6a | |||
b52bb5016c | |||
310104f786 | |||
ed95679953 | |||
a95749f968 | |||
5415ca2fa9 | |||
e98cf39b47 | |||
dda2f42e59 | |||
bc46e148df | |||
169a3217de | |||
905eee3198 | |||
8a11ed70e3 | |||
db9d769db6 | |||
45150f1a52 | |||
0f07b2499c | |||
0a0383d9bd | |||
1b3e50d0a3 | |||
dc5ddf1c1b | |||
03cf635adc | |||
77ba8b81f8 | |||
0ce3f763db | |||
0226f5466c | |||
166ffe430a | |||
1905f87942 | |||
c2d3b23449 | |||
fe2c3d08a0 | |||
7a0f62ce5a | |||
e58b3ba46c | |||
dd3b79b142 | |||
863f9560b0 | |||
f870568e62 | |||
9e03136861 | |||
1b48603d07 | |||
4e6fb4b12c | |||
d55eed803d | |||
8f5813b003 | |||
337aab4f0d | |||
1155f91574 | |||
9fbb2ef46a | |||
4d88f8f7f4 | |||
f33633efcb | |||
324d203f4e | |||
0cc997f531 | |||
f85f2cae98 | |||
6644fd472c | |||
101b71ed02 | |||
e808b7aac4 | |||
f4f4ea1483 | |||
979f6f3d57 | |||
cab9b6c862 | |||
4d935aa8b6 | |||
ccfe485c06 | |||
1a800cf4df | |||
fe7d942500 | |||
f323e3c43f | |||
40e46dbca2 | |||
7d70865db0 | |||
dbe99e5821 | |||
25fdf7e442 | |||
a91e7f7202 | |||
cdafb1b0c4 | |||
69db9f8a30 | |||
c4228edf3c | |||
03e3ecdbd3 | |||
0626edbcdd | |||
d03f4d76a2 | |||
710201fd51 | |||
ab5a7b0d04 | |||
440a48b973 | |||
f01887fb1e | |||
d6dfcb11e8 | |||
8a84f87879 | |||
57341d8a1b | |||
40cf66a730 |
13
.github/workflows/main.yml
vendored
13
.github/workflows/main.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "4"
|
||||
pm-version-major: "5"
|
||||
|
||||
phpstan:
|
||||
name: PHPStan analysis
|
||||
@ -43,7 +43,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "4"
|
||||
pm-version-major: "5"
|
||||
|
||||
- name: Install Composer
|
||||
run: curl -sS https://getcomposer.org/installer | php
|
||||
@ -82,7 +82,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "4"
|
||||
pm-version-major: "5"
|
||||
|
||||
- name: Install Composer
|
||||
run: curl -sS https://getcomposer.org/installer | php
|
||||
@ -123,7 +123,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "4"
|
||||
pm-version-major: "5"
|
||||
|
||||
- name: Install Composer
|
||||
run: curl -sS https://getcomposer.org/installer | php
|
||||
@ -162,7 +162,7 @@ jobs:
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
pm-version-major: "4"
|
||||
pm-version-major: "5"
|
||||
|
||||
- name: Install Composer
|
||||
run: curl -sS https://getcomposer.org/installer | php
|
||||
@ -186,6 +186,9 @@ jobs:
|
||||
- name: Regenerate KnownTranslation APIs
|
||||
run: php build/generate-known-translation-apis.php
|
||||
|
||||
- name: Regenerate RuntimeEnum(De)serializer
|
||||
run: php build/generate-runtime-enum-serializers.php
|
||||
|
||||
- name: Verify code is unchanged
|
||||
run: |
|
||||
git diff
|
||||
|
197
build/generate-block-serializer-consts.php
Normal file
197
build/generate-block-serializer-consts.php
Normal file
@ -0,0 +1,197 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\build\generate_block_serializer_consts;
|
||||
|
||||
use pocketmine\data\bedrock\block\BlockStateData;
|
||||
use pocketmine\data\bedrock\block\BlockStateNames;
|
||||
use pocketmine\data\bedrock\block\BlockStateStringValues;
|
||||
use pocketmine\data\bedrock\block\BlockTypeNames;
|
||||
use pocketmine\errorhandler\ErrorToExceptionHandler;
|
||||
use pocketmine\nbt\NbtException;
|
||||
use pocketmine\network\mcpe\convert\BlockStateDictionary;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\Utils;
|
||||
use function array_values;
|
||||
use function asort;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function explode;
|
||||
use function fclose;
|
||||
use function file_get_contents;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function is_string;
|
||||
use function ksort;
|
||||
use function mb_strtoupper;
|
||||
use function sort;
|
||||
use function strrpos;
|
||||
use function strtoupper;
|
||||
use function substr;
|
||||
use const SORT_STRING;
|
||||
use const STDERR;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
class BlockPaletteReport{
|
||||
/**
|
||||
* @var string[]
|
||||
* @phpstan-var array<string, string>
|
||||
*/
|
||||
public array $seenTypes = [];
|
||||
/**
|
||||
* @var string[][]
|
||||
* @phpstan-var array<string, array<mixed, mixed>>
|
||||
*/
|
||||
public array $seenStateValues = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BlockStateData[] $states
|
||||
* @phpstan-param list<BlockStateData> $states
|
||||
*/
|
||||
function generateBlockPaletteReport(array $states) : BlockPaletteReport{
|
||||
$result = new BlockPaletteReport();
|
||||
|
||||
foreach($states as $stateData){
|
||||
$name = $stateData->getName();
|
||||
$result->seenTypes[$name] = $name;
|
||||
foreach(Utils::stringifyKeys($stateData->getStates()) as $k => $v){
|
||||
$result->seenStateValues[$k][$v->getValue()] = $v->getValue();
|
||||
asort($result->seenStateValues[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
ksort($result->seenTypes, SORT_STRING);
|
||||
ksort($result->seenStateValues, SORT_STRING);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function constifyMcId(string $id) : string{
|
||||
return strtoupper(explode(":", $id, 2)[1]);
|
||||
}
|
||||
|
||||
function generateClassHeader(string $className) : string{
|
||||
$backslashPos = strrpos($className, "\\");
|
||||
if($backslashPos === false){
|
||||
throw new AssumptionFailedError("Expected a namespaced class FQN");
|
||||
}
|
||||
$namespace = substr($className, 0, $backslashPos);
|
||||
$shortName = substr($className, $backslashPos + 1);
|
||||
return <<<HEADER
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace $namespace;
|
||||
|
||||
/**
|
||||
* This class is generated automatically from the block palette for the current version. Do not edit it manually.
|
||||
*/
|
||||
final class $shortName{
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
|
||||
HEADER;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param list<string> $seenIds
|
||||
*/
|
||||
function generateBlockIds(array $seenIds) : void{
|
||||
$output = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen(dirname(__DIR__) . '/src/data/bedrock/block/BlockTypeNames.php', 'wb'));
|
||||
|
||||
fwrite($output, generateClassHeader(BlockTypeNames::class));
|
||||
|
||||
foreach($seenIds as $id){
|
||||
fwrite($output, "\tpublic const " . constifyMcId($id) . " = \"" . $id . "\";\n");
|
||||
}
|
||||
|
||||
fwrite($output, "}\n");
|
||||
fclose($output);
|
||||
}
|
||||
|
||||
function generateBlockStateNames(BlockPaletteReport $data) : void{
|
||||
$output = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen(dirname(__DIR__) . '/src/data/bedrock/block/BlockStateNames.php', 'wb'));
|
||||
|
||||
fwrite($output, generateClassHeader(BlockStateNames::class));
|
||||
foreach(Utils::stringifyKeys($data->seenStateValues) as $state => $values){
|
||||
$constName = mb_strtoupper($state, 'US-ASCII');
|
||||
fwrite($output, "\tpublic const $constName = \"$state\";\n");
|
||||
}
|
||||
|
||||
fwrite($output, "}\n");
|
||||
fclose($output);
|
||||
}
|
||||
|
||||
function generateBlockStringValues(BlockPaletteReport $data) : void{
|
||||
$output = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen(dirname(__DIR__) . '/src/data/bedrock/block/BlockStateStringValues.php', 'wb'));
|
||||
|
||||
fwrite($output, generateClassHeader(BlockStateStringValues::class));
|
||||
foreach(Utils::stringifyKeys($data->seenStateValues) as $stateName => $values){
|
||||
$anyWritten = false;
|
||||
sort($values, SORT_STRING);
|
||||
foreach($values as $value){
|
||||
if(!is_string($value)){
|
||||
continue;
|
||||
}
|
||||
$anyWritten = true;
|
||||
$constName = mb_strtoupper($stateName . "_" . $value, 'US-ASCII');
|
||||
fwrite($output, "\tpublic const $constName = \"$value\";\n");
|
||||
}
|
||||
if($anyWritten){
|
||||
fwrite($output, "\n");
|
||||
}
|
||||
}
|
||||
fwrite($output, "}\n");
|
||||
fclose($output);
|
||||
}
|
||||
|
||||
if(count($argv) !== 2){
|
||||
fwrite(STDERR, "This script regenerates BlockTypeNames, BlockStateNames and BlockStateStringValues from a given palette file\n");
|
||||
fwrite(STDERR, "Required arguments: path to block palette file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$palettePath = $argv[1];
|
||||
$paletteRaw = file_get_contents($palettePath);
|
||||
if($paletteRaw === false){
|
||||
fwrite(STDERR, "Failed to read block palette file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try{
|
||||
$states = BlockStateDictionary::loadPaletteFromString($paletteRaw);
|
||||
}catch(NbtException){
|
||||
fwrite(STDERR, "Invalid block palette file $argv[1]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$report = generateBlockPaletteReport($states);
|
||||
generateBlockIds(array_values($report->seenTypes));
|
||||
generateBlockStateNames($report);
|
||||
generateBlockStringValues($report);
|
||||
|
||||
echo "Done. Don't forget to run CS fixup after generating code.\n";
|
97
build/generate-item-type-names.php
Normal file
97
build/generate-item-type-names.php
Normal file
@ -0,0 +1,97 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\build\generate_item_serializer_ids;
|
||||
|
||||
use pocketmine\errorhandler\ErrorToExceptionHandler;
|
||||
use pocketmine\network\mcpe\convert\ItemTypeDictionaryFromDataHelper;
|
||||
use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary;
|
||||
use pocketmine\utils\Utils;
|
||||
use function asort;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function explode;
|
||||
use function fclose;
|
||||
use function file_get_contents;
|
||||
use function fopen;
|
||||
use function fwrite;
|
||||
use function strtoupper;
|
||||
use const SORT_STRING;
|
||||
use const STDERR;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
function constifyMcId(string $id) : string{
|
||||
return strtoupper(explode(":", $id, 2)[1]);
|
||||
}
|
||||
|
||||
function generateItemIds(ItemTypeDictionary $dictionary) : void{
|
||||
$ids = [];
|
||||
foreach($dictionary->getEntries() as $entry){
|
||||
if($entry->getNumericId() < 256){ //blockitems are serialized via BlockStateSerializer
|
||||
continue;
|
||||
}
|
||||
$ids[$entry->getStringId()] = $entry->getStringId();
|
||||
}
|
||||
asort($ids, SORT_STRING);
|
||||
|
||||
$file = ErrorToExceptionHandler::trapAndRemoveFalse(fn() => fopen(dirname(__DIR__) . '/src/data/bedrock/item/ItemTypeNames.php', 'wb'));
|
||||
|
||||
fwrite($file, <<<'HEADER'
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\bedrock\item;
|
||||
|
||||
/**
|
||||
* This class is generated automatically from the item type dictionary for the current version. Do not edit it manually.
|
||||
*/
|
||||
final class ItemTypeNames{
|
||||
|
||||
HEADER
|
||||
);
|
||||
|
||||
foreach(Utils::stringifyKeys($ids) as $id){
|
||||
fwrite($file, "\tpublic const " . constifyMcId($id) . " = \"" . $id . "\";\n");
|
||||
}
|
||||
fwrite($file, "}\n");
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
if(count($argv) !== 2){
|
||||
fwrite(STDERR, "This script regenerates ItemTypeNames from a given item dictionary file\n");
|
||||
fwrite(STDERR, "Required argument: path to item type dictionary file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$raw = file_get_contents($argv[1]);
|
||||
if($raw === false){
|
||||
fwrite(STDERR, "Failed to read item type dictionary file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$dictionary = ItemTypeDictionaryFromDataHelper::loadFromString($raw);
|
||||
generateItemIds($dictionary);
|
||||
|
||||
echo "Done. Don't forget to run CS fixup after generating code.\n";
|
263
build/generate-runtime-enum-serializers.php
Normal file
263
build/generate-runtime-enum-serializers.php
Normal file
@ -0,0 +1,263 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\build\generate_runtime_enum_serializers;
|
||||
|
||||
use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\CopperOxidation;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\DirtType;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\FroglightType;
|
||||
use pocketmine\block\utils\LeverFacing;
|
||||
use pocketmine\block\utils\MushroomBlockType;
|
||||
use pocketmine\block\utils\SkullType;
|
||||
use pocketmine\block\utils\SlabType;
|
||||
use pocketmine\item\MedicineType;
|
||||
use pocketmine\item\PotionType;
|
||||
use pocketmine\item\SuspiciousStewType;
|
||||
use function array_key_first;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function ceil;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function file_put_contents;
|
||||
use function implode;
|
||||
use function ksort;
|
||||
use function lcfirst;
|
||||
use function log;
|
||||
use function ob_get_clean;
|
||||
use function ob_start;
|
||||
use const SORT_STRING;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildWriterFunc(string $virtualTypeName, string $nativeTypeName, array $memberNames, string $functionName) : array{
|
||||
$bits = getBitsRequired($memberNames);
|
||||
$lines = [];
|
||||
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$this->writeInt($bits, match(\$value){";
|
||||
|
||||
foreach($memberNames as $key => $memberName){
|
||||
$lines[] = "\t\t$memberName => $key,";
|
||||
}
|
||||
$lines[] = "\t\tdefault => throw new \pocketmine\utils\AssumptionFailedError(\"All $virtualTypeName cases should be covered\")";
|
||||
$lines[] = "\t});";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildReaderFunc(string $virtualTypeName, string $nativeTypeName, array $memberNames, string $functionName) : array{
|
||||
$bits = getBitsRequired($memberNames);
|
||||
$lines = [];
|
||||
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$value = match(\$this->readInt($bits)){";
|
||||
|
||||
foreach($memberNames as $key => $memberName){
|
||||
$lines[] = "\t\t$key => $memberName,";
|
||||
}
|
||||
$lines[] = "\t\tdefault => throw new InvalidSerializedRuntimeDataException(\"Invalid serialized value for $virtualTypeName\")";
|
||||
$lines[] = "\t};";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
function buildInterfaceFunc(string $nativeTypeName, string $functionName) : string{
|
||||
return "public function $functionName(\\$nativeTypeName &\$value) : void;";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildSizeCalculationFunc(string $nativeTypeName, string $functionName, array $memberNames) : array{
|
||||
$lines = [];
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$this->addBits(" . getBitsRequired($memberNames) . ");";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $members
|
||||
*/
|
||||
function getBitsRequired(array $members) : int{
|
||||
return (int) ceil(log(count($members), 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object[] $members
|
||||
* @phpstan-param array<string, object> $members
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function stringifyEnumMembers(array $members, string $enumClass) : array{
|
||||
ksort($members, SORT_STRING);
|
||||
return array_map(fn(string $enumCaseName) => "\\$enumClass::$enumCaseName()", array_keys($members));
|
||||
}
|
||||
|
||||
$enumsUsed = [
|
||||
BellAttachmentType::getAll(),
|
||||
CopperOxidation::getAll(),
|
||||
CoralType::getAll(),
|
||||
DirtType::getAll(),
|
||||
DyeColor::getAll(),
|
||||
FroglightType::getAll(),
|
||||
LeverFacing::getAll(),
|
||||
MedicineType::getAll(),
|
||||
MushroomBlockType::getAll(),
|
||||
SkullType::getAll(),
|
||||
SlabType::getAll(),
|
||||
SuspiciousStewType::getAll(),
|
||||
PotionType::getAll()
|
||||
];
|
||||
|
||||
$readerFuncs = [
|
||||
"" => [
|
||||
"abstract protected function readInt(int \$bits) : int;"
|
||||
]
|
||||
];
|
||||
$writerFuncs = [
|
||||
"" => [
|
||||
"abstract protected function writeInt(int \$bits, int \$value) : void;"
|
||||
]
|
||||
];
|
||||
$interfaceFuncs = [];
|
||||
$sizeCalculationFuncs = [
|
||||
"" => [
|
||||
"abstract protected function addBits(int \$bits) : void;"
|
||||
]
|
||||
];
|
||||
|
||||
foreach($enumsUsed as $enumMembers){
|
||||
if(count($enumMembers) === 0){
|
||||
throw new \InvalidArgumentException("Enum members cannot be empty");
|
||||
}
|
||||
$reflect = new \ReflectionClass($enumMembers[array_key_first($enumMembers)]);
|
||||
$virtualTypeName = $reflect->getShortName();
|
||||
$nativeTypeName = $reflect->getName();
|
||||
$functionName = lcfirst($virtualTypeName);
|
||||
|
||||
$stringifiedMembers = stringifyEnumMembers($enumMembers, $nativeTypeName);
|
||||
$writerFuncs[$functionName] = buildWriterFunc(
|
||||
$virtualTypeName,
|
||||
$nativeTypeName,
|
||||
$stringifiedMembers,
|
||||
$functionName
|
||||
);
|
||||
$readerFuncs[$functionName] = buildReaderFunc(
|
||||
$virtualTypeName,
|
||||
$nativeTypeName,
|
||||
$stringifiedMembers,
|
||||
$functionName
|
||||
);
|
||||
$interfaceFuncs[$functionName] = [buildInterfaceFunc(
|
||||
$nativeTypeName,
|
||||
$functionName
|
||||
)];
|
||||
$sizeCalculationFuncs[$functionName] = buildSizeCalculationFunc(
|
||||
$nativeTypeName,
|
||||
$functionName,
|
||||
$stringifiedMembers
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[][] $functions
|
||||
* @phpstan-param array<string, list<string>> $functions
|
||||
*/
|
||||
function printFunctions(array $functions, string $className, string $classType) : void{
|
||||
ksort($functions, SORT_STRING);
|
||||
|
||||
ob_start();
|
||||
|
||||
echo <<<'HEADER'
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\data\runtime;
|
||||
|
||||
/**
|
||||
* This class is auto-generated. Do not edit it manually.
|
||||
* @see build/generate-runtime-enum-serializers.php
|
||||
*/
|
||||
|
||||
HEADER;
|
||||
|
||||
echo "$classType $className{\n\n";
|
||||
echo implode("\n\n", array_map(fn(array $functionLines) => "\t" . implode("\n\t", $functionLines), $functions));
|
||||
echo "\n\n}\n";
|
||||
|
||||
file_put_contents(dirname(__DIR__) . '/src/data/runtime/' . $className . '.php', ob_get_clean());
|
||||
}
|
||||
|
||||
printFunctions($writerFuncs, "RuntimeEnumSerializerTrait", "trait");
|
||||
printFunctions($readerFuncs, "RuntimeEnumDeserializerTrait", "trait");
|
||||
printFunctions($interfaceFuncs, "RuntimeEnumDescriber", "interface");
|
||||
printFunctions($sizeCalculationFuncs, "RuntimeEnumSizeCalculatorTrait", "trait");
|
||||
|
||||
echo "Done. Don't forget to run CS fixup after generating code.\n";
|
1038
changelogs/5.0-alpha.md
Normal file
1038
changelogs/5.0-alpha.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": "^4.0",
|
||||
"ext-pthreads": "^5.1",
|
||||
"ext-reflection": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-sockets": "*",
|
||||
@ -35,25 +35,24 @@
|
||||
"fgrosse/phpasn1": "^2.3",
|
||||
"netresearch/jsonmapper": "^4.0",
|
||||
"pocketmine/bedrock-block-upgrade-schema": "^1.0.0",
|
||||
"pocketmine/bedrock-data": "~1.14.0+bedrock-1.19.60",
|
||||
"pocketmine/bedrock-data": "dev-modern-world-support@dev",
|
||||
"pocketmine/bedrock-item-upgrade-schema": "^1.0.0",
|
||||
"pocketmine/bedrock-protocol": "~19.3.0+bedrock-1.19.62",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"pocketmine/classloader": "^0.2.0",
|
||||
"pocketmine/classloader": "^0.3.0",
|
||||
"pocketmine/color": "^0.3.0",
|
||||
"pocketmine/errorhandler": "^0.6.0",
|
||||
"pocketmine/locale-data": "~2.18.0",
|
||||
"pocketmine/locale-data": "~2.19.0",
|
||||
"pocketmine/log": "^0.4.0",
|
||||
"pocketmine/log-pthreads": "^0.4.0",
|
||||
"pocketmine/log-pthreads": "^0.5.0",
|
||||
"pocketmine/math": "^0.4.0",
|
||||
"pocketmine/nbt": "^0.3.2",
|
||||
"pocketmine/raklib": "^0.14.2",
|
||||
"pocketmine/raklib-ipc": "^0.1.0",
|
||||
"pocketmine/snooze": "^0.3.0",
|
||||
"pocketmine/raklib": "^0.15.0",
|
||||
"pocketmine/raklib-ipc": "^0.2.0",
|
||||
"pocketmine/snooze": "^0.4.0",
|
||||
"ramsey/uuid": "^4.1",
|
||||
"symfony/filesystem": "^5.4",
|
||||
"webmozart/path-util": "^2.3"
|
||||
"symfony/filesystem": "^5.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.9.18",
|
||||
|
233
composer.lock
generated
233
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "402f78d672d4e0bd8f092272bf7d82d7",
|
||||
"content-hash": "ea992cf9b9be39c9d5251b7769f9d044",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -276,16 +276,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-data",
|
||||
"version": "1.14.0+bedrock-1.19.60",
|
||||
"version": "dev-modern-world-support",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockData.git",
|
||||
"reference": "7b06234ec6e1f4fb06ad4b2f177e606c25df9b46"
|
||||
"reference": "27cb4d5133d6cbe30018b759eb97e3fdc7036c3b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/7b06234ec6e1f4fb06ad4b2f177e606c25df9b46",
|
||||
"reference": "7b06234ec6e1f4fb06ad4b2f177e606c25df9b46",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/27cb4d5133d6cbe30018b759eb97e3fdc7036c3b",
|
||||
"reference": "27cb4d5133d6cbe30018b759eb97e3fdc7036c3b",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -296,9 +296,9 @@
|
||||
"description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockData/issues",
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.19.60"
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/modern-world-support"
|
||||
},
|
||||
"time": "2023-02-08T18:32:01+00:00"
|
||||
"time": "2023-02-08T18:33:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-item-upgrade-schema",
|
||||
@ -467,20 +467,20 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/classloader",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/ClassLoader.git",
|
||||
"reference": "49ea303993efdfb39cd302e2156d50aa78209e78"
|
||||
"reference": "407caf521186ec1f03024f39031cc681ad491026"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/49ea303993efdfb39cd302e2156d50aa78209e78",
|
||||
"reference": "49ea303993efdfb39cd302e2156d50aa78209e78",
|
||||
"url": "https://api.github.com/repos/pmmp/ClassLoader/zipball/407caf521186ec1f03024f39031cc681ad491026",
|
||||
"reference": "407caf521186ec1f03024f39031cc681ad491026",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "~3.2.0 || ^4.0",
|
||||
"ext-pthreads": "^5.0",
|
||||
"ext-reflection": "*",
|
||||
"php": "^8.0"
|
||||
},
|
||||
@ -489,8 +489,8 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "0.12.99",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.4",
|
||||
"phpstan/phpstan": "1.9.4",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
@ -506,9 +506,9 @@
|
||||
"description": "Ad-hoc autoloading components used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/ClassLoader/issues",
|
||||
"source": "https://github.com/pmmp/ClassLoader/tree/0.2.0"
|
||||
"source": "https://github.com/pmmp/ClassLoader/tree/0.3.0"
|
||||
},
|
||||
"time": "2021-11-01T20:17:27+00:00"
|
||||
"time": "2023-01-23T19:46:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/color",
|
||||
@ -589,16 +589,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/locale-data",
|
||||
"version": "2.18.3",
|
||||
"version": "2.19.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Language.git",
|
||||
"reference": "da25bfe9ee4822a84feb9b7e620c56ad4000aed0"
|
||||
"reference": "f47d1687f21f09d2858f040873184a11746b1cf7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/da25bfe9ee4822a84feb9b7e620c56ad4000aed0",
|
||||
"reference": "da25bfe9ee4822a84feb9b7e620c56ad4000aed0",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/f47d1687f21f09d2858f040873184a11746b1cf7",
|
||||
"reference": "f47d1687f21f09d2858f040873184a11746b1cf7",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -606,9 +606,9 @@
|
||||
"description": "Language resources used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/Language/issues",
|
||||
"source": "https://github.com/pmmp/Language/tree/2.18.3"
|
||||
"source": "https://github.com/pmmp/Language/tree/2.19.0"
|
||||
},
|
||||
"time": "2023-01-17T21:43:36+00:00"
|
||||
"time": "2023-02-13T13:55:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/log",
|
||||
@ -653,21 +653,21 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/log-pthreads",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/LogPthreads.git",
|
||||
"reference": "61f709e8cf36bcc24e4efe02acded680a1ce23cd"
|
||||
"reference": "0ecfea6dcfc9a9f5c86e126ac1661732de5c5666"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/61f709e8cf36bcc24e4efe02acded680a1ce23cd",
|
||||
"reference": "61f709e8cf36bcc24e4efe02acded680a1ce23cd",
|
||||
"url": "https://api.github.com/repos/pmmp/LogPthreads/zipball/0ecfea6dcfc9a9f5c86e126ac1661732de5c5666",
|
||||
"reference": "0ecfea6dcfc9a9f5c86e126ac1661732de5c5666",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "~3.2.0 || ^4.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"ext-pthreads": "^5.0",
|
||||
"php": "^8.0",
|
||||
"pocketmine/log": "^0.4.0"
|
||||
},
|
||||
"conflict": {
|
||||
@ -675,8 +675,8 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "0.12.88",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.4"
|
||||
"phpstan/phpstan": "1.8.11",
|
||||
"phpstan/phpstan-strict-rules": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -691,9 +691,9 @@
|
||||
"description": "Logging components specialized for pthreads used by PocketMine-MP and related projects",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/LogPthreads/issues",
|
||||
"source": "https://github.com/pmmp/LogPthreads/tree/0.4.0"
|
||||
"source": "https://github.com/pmmp/LogPthreads/tree/0.5.0"
|
||||
},
|
||||
"time": "2021-11-01T21:42:09+00:00"
|
||||
"time": "2023-01-23T19:52:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/math",
|
||||
@ -780,16 +780,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/raklib",
|
||||
"version": "0.14.5",
|
||||
"version": "0.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/RakLib.git",
|
||||
"reference": "85b4e5cb7117d37e010eeadb3ff53b21276c6f48"
|
||||
"reference": "1f490cff6bf5e9eb46ebdbf7a7994d62be2bd2c1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/85b4e5cb7117d37e010eeadb3ff53b21276c6f48",
|
||||
"reference": "85b4e5cb7117d37e010eeadb3ff53b21276c6f48",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/1f490cff6bf5e9eb46ebdbf7a7994d62be2bd2c1",
|
||||
"reference": "1f490cff6bf5e9eb46ebdbf7a7994d62be2bd2c1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -801,7 +801,7 @@
|
||||
"pocketmine/log": "^0.3.0 || ^0.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.7.7",
|
||||
"phpstan/phpstan": "1.9.17",
|
||||
"phpstan/phpstan-strict-rules": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
@ -817,33 +817,33 @@
|
||||
"description": "A RakNet server implementation written in PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/RakLib/issues",
|
||||
"source": "https://github.com/pmmp/RakLib/tree/0.14.5"
|
||||
"source": "https://github.com/pmmp/RakLib/tree/0.15.0"
|
||||
},
|
||||
"time": "2022-08-25T16:16:44+00:00"
|
||||
"time": "2023-02-13T12:56:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/raklib-ipc",
|
||||
"version": "0.1.1",
|
||||
"version": "0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/RakLibIpc.git",
|
||||
"reference": "922a6444b0c6c7daaa5aa5a832107e1ec4738aed"
|
||||
"reference": "26ed56fa9db06e4ca6e8920c0ede2e01e219bb9c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/922a6444b0c6c7daaa5aa5a832107e1ec4738aed",
|
||||
"reference": "922a6444b0c6c7daaa5aa5a832107e1ec4738aed",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLibIpc/zipball/26ed56fa9db06e4ca6e8920c0ede2e01e219bb9c",
|
||||
"reference": "26ed56fa9db06e4ca6e8920c0ede2e01e219bb9c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"php": "^8.0",
|
||||
"php-64bit": "*",
|
||||
"pocketmine/binaryutils": "^0.2.0",
|
||||
"pocketmine/raklib": "^0.13.1 || ^0.14.0"
|
||||
"pocketmine/raklib": "^0.15.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "0.12.81",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.2"
|
||||
"phpstan/phpstan": "1.9.17",
|
||||
"phpstan/phpstan-strict-rules": "^1.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -858,32 +858,32 @@
|
||||
"description": "Channel-based protocols for inter-thread/inter-process communication with RakLib",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/RakLibIpc/issues",
|
||||
"source": "https://github.com/pmmp/RakLibIpc/tree/0.1.1"
|
||||
"source": "https://github.com/pmmp/RakLibIpc/tree/0.2.0"
|
||||
},
|
||||
"time": "2021-09-22T17:01:12+00:00"
|
||||
"time": "2023-02-13T13:40:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/snooze",
|
||||
"version": "0.3.1",
|
||||
"version": "0.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Snooze.git",
|
||||
"reference": "0ac8fc2a781c419a1f64ebca4d5835028f59e29b"
|
||||
"reference": "6b1d6cc645d674590ff9be2438ac00032f9ee292"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/0ac8fc2a781c419a1f64ebca4d5835028f59e29b",
|
||||
"reference": "0ac8fc2a781c419a1f64ebca4d5835028f59e29b",
|
||||
"url": "https://api.github.com/repos/pmmp/Snooze/zipball/6b1d6cc645d674590ff9be2438ac00032f9ee292",
|
||||
"reference": "6b1d6cc645d674590ff9be2438ac00032f9ee292",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-pthreads": "~3.2.0 || ^4.0",
|
||||
"php-64bit": "^7.3 || ^8.0"
|
||||
"ext-pthreads": "^5.0",
|
||||
"php-64bit": "^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "0.12.99",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.4"
|
||||
"phpstan/phpstan": "1.9.14",
|
||||
"phpstan/phpstan-strict-rules": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -898,9 +898,9 @@
|
||||
"description": "Thread notification management library for code using the pthreads extension",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/Snooze/issues",
|
||||
"source": "https://github.com/pmmp/Snooze/tree/0.3.1"
|
||||
"source": "https://github.com/pmmp/Snooze/tree/0.4.0"
|
||||
},
|
||||
"time": "2021-11-01T20:50:08+00:00"
|
||||
"time": "2023-01-23T19:43:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ramsey/collection",
|
||||
@ -1474,115 +1474,6 @@
|
||||
}
|
||||
],
|
||||
"time": "2022-11-03T14:55:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozarts/assert.git",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<0.12.20",
|
||||
"vimeo/psalm": "<4.6.1 || 4.6.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.10-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\Assert\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Assertions to validate method input/output with nice error messages.",
|
||||
"keywords": [
|
||||
"assert",
|
||||
"check",
|
||||
"validate"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozarts/assert/issues",
|
||||
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
||||
},
|
||||
"time": "2022-06-03T18:03:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/path-util",
|
||||
"version": "2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/path-util.git",
|
||||
"reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
|
||||
"reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"webmozart/assert": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6",
|
||||
"sebastian/version": "^1.0.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\PathUtil\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.",
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozart/path-util/issues",
|
||||
"source": "https://github.com/webmozart/path-util/tree/2.3.0"
|
||||
},
|
||||
"abandoned": "symfony/filesystem",
|
||||
"time": "2015-12-17T08:42:14+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
@ -3478,7 +3369,9 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"pocketmine/bedrock-data": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
@ -3499,7 +3392,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pthreads": "^4.0",
|
||||
"ext-pthreads": "^5.1",
|
||||
"ext-reflection": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-sockets": "*",
|
||||
|
@ -1,7 +1,6 @@
|
||||
includes:
|
||||
- tests/phpstan/analyse-for-current-php-version.neon.php
|
||||
- tests/phpstan/configs/actual-problems.neon
|
||||
- tests/phpstan/configs/gc-hacks.neon
|
||||
- tests/phpstan/configs/impossible-generics.neon
|
||||
- tests/phpstan/configs/php-bugs.neon
|
||||
- tests/phpstan/configs/phpstan-bugs.neon
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -281,10 +281,8 @@ class MemoryManager{
|
||||
|
||||
/**
|
||||
* Static memory dumper accessible from any thread.
|
||||
*
|
||||
* @param mixed $startingObject
|
||||
*/
|
||||
public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{
|
||||
public static function dumpMemory(mixed $startingObject, string $outputFolder, int $maxNesting, int $maxStringSize, \Logger $logger) : void{
|
||||
$hardLimit = Utils::assumeNotFalse(ini_get('memory_limit'), "memory_limit INI directive should always exist");
|
||||
ini_set('memory_limit', '-1');
|
||||
gc_disable();
|
||||
@ -475,7 +473,6 @@ class MemoryManager{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $from
|
||||
* @param object[] $objects reference parameter
|
||||
* @param int[] $refCounts reference parameter
|
||||
*
|
||||
@ -483,10 +480,8 @@ class MemoryManager{
|
||||
* @phpstan-param array<string, int> $refCounts
|
||||
* @phpstan-param-out array<string, object> $objects
|
||||
* @phpstan-param-out array<string, int> $refCounts
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private static function continueDump($from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
|
||||
private static function continueDump(mixed $from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize) : mixed{
|
||||
if($maxNesting <= 0){
|
||||
return "(error) NESTING LIMIT REACHED";
|
||||
}
|
||||
|
@ -122,8 +122,8 @@ namespace pocketmine {
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "4.0.0") < 0 || version_compare($pthreads_version, "5.0.0") >= 0){
|
||||
$messages[] = "pthreads ^4.0.0 is required, while you have $pthreads_version.";
|
||||
if(version_compare($pthreads_version, "5.1.0") < 0 || version_compare($pthreads_version, "6.0.0") >= 0){
|
||||
$messages[] = "pthreads ^5.0.0 is required, while you have $pthreads_version.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,10 +491,7 @@ class Server{
|
||||
return $this->configGroup->getPropertyBool("player.save-player-data", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OfflinePlayer|Player
|
||||
*/
|
||||
public function getOfflinePlayer(string $name){
|
||||
public function getOfflinePlayer(string $name) : Player|OfflinePlayer|null{
|
||||
$name = strtolower($name);
|
||||
$result = $this->getPlayerExact($name);
|
||||
|
||||
@ -583,8 +580,7 @@ class Server{
|
||||
},
|
||||
function() use ($playerPromiseResolver, $session) : void{
|
||||
if($session->isConnected()){
|
||||
//TODO: this needs to be localized - this might be reached if the spawn world was unloaded while the player was logging in
|
||||
$session->disconnect("Failed to find a safe spawn location");
|
||||
$session->disconnectWithError(KnownTranslationFactory::pocketmine_disconnect_error_respawn());
|
||||
}
|
||||
$playerPromiseResolver->reject();
|
||||
}
|
||||
@ -959,7 +955,7 @@ class Server{
|
||||
|
||||
$this->commandMap = new SimpleCommandMap($this);
|
||||
|
||||
$this->craftingManager = CraftingManagerFromDataHelper::make(Path::join(\pocketmine\RESOURCE_PATH, "legacy_recipes.json"));
|
||||
$this->craftingManager = CraftingManagerFromDataHelper::make(Path::join(\pocketmine\BEDROCK_DATA_PATH, "recipes"));
|
||||
|
||||
$this->resourceManager = new ResourcePackManager(Path::join($this->getDataPath(), "resource_packs"), $this->logger);
|
||||
|
||||
@ -1355,6 +1351,7 @@ class Server{
|
||||
return false;
|
||||
}
|
||||
$recipients = $ev->getTargets();
|
||||
$packets = $ev->getPackets();
|
||||
|
||||
/** @var PacketBroadcaster[] $broadcasters */
|
||||
$broadcasters = [];
|
||||
@ -1529,7 +1526,7 @@ class Server{
|
||||
* @param mixed[][]|null $trace
|
||||
* @phpstan-param list<array<string, mixed>>|null $trace
|
||||
*/
|
||||
public function exceptionHandler(\Throwable $e, $trace = null) : void{
|
||||
public function exceptionHandler(\Throwable $e, ?array $trace = null) : void{
|
||||
while(@ob_end_flush()){}
|
||||
global $lastError;
|
||||
|
||||
|
@ -43,12 +43,7 @@ final class ServerConfigGroup{
|
||||
private Config $serverProperties
|
||||
){}
|
||||
|
||||
/**
|
||||
* @param mixed $defaultValue
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProperty(string $variable, $defaultValue = null){
|
||||
public function getProperty(string $variable, mixed $defaultValue = null) : mixed{
|
||||
if(!array_key_exists($variable, $this->propertyCache)){
|
||||
$v = getopt("", ["$variable::"]);
|
||||
if(isset($v[$variable])){
|
||||
|
@ -31,9 +31,9 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "4.15.2";
|
||||
public const IS_DEVELOPMENT_BUILD = true;
|
||||
public const BUILD_CHANNEL = "stable";
|
||||
public const BASE_VERSION = "5.0.0-ALPHA9";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "alpha";
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
|
@ -24,17 +24,22 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\inventory\AnvilInventory;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\Fallable;
|
||||
use pocketmine\block\utils\FallableTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\object\FallingBlock;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\AnvilFallSound;
|
||||
use pocketmine\world\sound\Sound;
|
||||
use function lcg_value;
|
||||
use function round;
|
||||
|
||||
class Anvil extends Transparent implements Fallable{
|
||||
use FallableTrait;
|
||||
@ -46,21 +51,12 @@ class Anvil extends Transparent implements Fallable{
|
||||
|
||||
private int $damage = self::UNDAMAGED;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->damage << 2);
|
||||
protected function describeType(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(2, self::UNDAMAGED, self::VERY_DAMAGED, $this->damage);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x3);
|
||||
$this->damage = BlockDataSerializer::readBoundedInt("damage", $stateMeta >> 2, self::UNDAMAGED, self::VERY_DAMAGED);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return $this->damage << 2;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
}
|
||||
|
||||
public function getDamage() : int{ return $this->damage; }
|
||||
@ -85,7 +81,7 @@ class Anvil extends Transparent implements Fallable{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player instanceof Player){
|
||||
$player->setCurrentWindow(new AnvilInventory($this->position));
|
||||
}
|
||||
@ -100,7 +96,18 @@ class Anvil extends Transparent implements Fallable{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
public function onHitGround(FallingBlock $blockEntity) : bool{
|
||||
if(lcg_value() < 0.05 + (round($blockEntity->getFallDistance()) - 1) * 0.05){
|
||||
if($this->damage !== self::VERY_DAMAGED){
|
||||
$this->damage = $this->damage + 1;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLandSound() : ?Sound{
|
||||
return new AnvilFallSound();
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Bamboo as ItemBamboo;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -54,18 +55,10 @@ class Bamboo extends Transparent{
|
||||
protected bool $ready = false;
|
||||
protected int $leafSize = self::NO_LEAVES;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->thick = ($stateMeta & BlockLegacyMetadata::BAMBOO_FLAG_THICK) !== 0;
|
||||
$this->leafSize = BlockDataSerializer::readBoundedInt("leafSize", ($stateMeta >> BlockLegacyMetadata::BAMBOO_LEAF_SIZE_SHIFT) & BlockLegacyMetadata::BAMBOO_LEAF_SIZE_MASK, self::NO_LEAVES, self::LARGE_LEAVES);
|
||||
$this->ready = ($stateMeta & BlockLegacyMetadata::BAMBOO_FLAG_READY) !== 0;
|
||||
}
|
||||
|
||||
public function writeStateToMeta() : int{
|
||||
return ($this->thick ? BlockLegacyMetadata::BAMBOO_FLAG_THICK : 0) | ($this->leafSize << BlockLegacyMetadata::BAMBOO_LEAF_SIZE_SHIFT) | ($this->ready ? BlockLegacyMetadata::BAMBOO_FLAG_READY : 0);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(2, self::NO_LEAVES, self::LARGE_LEAVES, $this->leafSize);
|
||||
$w->bool($this->thick);
|
||||
$w->bool($this->ready);
|
||||
}
|
||||
|
||||
public function isThick() : bool{ return $this->thick; }
|
||||
@ -128,14 +121,11 @@ class Bamboo extends Transparent{
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
//TODO: tags would be better for this
|
||||
return
|
||||
$block instanceof Dirt ||
|
||||
$block instanceof Grass ||
|
||||
$block instanceof Gravel ||
|
||||
$block instanceof Sand ||
|
||||
$block instanceof Mycelium ||
|
||||
$block instanceof Podzol;
|
||||
$block->getTypeId() === BlockTypeIds::GRAVEL ||
|
||||
$block->hasTypeTag(BlockTypeTags::DIRT) ||
|
||||
$block->hasTypeTag(BlockTypeTags::MUD) ||
|
||||
$block->hasTypeTag(BlockTypeTags::SAND);
|
||||
}
|
||||
|
||||
private function seekToTop() : Bamboo{
|
||||
@ -147,7 +137,7 @@ class Bamboo extends Transparent{
|
||||
return $top;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof Fertilizer){
|
||||
$top = $this->seekToTop();
|
||||
if($top->grow(self::getMaxHeight($top->position->getFloorX(), $top->position->getFloorZ()), mt_rand(1, 2), $player)){
|
||||
@ -243,4 +233,8 @@ class Bamboo extends Transparent{
|
||||
$world->setBlock($this->position, $this);
|
||||
}
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::BAMBOO();
|
||||
}
|
||||
}
|
||||
|
@ -23,28 +23,23 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Bamboo as ItemBamboo;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class BambooSapling extends Flowable{
|
||||
|
||||
private bool $ready = false;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->ready = ($stateMeta & BlockLegacyMetadata::BAMBOO_SAPLING_FLAG_READY) !== 0;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->bool($this->ready);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->ready ? BlockLegacyMetadata::BAMBOO_SAPLING_FLAG_READY : 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{ return 0b1; }
|
||||
|
||||
public function isReady() : bool{ return $this->ready; }
|
||||
|
||||
/** @return $this */
|
||||
@ -54,14 +49,11 @@ final class BambooSapling extends Flowable{
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
//TODO: tags would be better for this
|
||||
return
|
||||
$block instanceof Dirt ||
|
||||
$block instanceof Grass ||
|
||||
$block instanceof Gravel ||
|
||||
$block instanceof Sand ||
|
||||
$block instanceof Mycelium ||
|
||||
$block instanceof Podzol;
|
||||
$block->getTypeId() === BlockTypeIds::GRAVEL ||
|
||||
$block->hasTypeTag(BlockTypeTags::DIRT) ||
|
||||
$block->hasTypeTag(BlockTypeTags::MUD) ||
|
||||
$block->hasTypeTag(BlockTypeTags::SAND);
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
@ -71,7 +63,7 @@ final class BambooSapling extends Flowable{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof Fertilizer || $item instanceof ItemBamboo){
|
||||
if($this->grow($player)){
|
||||
$item->pop();
|
||||
@ -126,6 +118,6 @@ final class BambooSapling extends Flowable{
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaBlocks::BAMBOO()->asItem();
|
||||
return VanillaItems::BAMBOO();
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Barrel as TileBarrel;
|
||||
use pocketmine\block\utils\AnyFacingTrait;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -38,17 +38,9 @@ class Barrel extends Opaque{
|
||||
|
||||
protected bool $open = false;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeFacing($this->facing) | ($this->open ? BlockLegacyMetadata::BARREL_FLAG_OPEN : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readFacing($stateMeta & 0x07);
|
||||
$this->open = ($stateMeta & BlockLegacyMetadata::BARREL_FLAG_OPEN) === BlockLegacyMetadata::BARREL_FLAG_OPEN;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->facing($this->facing);
|
||||
$w->bool($this->open);
|
||||
}
|
||||
|
||||
public function isOpen() : bool{
|
||||
@ -81,7 +73,7 @@ class Barrel extends Opaque{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player instanceof Player){
|
||||
$barrel = $this->position->getWorld()->getTile($this->position);
|
||||
if($barrel instanceof TileBarrel){
|
||||
|
@ -28,9 +28,9 @@ use pocketmine\block\utils\BannerPatternLayer;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\bedrock\DyeColorIdMap;
|
||||
use pocketmine\item\Banner as ItemBanner;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
@ -48,18 +48,20 @@ abstract class BaseBanner extends Transparent{
|
||||
*/
|
||||
protected array $patterns = [];
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::BLACK();
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
public function readStateFromWorld() : Block{
|
||||
parent::readStateFromWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
if($tile instanceof TileBanner){
|
||||
$this->color = $tile->getBaseColor();
|
||||
$this->setPatterns($tile->getPatterns());
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
@ -136,10 +138,6 @@ abstract class BaseBanner extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return DyeColorIdMap::getInstance()->toInvertedId($this->color);
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
$drop = $this->asItem();
|
||||
if($drop instanceof ItemBanner && count($this->patterns) > 0){
|
||||
@ -156,4 +154,8 @@ abstract class BaseBanner extends Transparent{
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::BANNER()->setColor($this->color);
|
||||
}
|
||||
}
|
||||
|
89
src/block/BaseCake.php
Normal file
89
src/block/BaseCake.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\entity\effect\EffectInstance;
|
||||
use pocketmine\entity\FoodSource;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
abstract class BaseCake extends Transparent implements FoodSource{
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getTypeId() !== BlockTypeIds::AIR){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->getTypeId() === BlockTypeIds::AIR){ //Replace with common break method
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player !== null){
|
||||
return $player->consumeObject($this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFoodRestore() : int{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getSaturationRestore() : float{
|
||||
return 0.4;
|
||||
}
|
||||
|
||||
public function requiresHunger() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EffectInstance[]
|
||||
*/
|
||||
public function getAdditionalEffects() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
abstract public function getResidue() : Block;
|
||||
|
||||
public function onConsume(Living $consumer) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, $this->getResidue());
|
||||
}
|
||||
}
|
@ -28,34 +28,28 @@ use pocketmine\block\utils\CoralTypeTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\event\block\BlockDeathEvent;
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
|
||||
abstract class BaseCoral extends Transparent{
|
||||
use CoralTypeTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
$this->coralType = CoralType::TUBE();
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->dead){
|
||||
$world = $this->position->getWorld();
|
||||
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(40, 200));
|
||||
}
|
||||
}
|
||||
|
||||
$hasWater = false;
|
||||
foreach($this->position->sides() as $vector3){
|
||||
if($world->getBlock($vector3) instanceof Water){
|
||||
$hasWater = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: check water inside the block itself (not supported on the API yet)
|
||||
if(!$hasWater){
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$world->setBlock($this->position, $ev->getNewState());
|
||||
}
|
||||
public function onScheduledUpdate() : void{
|
||||
if(!$this->dead && !$this->isCoveredWithWater()){
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->position->getWorld()->setBlock($this->position, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,6 +64,21 @@ abstract class BaseCoral extends Transparent{
|
||||
|
||||
public function isSolid() : bool{ return false; }
|
||||
|
||||
protected function isCoveredWithWater() : bool{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
$hasWater = false;
|
||||
foreach($this->position->sides() as $vector3){
|
||||
if($world->getBlock($vector3) instanceof Water){
|
||||
$hasWater = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: check water inside the block itself (not supported on the API yet)
|
||||
return $hasWater;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{ return []; }
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
|
63
src/block/BaseFire.php
Normal file
63
src/block/BaseFire.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\projectile\Arrow;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
abstract class BaseFire extends Flowable{
|
||||
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityInside(Entity $entity) : bool{
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, $this->getFireDamage());
|
||||
$entity->attack($ev);
|
||||
|
||||
$ev = new EntityCombustByBlockEvent($this, $entity, 8);
|
||||
if($entity instanceof Arrow){
|
||||
$ev->cancel();
|
||||
}
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$entity->setOnFire($ev->getDuration());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract protected function getFireDamage() : int;
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -24,35 +24,55 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Sign as TileSign;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\SignText;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\block\utils\WoodTypeTrait;
|
||||
use pocketmine\color\Color;
|
||||
use pocketmine\event\block\SignChangeEvent;
|
||||
use pocketmine\item\Dye;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemTypeIds;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\TextFormat;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\DyeUseSound;
|
||||
use pocketmine\world\sound\InkSacUseSound;
|
||||
use function array_map;
|
||||
use function assert;
|
||||
use function strlen;
|
||||
|
||||
abstract class BaseSign extends Transparent{
|
||||
use WoodTypeTrait;
|
||||
|
||||
protected SignText $text;
|
||||
protected ?int $editorEntityRuntimeId = null;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
/** @var \Closure() : Item */
|
||||
private \Closure $asItemCallback;
|
||||
|
||||
/**
|
||||
* @param \Closure() : Item $asItemCallback
|
||||
*/
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, WoodType $woodType, \Closure $asItemCallback){
|
||||
$this->woodType = $woodType;
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
$this->text = new SignText();
|
||||
$this->asItemCallback = $asItemCallback;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
public function readStateFromWorld() : Block{
|
||||
parent::readStateFromWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
if($tile instanceof TileSign){
|
||||
$this->text = $tile->getText();
|
||||
$this->editorEntityRuntimeId = $tile->getEditorEntityRuntimeId();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
@ -85,7 +105,7 @@ abstract class BaseSign extends Transparent{
|
||||
abstract protected function getSupportingFace() : int;
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide($this->getSupportingFace())->getId() === BlockLegacyIds::AIR){
|
||||
if($this->getSide($this->getSupportingFace())->getTypeId() === BlockTypeIds::AIR){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
@ -97,6 +117,55 @@ abstract class BaseSign extends Transparent{
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
private function doSignChange(SignText $newText, Player $player, Item $item) : bool{
|
||||
$ev = new SignChangeEvent($this, $player, $newText);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->text = $ev->getNewText();
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$item->pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function changeSignGlowingState(bool $glowing, Player $player, Item $item) : bool{
|
||||
if($this->text->isGlowing() !== $glowing && $this->doSignChange(new SignText($this->text->getLines(), $this->text->getBaseColor(), $glowing), $player, $item)){
|
||||
$this->position->getWorld()->addSound($this->position, new InkSacUseSound());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player === null){
|
||||
return false;
|
||||
}
|
||||
$dyeColor = $item instanceof Dye ? $item->getColor() : match($item->getTypeId()){
|
||||
ItemTypeIds::BONE_MEAL => DyeColor::WHITE(),
|
||||
ItemTypeIds::LAPIS_LAZULI => DyeColor::BLUE(),
|
||||
ItemTypeIds::COCOA_BEANS => DyeColor::BROWN(),
|
||||
default => null
|
||||
};
|
||||
if($dyeColor !== null){
|
||||
$color = $dyeColor->equals(DyeColor::BLACK()) ? new Color(0, 0, 0) : $dyeColor->getRgbValue();
|
||||
if($color->toARGB() === $this->text->getBaseColor()->toARGB()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->doSignChange(new SignText($this->text->getLines(), $color, $this->text->isGlowing()), $player, $item)){
|
||||
$this->position->getWorld()->addSound($this->position, new DyeUseSound());
|
||||
return true;
|
||||
}
|
||||
}elseif($item->getTypeId() === ItemTypeIds::INK_SAC){
|
||||
return $this->changeSignGlowingState(false, $player, $item);
|
||||
}elseif($item->getTypeId() === ItemTypeIds::GLOW_INK_SAC){
|
||||
return $this->changeSignGlowingState(true, $player, $item);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object containing information about the sign text.
|
||||
*/
|
||||
@ -139,4 +208,8 @@ abstract class BaseSign extends Transparent{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return ($this->asItemCallback)();
|
||||
}
|
||||
}
|
||||
|
@ -24,12 +24,11 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Bed as TileBed;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\bedrock\DyeColorIdMap;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\Item;
|
||||
@ -49,34 +48,26 @@ class Bed extends Transparent{
|
||||
protected bool $occupied = false;
|
||||
protected bool $head = false;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::RED();
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) |
|
||||
($this->occupied ? BlockLegacyMetadata::BED_FLAG_OCCUPIED : 0) |
|
||||
($this->head ? BlockLegacyMetadata::BED_FLAG_HEAD : 0);
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->occupied);
|
||||
$w->bool($this->head);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03);
|
||||
$this->occupied = ($stateMeta & BlockLegacyMetadata::BED_FLAG_OCCUPIED) !== 0;
|
||||
$this->head = ($stateMeta & BlockLegacyMetadata::BED_FLAG_HEAD) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
public function readStateFromWorld() : Block{
|
||||
parent::readStateFromWorld();
|
||||
//read extra state information from the tile - this is an ugly hack
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
if($tile instanceof TileBed){
|
||||
$this->color = $tile->getColor();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
@ -132,7 +123,7 @@ class Bed extends Transparent{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player !== null){
|
||||
$other = $this->getOtherHalf();
|
||||
$playerPos = $player->getPosition();
|
||||
@ -209,10 +200,6 @@ class Bed extends Transparent{
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return DyeColorIdMap::getInstance()->toId($this->color);
|
||||
}
|
||||
|
||||
public function getAffectedBlocks() : array{
|
||||
if(($other = $this->getOtherHalf()) !== null){
|
||||
return [$this, $other];
|
||||
@ -224,4 +211,6 @@ class Bed extends Transparent{
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE());
|
||||
}
|
||||
|
||||
public function getMaxStackSize() : int{ return 1; }
|
||||
}
|
||||
|
@ -23,20 +23,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class Bedrock extends Opaque{
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
|
||||
class Bedrock extends Opaque{
|
||||
private bool $burnsForever = false;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->burnsForever = ($stateMeta & BlockLegacyMetadata::BEDROCK_FLAG_INFINIBURN) !== 0;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->burnsForever ? BlockLegacyMetadata::BEDROCK_FLAG_INFINIBURN : 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->bool($this->burnsForever);
|
||||
}
|
||||
|
||||
public function burnsForever() : bool{
|
||||
|
@ -42,7 +42,7 @@ class Beetroot extends Crops{
|
||||
];
|
||||
}
|
||||
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::BEETROOT_SEEDS();
|
||||
}
|
||||
}
|
||||
|
@ -25,16 +25,16 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Bell as TileBell;
|
||||
use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\projectile\Projectile;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\BellRingSound;
|
||||
|
||||
@ -43,41 +43,14 @@ final class Bell extends Transparent{
|
||||
|
||||
private BellAttachmentType $attachmentType;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->attachmentType = BellAttachmentType::FLOOR();
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->setFacing(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03));
|
||||
|
||||
$attachmentType = [
|
||||
BlockLegacyMetadata::BELL_ATTACHMENT_FLOOR => BellAttachmentType::FLOOR(),
|
||||
BlockLegacyMetadata::BELL_ATTACHMENT_CEILING => BellAttachmentType::CEILING(),
|
||||
BlockLegacyMetadata::BELL_ATTACHMENT_ONE_WALL => BellAttachmentType::ONE_WALL(),
|
||||
BlockLegacyMetadata::BELL_ATTACHMENT_TWO_WALLS => BellAttachmentType::TWO_WALLS()
|
||||
][($stateMeta >> 2) & 0b11] ?? null;
|
||||
if($attachmentType === null){
|
||||
throw new InvalidBlockStateException("No such attachment type");
|
||||
}
|
||||
$this->setAttachmentType($attachmentType);
|
||||
}
|
||||
|
||||
public function writeStateToMeta() : int{
|
||||
$attachmentTypeMeta = [
|
||||
BellAttachmentType::FLOOR()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_FLOOR,
|
||||
BellAttachmentType::CEILING()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_CEILING,
|
||||
BellAttachmentType::ONE_WALL()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_ONE_WALL,
|
||||
BellAttachmentType::TWO_WALLS()->id() => BlockLegacyMetadata::BELL_ATTACHMENT_TWO_WALLS
|
||||
][$this->getAttachmentType()->id()] ?? null;
|
||||
if($attachmentTypeMeta === null){
|
||||
throw new AssumptionFailedError("Mapping should cover all cases");
|
||||
}
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->getFacing()) | ($attachmentTypeMeta << 2);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->bellAttachmentType($this->attachmentType);
|
||||
$w->horizontalFacing($this->facing);
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
@ -157,17 +130,10 @@ final class Bell extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player !== null){
|
||||
$faceHit = Facing::opposite($player->getHorizontalFacing());
|
||||
if(
|
||||
$this->attachmentType->equals(BellAttachmentType::CEILING()) ||
|
||||
($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)) ||
|
||||
(
|
||||
($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) &&
|
||||
($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true))
|
||||
)
|
||||
){
|
||||
if($this->isValidFaceToRing($faceHit)){
|
||||
$this->ring($faceHit);
|
||||
return true;
|
||||
}
|
||||
@ -176,6 +142,13 @@ final class Bell extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
|
||||
$faceHit = Facing::opposite($projectile->getHorizontalFacing());
|
||||
if($this->isValidFaceToRing($faceHit)){
|
||||
$this->ring($faceHit);
|
||||
}
|
||||
}
|
||||
|
||||
public function ring(int $faceHit) : void{
|
||||
$world = $this->position->getWorld();
|
||||
$world->addSound($this->position, new BellRingSound());
|
||||
@ -184,4 +157,15 @@ final class Bell extends Transparent{
|
||||
$world->broadcastPacketToViewers($this->position, $tile->createFakeUpdatePacket($faceHit));
|
||||
}
|
||||
}
|
||||
|
||||
private function isValidFaceToRing(int $faceHit) : bool{
|
||||
return (
|
||||
$this->attachmentType->equals(BellAttachmentType::CEILING()) ||
|
||||
($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)) ||
|
||||
(
|
||||
($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) &&
|
||||
($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -28,49 +28,61 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Spawnable;
|
||||
use pocketmine\block\tile\Tile;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\data\runtime\RuntimeDataReader;
|
||||
use pocketmine\data\runtime\RuntimeDataSizeCalculator;
|
||||
use pocketmine\data\runtime\RuntimeDataWriter;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\projectile\Projectile;
|
||||
use pocketmine\item\enchantment\VanillaEnchantments;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\ItemBlock;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\Position;
|
||||
use pocketmine\world\World;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function dechex;
|
||||
use function get_class;
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
class Block{
|
||||
public const INTERNAL_METADATA_BITS = 4;
|
||||
public const INTERNAL_METADATA_MASK = ~(~0 << self::INTERNAL_METADATA_BITS);
|
||||
public const INTERNAL_STATE_DATA_BITS = 9;
|
||||
public const INTERNAL_STATE_DATA_MASK = ~(~0 << self::INTERNAL_STATE_DATA_BITS);
|
||||
|
||||
protected BlockIdentifier $idInfo;
|
||||
protected string $fallbackName;
|
||||
protected BlockBreakInfo $breakInfo;
|
||||
protected BlockTypeInfo $typeInfo;
|
||||
protected Position $position;
|
||||
|
||||
/** @var AxisAlignedBB[]|null */
|
||||
protected ?array $collisionBoxes = null;
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<string, int>
|
||||
*/
|
||||
private static array $typeDataBits = [];
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<string, int>
|
||||
*/
|
||||
private static array $stateDataBits = [];
|
||||
|
||||
/**
|
||||
* @param string $name English name of the block type (TODO: implement translations)
|
||||
*/
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
if(($idInfo->getVariant() & $this->getStateBitmask()) !== 0){
|
||||
throw new \InvalidArgumentException("Variant 0x" . dechex($idInfo->getVariant()) . " collides with state bitmask 0x" . dechex($this->getStateBitmask()));
|
||||
}
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->idInfo = $idInfo;
|
||||
$this->fallbackName = $name;
|
||||
$this->breakInfo = $breakInfo;
|
||||
$this->typeInfo = $typeInfo;
|
||||
$this->position = new Position(0, 0, 0, null);
|
||||
}
|
||||
|
||||
@ -79,8 +91,8 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object containing information about how to identify and store this block type, such as its legacy
|
||||
* numeric ID(s), tile type (if any), and legacy variant metadata.
|
||||
* Returns an object containing information about how to identify and store this block type, such as type ID and
|
||||
* tile type (if any).
|
||||
*/
|
||||
public function getIdInfo() : BlockIdentifier{
|
||||
return $this->idInfo;
|
||||
@ -93,25 +105,16 @@ class Block{
|
||||
return $this->fallbackName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* Returns the legacy numeric Minecraft block ID.
|
||||
*/
|
||||
public function getId() : int{
|
||||
return $this->idInfo->getBlockId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Returns the full blockstate ID of this block. This is a compact way of representing a blockstate used to store
|
||||
* blocks in chunks at runtime.
|
||||
*
|
||||
* This ID can be used to later obtain a copy of this block using {@link BlockFactory::get()}.
|
||||
* This ID can be used to later obtain a copy of this block using {@link RuntimeBlockStateRegistry::fromStateId()}.
|
||||
*/
|
||||
public function getFullId() : int{
|
||||
return ($this->getId() << self::INTERNAL_METADATA_BITS) | $this->getMeta();
|
||||
public function getStateId() : int{
|
||||
return ($this->getTypeId() << self::INTERNAL_STATE_DATA_BITS) | $this->computeStateData();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,44 +123,102 @@ class Block{
|
||||
* Type information such as colour, wood type, etc. is preserved.
|
||||
*/
|
||||
public function asItem() : Item{
|
||||
return ItemFactory::getInstance()->get(
|
||||
$this->idInfo->getItemId(),
|
||||
$this->idInfo->getVariant() | $this->writeStateToItemMeta()
|
||||
);
|
||||
return new ItemBlock($this);
|
||||
}
|
||||
|
||||
final public function getRequiredTypeDataBits() : int{
|
||||
$class = get_class($this);
|
||||
if(isset(self::$typeDataBits[$class])){
|
||||
return self::$typeDataBits[$class];
|
||||
}
|
||||
$calculator = new RuntimeDataSizeCalculator();
|
||||
$this->describeType($calculator);
|
||||
return self::$typeDataBits[$class] = $calculator->getBitsUsed();
|
||||
}
|
||||
|
||||
final public function getRequiredStateDataBits() : int{
|
||||
$class = get_class($this);
|
||||
if(isset(self::$stateDataBits[$class])){
|
||||
return self::$stateDataBits[$class];
|
||||
}
|
||||
$calculator = new RuntimeDataSizeCalculator();
|
||||
$this->describeState($calculator);
|
||||
return self::$stateDataBits[$class] = $calculator->getBitsUsed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* Returns the legacy Minecraft block meta value. This is a mixed-purpose value, which is used to store different
|
||||
* things for different blocks.
|
||||
* @internal
|
||||
*/
|
||||
public function getMeta() : int{
|
||||
$stateMeta = $this->writeStateToMeta();
|
||||
assert(($stateMeta & ~$this->getStateBitmask()) === 0);
|
||||
return $this->idInfo->getVariant() | $stateMeta;
|
||||
}
|
||||
final public function decodeTypeData(int $data) : void{
|
||||
$typeBits = $this->getRequiredTypeDataBits();
|
||||
$givenBits = $typeBits;
|
||||
$reader = new RuntimeDataReader($givenBits, $data);
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return 0;
|
||||
$this->describeType($reader);
|
||||
$readBits = $reader->getOffset();
|
||||
if($typeBits !== $readBits){
|
||||
throw new \LogicException(get_class($this) . ": Exactly $typeBits bits of type data were provided, but $readBits were read");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bitmask used to extract state bits from block metadata.
|
||||
* This is used to remove unwanted information from the legacy meta value when getting the block as an item.
|
||||
* @internal
|
||||
*/
|
||||
public function getStateBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
final public function decodeStateData(int $data) : void{
|
||||
$typeBits = $this->getRequiredTypeDataBits();
|
||||
$stateBits = $this->getRequiredStateDataBits();
|
||||
$givenBits = $typeBits + $stateBits;
|
||||
$reader = new RuntimeDataReader($givenBits, $data);
|
||||
$this->decodeTypeData($reader->readInt($typeBits));
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return 0;
|
||||
$this->describeState($reader);
|
||||
$readBits = $reader->getOffset() - $typeBits;
|
||||
if($stateBits !== $readBits){
|
||||
throw new \LogicException(get_class($this) . ": Exactly $stateBits bits of state data were provided, but $readBits were read");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidBlockStateException
|
||||
* @internal
|
||||
*/
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
final public function computeTypeData() : int{
|
||||
$typeBits = $this->getRequiredTypeDataBits();
|
||||
$requiredBits = $typeBits;
|
||||
$writer = new RuntimeDataWriter($requiredBits);
|
||||
|
||||
$this->describeType($writer);
|
||||
$writtenBits = $writer->getOffset();
|
||||
if($typeBits !== $writtenBits){
|
||||
throw new \LogicException(get_class($this) . ": Exactly $typeBits bits of type data were expected, but $writtenBits were written");
|
||||
}
|
||||
|
||||
return $writer->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final public function computeStateData() : int{
|
||||
$typeBits = $this->getRequiredTypeDataBits();
|
||||
$stateBits = $this->getRequiredStateDataBits();
|
||||
$requiredBits = $typeBits + $stateBits;
|
||||
$writer = new RuntimeDataWriter($requiredBits);
|
||||
$writer->writeInt($typeBits, $this->computeTypeData());
|
||||
|
||||
$this->describeState($writer);
|
||||
$writtenBits = $writer->getOffset() - $typeBits;
|
||||
if($stateBits !== $writtenBits){
|
||||
throw new \LogicException(get_class($this) . ": Exactly $stateBits bits of state data were expected, but $writtenBits were written");
|
||||
}
|
||||
|
||||
return $writer->getValue();
|
||||
}
|
||||
|
||||
protected function describeType(RuntimeDataDescriber $w) : void{
|
||||
//NOOP
|
||||
}
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
//NOOP
|
||||
}
|
||||
|
||||
@ -167,9 +228,14 @@ class Block{
|
||||
*
|
||||
* Clears any cached precomputed objects, such as bounding boxes. Remove any outdated precomputed things such as
|
||||
* AABBs and force recalculation.
|
||||
*
|
||||
* A replacement block may be returned. This is useful if the block type changed due to reading of world data (e.g.
|
||||
* data from a block entity).
|
||||
*/
|
||||
public function readStateFromWorld() : void{
|
||||
public function readStateFromWorld() : Block{
|
||||
$this->collisionBoxes = null;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,7 +246,11 @@ class Block{
|
||||
*/
|
||||
public function writeStateToWorld() : void{
|
||||
$world = $this->position->getWorld();
|
||||
$world->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getFullId());
|
||||
$chunk = $world->getOrLoadChunkAtPosition($this->position);
|
||||
if($chunk === null){
|
||||
throw new AssumptionFailedError("World::setBlock() should have loaded the chunk before calling this method");
|
||||
}
|
||||
$chunk->setBlockStateId($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getStateId());
|
||||
|
||||
$tileType = $this->idInfo->getTileClass();
|
||||
$oldTile = $world->getTile($this->position);
|
||||
@ -207,14 +277,11 @@ class Block{
|
||||
* powered/unpowered, etc.
|
||||
*/
|
||||
public function getTypeId() : int{
|
||||
return ($this->idInfo->getBlockId() << Block::INTERNAL_METADATA_BITS) | $this->idInfo->getVariant();
|
||||
return $this->idInfo->getBlockTypeId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given block has an equivalent type to this one. This compares the type IDs.
|
||||
*
|
||||
* Note: This ignores additional IDs used to represent additional states. This means that, for example, a lit
|
||||
* furnace and unlit furnace are considered the same type.
|
||||
*/
|
||||
public function isSameType(Block $other) : bool{
|
||||
return $this->getTypeId() === $other->getTypeId();
|
||||
@ -224,7 +291,26 @@ class Block{
|
||||
* Returns whether the given block has the same type and properties as this block.
|
||||
*/
|
||||
public function isSameState(Block $other) : bool{
|
||||
return $this->getFullId() === $other->getFullId();
|
||||
return $this->getStateId() === $other->getStateId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getTypeTags() : array{
|
||||
return $this->typeInfo->getTypeTags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block type has the given type tag. Type tags are used as a dynamic way to tag blocks as
|
||||
* having certain properties, allowing type checks which are more dynamic than hardcoding a bunch of IDs or a bunch
|
||||
* of instanceof checks.
|
||||
*
|
||||
* For example, grass blocks, dirt, farmland, podzol and mycelium are all dirt-like blocks, and support the
|
||||
* placement of blocks like flowers, so they have a common tag which allows them to be identified as such.
|
||||
*/
|
||||
public function hasTypeTag(string $tag) : bool{
|
||||
return $this->typeInfo->hasTypeTag($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -280,13 +366,15 @@ class Block{
|
||||
* Returns an object containing information about the destruction requirements of this block.
|
||||
*/
|
||||
public function getBreakInfo() : BlockBreakInfo{
|
||||
return $this->breakInfo;
|
||||
return $this->typeInfo->getBreakInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the actions needed so the block is broken with the Item
|
||||
*
|
||||
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if full)
|
||||
*/
|
||||
public function onBreak(Item $item, ?Player $player = null) : bool{
|
||||
public function onBreak(Item $item, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
if(($t = $world->getTile($this->position)) !== null){
|
||||
$t->onBlockDestroyed();
|
||||
@ -326,8 +414,10 @@ class Block{
|
||||
|
||||
/**
|
||||
* Do actions when interacted by Item. Returns if it has done anything
|
||||
*
|
||||
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
|
||||
*/
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -419,7 +509,7 @@ class Block{
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->breakInfo->isToolCompatible($item)){
|
||||
if($this->getBreakInfo()->isToolCompatible($item)){
|
||||
if($this->isAffectedBySilkTouch() && $item->hasEnchantment(VanillaEnchantments::SILK_TOUCH())){
|
||||
return $this->getSilkTouchDrops($item);
|
||||
}
|
||||
@ -461,7 +551,7 @@ class Block{
|
||||
* Returns how much XP will be dropped by breaking this block with the given item.
|
||||
*/
|
||||
public function getXpDropForTool(Item $item) : int{
|
||||
if($item->hasEnchantment(VanillaEnchantments::SILK_TOUCH()) || !$this->breakInfo->isToolCompatible($item)){
|
||||
if($item->hasEnchantment(VanillaEnchantments::SILK_TOUCH()) || !$this->getBreakInfo()->isToolCompatible($item)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -515,6 +605,10 @@ class Block{
|
||||
return 64;
|
||||
}
|
||||
|
||||
public function isFireProofAsItem() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the chance that the block will catch fire from nearby fire sources. Higher values lead to faster catching
|
||||
* fire.
|
||||
@ -604,7 +698,7 @@ class Block{
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(){
|
||||
return "Block[" . $this->getName() . "] (" . $this->getId() . ":" . $this->getMeta() . ")";
|
||||
return "Block[" . $this->getName() . "] (" . $this->getTypeId() . ":" . $this->computeStateData() . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -663,6 +757,13 @@ class Block{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a projectile collides with one of this block's collision boxes.
|
||||
*/
|
||||
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
|
||||
//NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of collision bounding boxes for this block.
|
||||
* These are used for:
|
||||
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ToolTier;
|
||||
use function get_class;
|
||||
|
||||
class BlockBreakInfo{
|
||||
@ -52,6 +53,22 @@ class BlockBreakInfo{
|
||||
$this->blastResistance = $blastResistance ?? $hardness * 5;
|
||||
}
|
||||
|
||||
public static function tier(float $hardness, int $toolType, ToolTier $toolTier, ?float $blastResistance = null) : self{
|
||||
return new self($hardness, $toolType, $toolTier->getHarvestLevel(), $blastResistance);
|
||||
}
|
||||
|
||||
public static function pickaxe(float $hardness, ?ToolTier $toolTier = null, ?float $blastResistance = null) : self{
|
||||
return new self($hardness, BlockToolType::PICKAXE, $toolTier?->getHarvestLevel() ?? 0, $blastResistance);
|
||||
}
|
||||
|
||||
public static function shovel(float $hardness, ?ToolTier $toolTier = null, ?float $blastResistance = null) : self{
|
||||
return new self($hardness, BlockToolType::SHOVEL, $toolTier?->getHarvestLevel() ?? 0, $blastResistance);
|
||||
}
|
||||
|
||||
public static function axe(float $hardness, ?ToolTier $toolTier = null, ?float $blastResistance = null) : self{
|
||||
return new self($hardness, BlockToolType::AXE, $toolTier?->getHarvestLevel() ?? 0, $blastResistance);
|
||||
}
|
||||
|
||||
public static function instant(int $toolType = BlockToolType::NONE, int $toolHarvestLevel = 0) : self{
|
||||
return new self(0.0, $toolType, $toolHarvestLevel, 0.0);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -31,34 +31,18 @@ class BlockIdentifier{
|
||||
* @phpstan-param class-string<Tile>|null $tileClass
|
||||
*/
|
||||
public function __construct(
|
||||
private int $blockId,
|
||||
private int $variant,
|
||||
private ?int $itemId = null,
|
||||
private int $blockTypeId,
|
||||
private ?string $tileClass = null
|
||||
){
|
||||
if($blockTypeId < 0){
|
||||
throw new \InvalidArgumentException("Block type ID may not be negative");
|
||||
}
|
||||
if($tileClass !== null){
|
||||
Utils::testValidInstance($tileClass, Tile::class);
|
||||
}
|
||||
}
|
||||
|
||||
public function getBlockId() : int{
|
||||
return $this->blockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
public function getAllBlockIds() : array{
|
||||
return [$this->blockId];
|
||||
}
|
||||
|
||||
public function getVariant() : int{
|
||||
return $this->variant;
|
||||
}
|
||||
|
||||
public function getItemId() : int{
|
||||
return $this->itemId ?? ($this->blockId > 255 ? 255 - $this->blockId : $this->blockId);
|
||||
}
|
||||
public function getBlockTypeId() : int{ return $this->blockTypeId; }
|
||||
|
||||
/**
|
||||
* @phpstan-return class-string<Tile>|null
|
||||
|
@ -1,59 +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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use function count;
|
||||
|
||||
class BlockIdentifierFlattened extends BlockIdentifier{
|
||||
|
||||
/** @var int[] */
|
||||
private array $additionalIds;
|
||||
|
||||
/**
|
||||
* @param int[] $additionalIds
|
||||
*/
|
||||
public function __construct(int $blockId, array $additionalIds, int $variant, ?int $itemId = null, ?string $tileClass = null){
|
||||
if(count($additionalIds) === 0){
|
||||
throw new \InvalidArgumentException("Expected at least 1 additional ID");
|
||||
}
|
||||
parent::__construct($blockId, $variant, $itemId, $tileClass);
|
||||
|
||||
$this->additionalIds = $additionalIds;
|
||||
}
|
||||
|
||||
public function getAdditionalId(int $index) : int{
|
||||
if(!isset($this->additionalIds[$index])){
|
||||
throw new \InvalidArgumentException("No such ID at index $index");
|
||||
}
|
||||
return $this->additionalIds[$index];
|
||||
}
|
||||
|
||||
public function getSecondId() : int{
|
||||
return $this->getAdditionalId(0);
|
||||
}
|
||||
|
||||
public function getAllBlockIds() : array{
|
||||
return [$this->getBlockId(), ...$this->additionalIds];
|
||||
}
|
||||
}
|
@ -24,225 +24,270 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\BlockIdentifier as BID;
|
||||
use pocketmine\block\BlockLegacyIds as Ids;
|
||||
use pocketmine\block\BlockTypeIds as Ids;
|
||||
use pocketmine\block\tile\Sign as TileSign;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\LeavesType;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\item\ItemIds;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
|
||||
final class BlockLegacyIdHelper{
|
||||
|
||||
public static function getWoodenFloorSignIdentifier(TreeType $treeType) : BID{
|
||||
public static function getWoodenPlanksIdentifier(WoodType $type) : BID{
|
||||
return new BID(match($type->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_PLANKS,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_PLANKS,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_PLANKS,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_PLANKS,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_PLANKS,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_PLANKS,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_PLANKS,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_PLANKS,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_PLANKS,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenFenceIdentifier(WoodType $type) : BID{
|
||||
return new BID(match($type->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_FENCE,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_FENCE,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_FENCE,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_FENCE,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_FENCE,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_FENCE,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_FENCE,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_FENCE,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_FENCE,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenSlabIdentifier(WoodType $type) : BID{
|
||||
return new BID(match($type->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_SLAB,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_SLAB,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_SLAB,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_SLAB,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_SLAB,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_SLAB,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_SLAB,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_SLAB,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_SLAB,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getLogIdentifier(WoodType $treeType) : BID{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_LOG,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_LOG,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_LOG,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_LOG,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_LOG,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_LOG,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_LOG,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_STEM,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_STEM,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getAllSidedLogIdentifier(WoodType $treeType) : BID{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_WOOD,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_WOOD,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_WOOD,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_WOOD,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_WOOD,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_WOOD,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_WOOD,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_HYPHAE,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_HYPHAE,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getLeavesIdentifier(LeavesType $leavesType) : BID{
|
||||
return new BID(match($leavesType->id()){
|
||||
LeavesType::OAK()->id() => Ids::OAK_LEAVES,
|
||||
LeavesType::SPRUCE()->id() => Ids::SPRUCE_LEAVES,
|
||||
LeavesType::BIRCH()->id() => Ids::BIRCH_LEAVES,
|
||||
LeavesType::JUNGLE()->id() => Ids::JUNGLE_LEAVES,
|
||||
LeavesType::ACACIA()->id() => Ids::ACACIA_LEAVES,
|
||||
LeavesType::DARK_OAK()->id() => Ids::DARK_OAK_LEAVES,
|
||||
LeavesType::MANGROVE()->id() => Ids::MANGROVE_LEAVES,
|
||||
LeavesType::AZALEA()->id() => Ids::AZALEA_LEAVES,
|
||||
LeavesType::FLOWERING_AZALEA()->id() => Ids::FLOWERING_AZALEA_LEAVES,
|
||||
default => throw new AssumptionFailedError("All leaves types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getSaplingIdentifier(TreeType $treeType) : BID{
|
||||
return new BID(match($treeType->id()){
|
||||
TreeType::OAK()->id() => Ids::OAK_SAPLING,
|
||||
TreeType::SPRUCE()->id() => Ids::SPRUCE_SAPLING,
|
||||
TreeType::BIRCH()->id() => Ids::BIRCH_SAPLING,
|
||||
TreeType::JUNGLE()->id() => Ids::JUNGLE_SAPLING,
|
||||
TreeType::ACACIA()->id() => Ids::ACACIA_SAPLING,
|
||||
TreeType::DARK_OAK()->id() => Ids::DARK_OAK_SAPLING,
|
||||
default => throw new AssumptionFailedError("All tree types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BID[]|\Closure[]
|
||||
* @phpstan-return array{BID, BID, \Closure() : \pocketmine\item\Item}
|
||||
*/
|
||||
public static function getWoodenSignInfo(WoodType $treeType) : array{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BID(Ids::SIGN_POST, 0, ItemIds::SIGN, TileSign::class);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BID(Ids::SPRUCE_STANDING_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BID(Ids::BIRCH_STANDING_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BID(Ids::JUNGLE_STANDING_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BID(Ids::ACACIA_STANDING_SIGN,0, ItemIds::ACACIA_SIGN, TileSign::class);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BID(Ids::DARKOAK_STANDING_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class);
|
||||
case WoodType::OAK()->id():
|
||||
return [
|
||||
new BID(Ids::OAK_SIGN, TileSign::class),
|
||||
new BID(Ids::OAK_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::OAK_SIGN()
|
||||
];
|
||||
case WoodType::SPRUCE()->id():
|
||||
return [
|
||||
new BID(Ids::SPRUCE_SIGN, TileSign::class),
|
||||
new BID(Ids::SPRUCE_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::SPRUCE_SIGN()
|
||||
];
|
||||
case WoodType::BIRCH()->id():
|
||||
return [
|
||||
new BID(Ids::BIRCH_SIGN, TileSign::class),
|
||||
new BID(Ids::BIRCH_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::BIRCH_SIGN()
|
||||
];
|
||||
case WoodType::JUNGLE()->id():
|
||||
return [
|
||||
new BID(Ids::JUNGLE_SIGN, TileSign::class),
|
||||
new BID(Ids::JUNGLE_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::JUNGLE_SIGN()
|
||||
];
|
||||
case WoodType::ACACIA()->id():
|
||||
return [
|
||||
new BID(Ids::ACACIA_SIGN, TileSign::class),
|
||||
new BID(Ids::ACACIA_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::ACACIA_SIGN()
|
||||
];
|
||||
case WoodType::DARK_OAK()->id():
|
||||
return [
|
||||
new BID(Ids::DARK_OAK_SIGN, TileSign::class),
|
||||
new BID(Ids::DARK_OAK_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::DARK_OAK_SIGN()
|
||||
];
|
||||
case WoodType::MANGROVE()->id():
|
||||
return [
|
||||
new BID(Ids::MANGROVE_SIGN, TileSign::class),
|
||||
new BID(Ids::MANGROVE_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::MANGROVE_SIGN()
|
||||
];
|
||||
case WoodType::CRIMSON()->id():
|
||||
return [
|
||||
new BID(Ids::CRIMSON_SIGN, TileSign::class),
|
||||
new BID(Ids::CRIMSON_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::CRIMSON_SIGN()
|
||||
];
|
||||
case WoodType::WARPED()->id():
|
||||
return [
|
||||
new BID(Ids::WARPED_SIGN, TileSign::class),
|
||||
new BID(Ids::WARPED_WALL_SIGN, TileSign::class),
|
||||
fn() => VanillaItems::WARPED_SIGN()
|
||||
];
|
||||
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenWallSignIdentifier(TreeType $treeType) : BID{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BID(Ids::WALL_SIGN, 0, ItemIds::SIGN, TileSign::class);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BID(Ids::SPRUCE_WALL_SIGN, 0, ItemIds::SPRUCE_SIGN, TileSign::class);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BID(Ids::BIRCH_WALL_SIGN, 0, ItemIds::BIRCH_SIGN, TileSign::class);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BID(Ids::JUNGLE_WALL_SIGN, 0, ItemIds::JUNGLE_SIGN, TileSign::class);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BID(Ids::ACACIA_WALL_SIGN, 0, ItemIds::ACACIA_SIGN, TileSign::class);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BID(Ids::DARKOAK_WALL_SIGN, 0, ItemIds::DARKOAK_SIGN, TileSign::class);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
public static function getWoodenTrapdoorIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_TRAPDOOR,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_TRAPDOOR,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_TRAPDOOR,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_TRAPDOOR,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_TRAPDOOR,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_TRAPDOOR,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_TRAPDOOR,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_TRAPDOOR,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_TRAPDOOR,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenTrapdoorIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::WOODEN_TRAPDOOR, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_TRAPDOOR, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_TRAPDOOR, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_TRAPDOOR, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_TRAPDOOR, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_TRAPDOOR, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
public static function getWoodenButtonIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_BUTTON,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_BUTTON,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_BUTTON,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_BUTTON,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_BUTTON,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_BUTTON,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_BUTTON,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_BUTTON,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_BUTTON,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenButtonIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::WOODEN_BUTTON, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_BUTTON, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_BUTTON, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_BUTTON, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_BUTTON, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_BUTTON, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
public static function getWoodenPressurePlateIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_PRESSURE_PLATE,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_PRESSURE_PLATE,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_PRESSURE_PLATE,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_PRESSURE_PLATE,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_PRESSURE_PLATE,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_PRESSURE_PLATE,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_PRESSURE_PLATE,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_PRESSURE_PLATE,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_PRESSURE_PLATE,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenPressurePlateIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::WOODEN_PRESSURE_PLATE, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_PRESSURE_PLATE, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_PRESSURE_PLATE, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_PRESSURE_PLATE, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_PRESSURE_PLATE, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_PRESSURE_PLATE, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
public static function getWoodenDoorIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_DOOR,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_DOOR,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_DOOR,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_DOOR,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_DOOR,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_DOOR,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_DOOR,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_DOOR,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_DOOR,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenDoorIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BID(Ids::OAK_DOOR_BLOCK, 0, ItemIds::OAK_DOOR);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BID(Ids::SPRUCE_DOOR_BLOCK, 0, ItemIds::SPRUCE_DOOR);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BID(Ids::BIRCH_DOOR_BLOCK, 0, ItemIds::BIRCH_DOOR);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BID(Ids::JUNGLE_DOOR_BLOCK, 0, ItemIds::JUNGLE_DOOR);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BID(Ids::ACACIA_DOOR_BLOCK, 0, ItemIds::ACACIA_DOOR);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BID(Ids::DARK_OAK_DOOR_BLOCK, 0, ItemIds::DARK_OAK_DOOR);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
public static function getWoodenFenceGateIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_FENCE_GATE,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_FENCE_GATE,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_FENCE_GATE,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_FENCE_GATE,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_FENCE_GATE,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_FENCE_GATE,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_FENCE_GATE,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_FENCE_GATE,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_FENCE_GATE,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public static function getWoodenFenceIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::OAK_FENCE_GATE, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_FENCE_GATE, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_FENCE_GATE, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_FENCE_GATE, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_FENCE_GATE, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_FENCE_GATE, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getWoodenStairsIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::OAK_STAIRS, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::SPRUCE_STAIRS, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::BIRCH_STAIRS, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::JUNGLE_STAIRS, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::ACACIA_STAIRS, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::DARK_OAK_STAIRS, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getStrippedLogIdentifier(TreeType $treeType) : BlockIdentifier{
|
||||
switch($treeType->id()){
|
||||
case TreeType::OAK()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_OAK_LOG, 0);
|
||||
case TreeType::SPRUCE()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_SPRUCE_LOG, 0);
|
||||
case TreeType::BIRCH()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_BIRCH_LOG, 0);
|
||||
case TreeType::JUNGLE()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_JUNGLE_LOG, 0);
|
||||
case TreeType::ACACIA()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_ACACIA_LOG, 0);
|
||||
case TreeType::DARK_OAK()->id():
|
||||
return new BlockIdentifier(Ids::STRIPPED_DARK_OAK_LOG, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all wood types");
|
||||
}
|
||||
|
||||
public static function getGlazedTerracottaIdentifier(DyeColor $color) : BlockIdentifier{
|
||||
switch($color->id()){
|
||||
case DyeColor::WHITE()->id():
|
||||
return new BlockIdentifier(Ids::WHITE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::ORANGE()->id():
|
||||
return new BlockIdentifier(Ids::ORANGE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::MAGENTA()->id():
|
||||
return new BlockIdentifier(Ids::MAGENTA_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::LIGHT_BLUE()->id():
|
||||
return new BlockIdentifier(Ids::LIGHT_BLUE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::YELLOW()->id():
|
||||
return new BlockIdentifier(Ids::YELLOW_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::LIME()->id():
|
||||
return new BlockIdentifier(Ids::LIME_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::PINK()->id():
|
||||
return new BlockIdentifier(Ids::PINK_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::GRAY()->id():
|
||||
return new BlockIdentifier(Ids::GRAY_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::LIGHT_GRAY()->id():
|
||||
return new BlockIdentifier(Ids::SILVER_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::CYAN()->id():
|
||||
return new BlockIdentifier(Ids::CYAN_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::PURPLE()->id():
|
||||
return new BlockIdentifier(Ids::PURPLE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::BLUE()->id():
|
||||
return new BlockIdentifier(Ids::BLUE_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::BROWN()->id():
|
||||
return new BlockIdentifier(Ids::BROWN_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::GREEN()->id():
|
||||
return new BlockIdentifier(Ids::GREEN_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::RED()->id():
|
||||
return new BlockIdentifier(Ids::RED_GLAZED_TERRACOTTA, 0);
|
||||
case DyeColor::BLACK()->id():
|
||||
return new BlockIdentifier(Ids::BLACK_GLAZED_TERRACOTTA, 0);
|
||||
}
|
||||
throw new AssumptionFailedError("Switch should cover all colours");
|
||||
}
|
||||
|
||||
public static function getStoneSlabIdentifier(int $stoneSlabId, int $meta) : BlockIdentifierFlattened{
|
||||
$id = [
|
||||
1 => [Ids::STONE_SLAB, Ids::DOUBLE_STONE_SLAB],
|
||||
2 => [Ids::STONE_SLAB2, Ids::DOUBLE_STONE_SLAB2],
|
||||
3 => [Ids::STONE_SLAB3, Ids::DOUBLE_STONE_SLAB3],
|
||||
4 => [Ids::STONE_SLAB4, Ids::DOUBLE_STONE_SLAB4]
|
||||
][$stoneSlabId] ?? null;
|
||||
if($id === null){
|
||||
throw new \InvalidArgumentException("Stone slab type should be 1, 2, 3 or 4");
|
||||
}
|
||||
return new BlockIdentifierFlattened($id[0], [$id[1]], $meta);
|
||||
public static function getWoodenStairsIdentifier(WoodType $treeType) : BlockIdentifier{
|
||||
return new BID(match($treeType->id()){
|
||||
WoodType::OAK()->id() => Ids::OAK_STAIRS,
|
||||
WoodType::SPRUCE()->id() => Ids::SPRUCE_STAIRS,
|
||||
WoodType::BIRCH()->id() => Ids::BIRCH_STAIRS,
|
||||
WoodType::JUNGLE()->id() => Ids::JUNGLE_STAIRS,
|
||||
WoodType::ACACIA()->id() => Ids::ACACIA_STAIRS,
|
||||
WoodType::DARK_OAK()->id() => Ids::DARK_OAK_STAIRS,
|
||||
WoodType::MANGROVE()->id() => Ids::MANGROVE_STAIRS,
|
||||
WoodType::CRIMSON()->id() => Ids::CRIMSON_STAIRS,
|
||||
WoodType::WARPED()->id() => Ids::WARPED_STAIRS,
|
||||
default => throw new AssumptionFailedError("All wood types should be covered")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,501 +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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
final class BlockLegacyIds{
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
public const AIR = 0;
|
||||
public const STONE = 1;
|
||||
public const GRASS = 2;
|
||||
public const DIRT = 3;
|
||||
public const COBBLESTONE = 4;
|
||||
public const PLANKS = 5, WOODEN_PLANKS = 5;
|
||||
public const SAPLING = 6;
|
||||
public const BEDROCK = 7;
|
||||
public const FLOWING_WATER = 8;
|
||||
public const STILL_WATER = 9, WATER = 9;
|
||||
public const FLOWING_LAVA = 10;
|
||||
public const LAVA = 11, STILL_LAVA = 11;
|
||||
public const SAND = 12;
|
||||
public const GRAVEL = 13;
|
||||
public const GOLD_ORE = 14;
|
||||
public const IRON_ORE = 15;
|
||||
public const COAL_ORE = 16;
|
||||
public const LOG = 17;
|
||||
public const LEAVES = 18;
|
||||
public const SPONGE = 19;
|
||||
public const GLASS = 20;
|
||||
public const LAPIS_ORE = 21;
|
||||
public const LAPIS_BLOCK = 22;
|
||||
public const DISPENSER = 23;
|
||||
public const SANDSTONE = 24;
|
||||
public const NOTEBLOCK = 25, NOTE_BLOCK = 25;
|
||||
public const BED_BLOCK = 26;
|
||||
public const GOLDEN_RAIL = 27, POWERED_RAIL = 27;
|
||||
public const DETECTOR_RAIL = 28;
|
||||
public const STICKY_PISTON = 29;
|
||||
public const COBWEB = 30, WEB = 30;
|
||||
public const TALLGRASS = 31, TALL_GRASS = 31;
|
||||
public const DEADBUSH = 32, DEAD_BUSH = 32;
|
||||
public const PISTON = 33;
|
||||
public const PISTONARMCOLLISION = 34, PISTON_ARM_COLLISION = 34;
|
||||
public const WOOL = 35;
|
||||
public const ELEMENT_0 = 36;
|
||||
public const DANDELION = 37, YELLOW_FLOWER = 37;
|
||||
public const POPPY = 38, RED_FLOWER = 38;
|
||||
public const BROWN_MUSHROOM = 39;
|
||||
public const RED_MUSHROOM = 40;
|
||||
public const GOLD_BLOCK = 41;
|
||||
public const IRON_BLOCK = 42;
|
||||
public const DOUBLE_STONE_SLAB = 43;
|
||||
public const STONE_SLAB = 44;
|
||||
public const BRICK_BLOCK = 45;
|
||||
public const TNT = 46;
|
||||
public const BOOKSHELF = 47;
|
||||
public const MOSSY_COBBLESTONE = 48, MOSS_STONE = 48;
|
||||
public const OBSIDIAN = 49;
|
||||
public const TORCH = 50;
|
||||
public const FIRE = 51;
|
||||
public const MOB_SPAWNER = 52, MONSTER_SPAWNER = 52;
|
||||
public const OAK_STAIRS = 53, WOODEN_STAIRS = 53;
|
||||
public const CHEST = 54;
|
||||
public const REDSTONE_WIRE = 55;
|
||||
public const DIAMOND_ORE = 56;
|
||||
public const DIAMOND_BLOCK = 57;
|
||||
public const CRAFTING_TABLE = 58, WORKBENCH = 58;
|
||||
public const WHEAT_BLOCK = 59;
|
||||
public const FARMLAND = 60;
|
||||
public const FURNACE = 61;
|
||||
public const BURNING_FURNACE = 62, LIT_FURNACE = 62;
|
||||
public const SIGN_POST = 63, STANDING_SIGN = 63;
|
||||
public const OAK_DOOR_BLOCK = 64, WOODEN_DOOR_BLOCK = 64;
|
||||
public const LADDER = 65;
|
||||
public const RAIL = 66;
|
||||
public const COBBLESTONE_STAIRS = 67, STONE_STAIRS = 67;
|
||||
public const WALL_SIGN = 68;
|
||||
public const LEVER = 69;
|
||||
public const STONE_PRESSURE_PLATE = 70;
|
||||
public const IRON_DOOR_BLOCK = 71;
|
||||
public const WOODEN_PRESSURE_PLATE = 72;
|
||||
public const REDSTONE_ORE = 73;
|
||||
public const GLOWING_REDSTONE_ORE = 74, LIT_REDSTONE_ORE = 74;
|
||||
public const UNLIT_REDSTONE_TORCH = 75;
|
||||
public const LIT_REDSTONE_TORCH = 76, REDSTONE_TORCH = 76;
|
||||
public const STONE_BUTTON = 77;
|
||||
public const SNOW_LAYER = 78;
|
||||
public const ICE = 79;
|
||||
public const SNOW = 80, SNOW_BLOCK = 80;
|
||||
public const CACTUS = 81;
|
||||
public const CLAY_BLOCK = 82;
|
||||
public const REEDS_BLOCK = 83, SUGARCANE_BLOCK = 83;
|
||||
public const JUKEBOX = 84;
|
||||
public const FENCE = 85;
|
||||
public const PUMPKIN = 86;
|
||||
public const NETHERRACK = 87;
|
||||
public const SOUL_SAND = 88;
|
||||
public const GLOWSTONE = 89;
|
||||
public const PORTAL = 90;
|
||||
public const JACK_O_LANTERN = 91, LIT_PUMPKIN = 91;
|
||||
public const CAKE_BLOCK = 92;
|
||||
public const REPEATER_BLOCK = 93, UNPOWERED_REPEATER = 93;
|
||||
public const POWERED_REPEATER = 94;
|
||||
public const INVISIBLEBEDROCK = 95, INVISIBLE_BEDROCK = 95;
|
||||
public const TRAPDOOR = 96, WOODEN_TRAPDOOR = 96;
|
||||
public const MONSTER_EGG = 97;
|
||||
public const STONEBRICK = 98, STONE_BRICK = 98, STONE_BRICKS = 98;
|
||||
public const BROWN_MUSHROOM_BLOCK = 99;
|
||||
public const RED_MUSHROOM_BLOCK = 100;
|
||||
public const IRON_BARS = 101;
|
||||
public const GLASS_PANE = 102;
|
||||
public const MELON_BLOCK = 103;
|
||||
public const PUMPKIN_STEM = 104;
|
||||
public const MELON_STEM = 105;
|
||||
public const VINE = 106, VINES = 106;
|
||||
public const FENCE_GATE = 107, OAK_FENCE_GATE = 107;
|
||||
public const BRICK_STAIRS = 108;
|
||||
public const STONE_BRICK_STAIRS = 109;
|
||||
public const MYCELIUM = 110;
|
||||
public const LILY_PAD = 111, WATERLILY = 111, WATER_LILY = 111;
|
||||
public const NETHER_BRICK_BLOCK = 112;
|
||||
public const NETHER_BRICK_FENCE = 113;
|
||||
public const NETHER_BRICK_STAIRS = 114;
|
||||
public const NETHER_WART_PLANT = 115;
|
||||
public const ENCHANTING_TABLE = 116, ENCHANTMENT_TABLE = 116;
|
||||
public const BREWING_STAND_BLOCK = 117;
|
||||
public const CAULDRON_BLOCK = 118;
|
||||
public const END_PORTAL = 119;
|
||||
public const END_PORTAL_FRAME = 120;
|
||||
public const END_STONE = 121;
|
||||
public const DRAGON_EGG = 122;
|
||||
public const REDSTONE_LAMP = 123;
|
||||
public const LIT_REDSTONE_LAMP = 124;
|
||||
public const DROPPER = 125;
|
||||
public const ACTIVATOR_RAIL = 126;
|
||||
public const COCOA = 127, COCOA_BLOCK = 127;
|
||||
public const SANDSTONE_STAIRS = 128;
|
||||
public const EMERALD_ORE = 129;
|
||||
public const ENDER_CHEST = 130;
|
||||
public const TRIPWIRE_HOOK = 131;
|
||||
public const TRIPWIRE = 132, TRIP_WIRE = 132;
|
||||
public const EMERALD_BLOCK = 133;
|
||||
public const SPRUCE_STAIRS = 134;
|
||||
public const BIRCH_STAIRS = 135;
|
||||
public const JUNGLE_STAIRS = 136;
|
||||
public const COMMAND_BLOCK = 137;
|
||||
public const BEACON = 138;
|
||||
public const COBBLESTONE_WALL = 139, STONE_WALL = 139;
|
||||
public const FLOWER_POT_BLOCK = 140;
|
||||
public const CARROTS = 141, CARROT_BLOCK = 141;
|
||||
public const POTATOES = 142, POTATO_BLOCK = 142;
|
||||
public const WOODEN_BUTTON = 143;
|
||||
public const MOB_HEAD_BLOCK = 144, SKULL_BLOCK = 144;
|
||||
public const ANVIL = 145;
|
||||
public const TRAPPED_CHEST = 146;
|
||||
public const LIGHT_WEIGHTED_PRESSURE_PLATE = 147;
|
||||
public const HEAVY_WEIGHTED_PRESSURE_PLATE = 148;
|
||||
public const COMPARATOR_BLOCK = 149, UNPOWERED_COMPARATOR = 149;
|
||||
public const POWERED_COMPARATOR = 150;
|
||||
public const DAYLIGHT_DETECTOR = 151, DAYLIGHT_SENSOR = 151;
|
||||
public const REDSTONE_BLOCK = 152;
|
||||
public const NETHER_QUARTZ_ORE = 153, QUARTZ_ORE = 153;
|
||||
public const HOPPER_BLOCK = 154;
|
||||
public const QUARTZ_BLOCK = 155;
|
||||
public const QUARTZ_STAIRS = 156;
|
||||
public const DOUBLE_WOODEN_SLAB = 157;
|
||||
public const WOODEN_SLAB = 158;
|
||||
public const STAINED_CLAY = 159, STAINED_HARDENED_CLAY = 159, TERRACOTTA = 159;
|
||||
public const STAINED_GLASS_PANE = 160;
|
||||
public const LEAVES2 = 161;
|
||||
public const LOG2 = 162;
|
||||
public const ACACIA_STAIRS = 163;
|
||||
public const DARK_OAK_STAIRS = 164;
|
||||
public const SLIME = 165, SLIME_BLOCK = 165;
|
||||
public const GLOW_STICK = 166;
|
||||
public const IRON_TRAPDOOR = 167;
|
||||
public const PRISMARINE = 168;
|
||||
public const SEALANTERN = 169, SEA_LANTERN = 169;
|
||||
public const HAY_BALE = 170, HAY_BLOCK = 170;
|
||||
public const CARPET = 171;
|
||||
public const HARDENED_CLAY = 172;
|
||||
public const COAL_BLOCK = 173;
|
||||
public const PACKED_ICE = 174;
|
||||
public const DOUBLE_PLANT = 175;
|
||||
public const STANDING_BANNER = 176;
|
||||
public const WALL_BANNER = 177;
|
||||
public const DAYLIGHT_DETECTOR_INVERTED = 178, DAYLIGHT_SENSOR_INVERTED = 178;
|
||||
public const RED_SANDSTONE = 179;
|
||||
public const RED_SANDSTONE_STAIRS = 180;
|
||||
public const DOUBLE_STONE_SLAB2 = 181;
|
||||
public const STONE_SLAB2 = 182;
|
||||
public const SPRUCE_FENCE_GATE = 183;
|
||||
public const BIRCH_FENCE_GATE = 184;
|
||||
public const JUNGLE_FENCE_GATE = 185;
|
||||
public const DARK_OAK_FENCE_GATE = 186;
|
||||
public const ACACIA_FENCE_GATE = 187;
|
||||
public const REPEATING_COMMAND_BLOCK = 188;
|
||||
public const CHAIN_COMMAND_BLOCK = 189;
|
||||
public const HARD_GLASS_PANE = 190;
|
||||
public const HARD_STAINED_GLASS_PANE = 191;
|
||||
public const CHEMICAL_HEAT = 192;
|
||||
public const SPRUCE_DOOR_BLOCK = 193;
|
||||
public const BIRCH_DOOR_BLOCK = 194;
|
||||
public const JUNGLE_DOOR_BLOCK = 195;
|
||||
public const ACACIA_DOOR_BLOCK = 196;
|
||||
public const DARK_OAK_DOOR_BLOCK = 197;
|
||||
public const GRASS_PATH = 198;
|
||||
public const FRAME_BLOCK = 199, ITEM_FRAME_BLOCK = 199;
|
||||
public const CHORUS_FLOWER = 200;
|
||||
public const PURPUR_BLOCK = 201;
|
||||
public const COLORED_TORCH_RG = 202;
|
||||
public const PURPUR_STAIRS = 203;
|
||||
public const COLORED_TORCH_BP = 204;
|
||||
public const UNDYED_SHULKER_BOX = 205;
|
||||
public const END_BRICKS = 206;
|
||||
public const FROSTED_ICE = 207;
|
||||
public const END_ROD = 208;
|
||||
public const END_GATEWAY = 209;
|
||||
|
||||
public const MAGMA = 213;
|
||||
public const NETHER_WART_BLOCK = 214;
|
||||
public const RED_NETHER_BRICK = 215;
|
||||
public const BONE_BLOCK = 216;
|
||||
|
||||
public const SHULKER_BOX = 218;
|
||||
public const PURPLE_GLAZED_TERRACOTTA = 219;
|
||||
public const WHITE_GLAZED_TERRACOTTA = 220;
|
||||
public const ORANGE_GLAZED_TERRACOTTA = 221;
|
||||
public const MAGENTA_GLAZED_TERRACOTTA = 222;
|
||||
public const LIGHT_BLUE_GLAZED_TERRACOTTA = 223;
|
||||
public const YELLOW_GLAZED_TERRACOTTA = 224;
|
||||
public const LIME_GLAZED_TERRACOTTA = 225;
|
||||
public const PINK_GLAZED_TERRACOTTA = 226;
|
||||
public const GRAY_GLAZED_TERRACOTTA = 227;
|
||||
public const SILVER_GLAZED_TERRACOTTA = 228;
|
||||
public const CYAN_GLAZED_TERRACOTTA = 229;
|
||||
|
||||
public const BLUE_GLAZED_TERRACOTTA = 231;
|
||||
public const BROWN_GLAZED_TERRACOTTA = 232;
|
||||
public const GREEN_GLAZED_TERRACOTTA = 233;
|
||||
public const RED_GLAZED_TERRACOTTA = 234;
|
||||
public const BLACK_GLAZED_TERRACOTTA = 235;
|
||||
public const CONCRETE = 236;
|
||||
public const CONCRETEPOWDER = 237, CONCRETE_POWDER = 237;
|
||||
public const CHEMISTRY_TABLE = 238;
|
||||
public const UNDERWATER_TORCH = 239;
|
||||
public const CHORUS_PLANT = 240;
|
||||
public const STAINED_GLASS = 241;
|
||||
|
||||
public const PODZOL = 243;
|
||||
public const BEETROOT_BLOCK = 244;
|
||||
public const STONECUTTER = 245;
|
||||
public const GLOWINGOBSIDIAN = 246, GLOWING_OBSIDIAN = 246;
|
||||
public const NETHERREACTOR = 247, NETHER_REACTOR = 247;
|
||||
public const INFO_UPDATE = 248;
|
||||
public const INFO_UPDATE2 = 249;
|
||||
public const MOVINGBLOCK = 250, MOVING_BLOCK = 250;
|
||||
public const OBSERVER = 251;
|
||||
public const STRUCTURE_BLOCK = 252;
|
||||
public const HARD_GLASS = 253;
|
||||
public const HARD_STAINED_GLASS = 254;
|
||||
public const RESERVED6 = 255;
|
||||
|
||||
public const PRISMARINE_STAIRS = 257;
|
||||
public const DARK_PRISMARINE_STAIRS = 258;
|
||||
public const PRISMARINE_BRICKS_STAIRS = 259;
|
||||
public const STRIPPED_SPRUCE_LOG = 260;
|
||||
public const STRIPPED_BIRCH_LOG = 261;
|
||||
public const STRIPPED_JUNGLE_LOG = 262;
|
||||
public const STRIPPED_ACACIA_LOG = 263;
|
||||
public const STRIPPED_DARK_OAK_LOG = 264;
|
||||
public const STRIPPED_OAK_LOG = 265;
|
||||
public const BLUE_ICE = 266;
|
||||
public const ELEMENT_1 = 267;
|
||||
public const ELEMENT_2 = 268;
|
||||
public const ELEMENT_3 = 269;
|
||||
public const ELEMENT_4 = 270;
|
||||
public const ELEMENT_5 = 271;
|
||||
public const ELEMENT_6 = 272;
|
||||
public const ELEMENT_7 = 273;
|
||||
public const ELEMENT_8 = 274;
|
||||
public const ELEMENT_9 = 275;
|
||||
public const ELEMENT_10 = 276;
|
||||
public const ELEMENT_11 = 277;
|
||||
public const ELEMENT_12 = 278;
|
||||
public const ELEMENT_13 = 279;
|
||||
public const ELEMENT_14 = 280;
|
||||
public const ELEMENT_15 = 281;
|
||||
public const ELEMENT_16 = 282;
|
||||
public const ELEMENT_17 = 283;
|
||||
public const ELEMENT_18 = 284;
|
||||
public const ELEMENT_19 = 285;
|
||||
public const ELEMENT_20 = 286;
|
||||
public const ELEMENT_21 = 287;
|
||||
public const ELEMENT_22 = 288;
|
||||
public const ELEMENT_23 = 289;
|
||||
public const ELEMENT_24 = 290;
|
||||
public const ELEMENT_25 = 291;
|
||||
public const ELEMENT_26 = 292;
|
||||
public const ELEMENT_27 = 293;
|
||||
public const ELEMENT_28 = 294;
|
||||
public const ELEMENT_29 = 295;
|
||||
public const ELEMENT_30 = 296;
|
||||
public const ELEMENT_31 = 297;
|
||||
public const ELEMENT_32 = 298;
|
||||
public const ELEMENT_33 = 299;
|
||||
public const ELEMENT_34 = 300;
|
||||
public const ELEMENT_35 = 301;
|
||||
public const ELEMENT_36 = 302;
|
||||
public const ELEMENT_37 = 303;
|
||||
public const ELEMENT_38 = 304;
|
||||
public const ELEMENT_39 = 305;
|
||||
public const ELEMENT_40 = 306;
|
||||
public const ELEMENT_41 = 307;
|
||||
public const ELEMENT_42 = 308;
|
||||
public const ELEMENT_43 = 309;
|
||||
public const ELEMENT_44 = 310;
|
||||
public const ELEMENT_45 = 311;
|
||||
public const ELEMENT_46 = 312;
|
||||
public const ELEMENT_47 = 313;
|
||||
public const ELEMENT_48 = 314;
|
||||
public const ELEMENT_49 = 315;
|
||||
public const ELEMENT_50 = 316;
|
||||
public const ELEMENT_51 = 317;
|
||||
public const ELEMENT_52 = 318;
|
||||
public const ELEMENT_53 = 319;
|
||||
public const ELEMENT_54 = 320;
|
||||
public const ELEMENT_55 = 321;
|
||||
public const ELEMENT_56 = 322;
|
||||
public const ELEMENT_57 = 323;
|
||||
public const ELEMENT_58 = 324;
|
||||
public const ELEMENT_59 = 325;
|
||||
public const ELEMENT_60 = 326;
|
||||
public const ELEMENT_61 = 327;
|
||||
public const ELEMENT_62 = 328;
|
||||
public const ELEMENT_63 = 329;
|
||||
public const ELEMENT_64 = 330;
|
||||
public const ELEMENT_65 = 331;
|
||||
public const ELEMENT_66 = 332;
|
||||
public const ELEMENT_67 = 333;
|
||||
public const ELEMENT_68 = 334;
|
||||
public const ELEMENT_69 = 335;
|
||||
public const ELEMENT_70 = 336;
|
||||
public const ELEMENT_71 = 337;
|
||||
public const ELEMENT_72 = 338;
|
||||
public const ELEMENT_73 = 339;
|
||||
public const ELEMENT_74 = 340;
|
||||
public const ELEMENT_75 = 341;
|
||||
public const ELEMENT_76 = 342;
|
||||
public const ELEMENT_77 = 343;
|
||||
public const ELEMENT_78 = 344;
|
||||
public const ELEMENT_79 = 345;
|
||||
public const ELEMENT_80 = 346;
|
||||
public const ELEMENT_81 = 347;
|
||||
public const ELEMENT_82 = 348;
|
||||
public const ELEMENT_83 = 349;
|
||||
public const ELEMENT_84 = 350;
|
||||
public const ELEMENT_85 = 351;
|
||||
public const ELEMENT_86 = 352;
|
||||
public const ELEMENT_87 = 353;
|
||||
public const ELEMENT_88 = 354;
|
||||
public const ELEMENT_89 = 355;
|
||||
public const ELEMENT_90 = 356;
|
||||
public const ELEMENT_91 = 357;
|
||||
public const ELEMENT_92 = 358;
|
||||
public const ELEMENT_93 = 359;
|
||||
public const ELEMENT_94 = 360;
|
||||
public const ELEMENT_95 = 361;
|
||||
public const ELEMENT_96 = 362;
|
||||
public const ELEMENT_97 = 363;
|
||||
public const ELEMENT_98 = 364;
|
||||
public const ELEMENT_99 = 365;
|
||||
public const ELEMENT_100 = 366;
|
||||
public const ELEMENT_101 = 367;
|
||||
public const ELEMENT_102 = 368;
|
||||
public const ELEMENT_103 = 369;
|
||||
public const ELEMENT_104 = 370;
|
||||
public const ELEMENT_105 = 371;
|
||||
public const ELEMENT_106 = 372;
|
||||
public const ELEMENT_107 = 373;
|
||||
public const ELEMENT_108 = 374;
|
||||
public const ELEMENT_109 = 375;
|
||||
public const ELEMENT_110 = 376;
|
||||
public const ELEMENT_111 = 377;
|
||||
public const ELEMENT_112 = 378;
|
||||
public const ELEMENT_113 = 379;
|
||||
public const ELEMENT_114 = 380;
|
||||
public const ELEMENT_115 = 381;
|
||||
public const ELEMENT_116 = 382;
|
||||
public const ELEMENT_117 = 383;
|
||||
public const ELEMENT_118 = 384;
|
||||
public const SEAGRASS = 385;
|
||||
public const CORAL = 386;
|
||||
public const CORAL_BLOCK = 387;
|
||||
public const CORAL_FAN = 388;
|
||||
public const CORAL_FAN_DEAD = 389;
|
||||
public const CORAL_FAN_HANG = 390;
|
||||
public const CORAL_FAN_HANG2 = 391;
|
||||
public const CORAL_FAN_HANG3 = 392;
|
||||
public const KELP = 393;
|
||||
public const DRIED_KELP_BLOCK = 394;
|
||||
public const ACACIA_BUTTON = 395;
|
||||
public const BIRCH_BUTTON = 396;
|
||||
public const DARK_OAK_BUTTON = 397;
|
||||
public const JUNGLE_BUTTON = 398;
|
||||
public const SPRUCE_BUTTON = 399;
|
||||
public const ACACIA_TRAPDOOR = 400;
|
||||
public const BIRCH_TRAPDOOR = 401;
|
||||
public const DARK_OAK_TRAPDOOR = 402;
|
||||
public const JUNGLE_TRAPDOOR = 403;
|
||||
public const SPRUCE_TRAPDOOR = 404;
|
||||
public const ACACIA_PRESSURE_PLATE = 405;
|
||||
public const BIRCH_PRESSURE_PLATE = 406;
|
||||
public const DARK_OAK_PRESSURE_PLATE = 407;
|
||||
public const JUNGLE_PRESSURE_PLATE = 408;
|
||||
public const SPRUCE_PRESSURE_PLATE = 409;
|
||||
public const CARVED_PUMPKIN = 410;
|
||||
public const SEA_PICKLE = 411;
|
||||
public const CONDUIT = 412;
|
||||
|
||||
public const TURTLE_EGG = 414;
|
||||
public const BUBBLE_COLUMN = 415;
|
||||
public const BARRIER = 416;
|
||||
public const STONE_SLAB3 = 417;
|
||||
public const BAMBOO = 418;
|
||||
public const BAMBOO_SAPLING = 419;
|
||||
public const SCAFFOLDING = 420;
|
||||
public const STONE_SLAB4 = 421;
|
||||
public const DOUBLE_STONE_SLAB3 = 422;
|
||||
public const DOUBLE_STONE_SLAB4 = 423;
|
||||
public const GRANITE_STAIRS = 424;
|
||||
public const DIORITE_STAIRS = 425;
|
||||
public const ANDESITE_STAIRS = 426;
|
||||
public const POLISHED_GRANITE_STAIRS = 427;
|
||||
public const POLISHED_DIORITE_STAIRS = 428;
|
||||
public const POLISHED_ANDESITE_STAIRS = 429;
|
||||
public const MOSSY_STONE_BRICK_STAIRS = 430;
|
||||
public const SMOOTH_RED_SANDSTONE_STAIRS = 431;
|
||||
public const SMOOTH_SANDSTONE_STAIRS = 432;
|
||||
public const END_BRICK_STAIRS = 433;
|
||||
public const MOSSY_COBBLESTONE_STAIRS = 434;
|
||||
public const NORMAL_STONE_STAIRS = 435;
|
||||
public const SPRUCE_STANDING_SIGN = 436;
|
||||
public const SPRUCE_WALL_SIGN = 437;
|
||||
public const SMOOTH_STONE = 438;
|
||||
public const RED_NETHER_BRICK_STAIRS = 439;
|
||||
public const SMOOTH_QUARTZ_STAIRS = 440;
|
||||
public const BIRCH_STANDING_SIGN = 441;
|
||||
public const BIRCH_WALL_SIGN = 442;
|
||||
public const JUNGLE_STANDING_SIGN = 443;
|
||||
public const JUNGLE_WALL_SIGN = 444;
|
||||
public const ACACIA_STANDING_SIGN = 445;
|
||||
public const ACACIA_WALL_SIGN = 446;
|
||||
public const DARKOAK_STANDING_SIGN = 447;
|
||||
public const DARKOAK_WALL_SIGN = 448;
|
||||
public const LECTERN = 449;
|
||||
public const GRINDSTONE = 450;
|
||||
public const BLAST_FURNACE = 451;
|
||||
public const STONECUTTER_BLOCK = 452;
|
||||
public const SMOKER = 453;
|
||||
public const LIT_SMOKER = 454;
|
||||
public const CARTOGRAPHY_TABLE = 455;
|
||||
public const FLETCHING_TABLE = 456;
|
||||
public const SMITHING_TABLE = 457;
|
||||
public const BARREL = 458;
|
||||
public const LOOM = 459;
|
||||
|
||||
public const BELL = 461;
|
||||
public const SWEET_BERRY_BUSH = 462;
|
||||
public const LANTERN = 463;
|
||||
public const CAMPFIRE = 464;
|
||||
public const LAVA_CAULDRON = 465;
|
||||
public const JIGSAW = 466;
|
||||
public const WOOD = 467;
|
||||
public const COMPOSTER = 468;
|
||||
public const LIT_BLAST_FURNACE = 469;
|
||||
|
||||
}
|
@ -1,303 +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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
/**
|
||||
* Constants for legacy metadata for various blocks.
|
||||
*/
|
||||
final class BlockLegacyMetadata{
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
public const ANVIL_NORMAL = 0;
|
||||
public const ANVIL_SLIGHTLY_DAMAGED = 4;
|
||||
public const ANVIL_VERY_DAMAGED = 8;
|
||||
|
||||
public const BAMBOO_FLAG_THICK = 0x01;
|
||||
public const BAMBOO_FLAG_READY = 0x08;
|
||||
|
||||
public const BAMBOO_LEAF_SIZE_SHIFT = 1;
|
||||
public const BAMBOO_LEAF_SIZE_MASK = 0x03;
|
||||
|
||||
public const BAMBOO_SAPLING_FLAG_READY = 0x01;
|
||||
|
||||
public const BARREL_FLAG_OPEN = 0x08;
|
||||
|
||||
public const BED_FLAG_HEAD = 0x08;
|
||||
public const BED_FLAG_OCCUPIED = 0x04;
|
||||
|
||||
public const BEDROCK_FLAG_INFINIBURN = 0x01;
|
||||
|
||||
public const BELL_ATTACHMENT_FLOOR = 0;
|
||||
public const BELL_ATTACHMENT_CEILING = 1;
|
||||
public const BELL_ATTACHMENT_ONE_WALL = 2;
|
||||
public const BELL_ATTACHMENT_TWO_WALLS = 3;
|
||||
|
||||
public const BREWING_STAND_FLAG_EAST = 0x01;
|
||||
public const BREWING_STAND_FLAG_SOUTHWEST = 0x02;
|
||||
public const BREWING_STAND_FLAG_NORTHWEST = 0x04;
|
||||
|
||||
public const BUTTON_FLAG_POWERED = 0x08;
|
||||
|
||||
public const CHEMISTRY_COMPOUND_CREATOR = 0;
|
||||
public const CHEMISTRY_MATERIAL_REDUCER = 4;
|
||||
public const CHEMISTRY_ELEMENT_CONSTRUCTOR = 8;
|
||||
public const CHEMISTRY_LAB_TABLE = 12;
|
||||
|
||||
public const COLORED_TORCH_BP_BLUE = 0;
|
||||
public const COLORED_TORCH_BP_PURPLE = 8;
|
||||
public const COLORED_TORCH_RG_RED = 0;
|
||||
public const COLORED_TORCH_RG_GREEN = 8;
|
||||
|
||||
public const CORAL_BLOCK_FLAG_DEAD = 0x8;
|
||||
|
||||
public const CORAL_FAN_EAST_WEST = 0;
|
||||
public const CORAL_FAN_NORTH_SOUTH = 1;
|
||||
public const CORAL_FAN_TYPE_MASK = 0x7;
|
||||
|
||||
public const CORAL_FAN_HANG_FLAG_DEAD = 0x2;
|
||||
|
||||
public const CORAL_FAN_HANG_TUBE = 0;
|
||||
public const CORAL_FAN_HANG_BRAIN = 1;
|
||||
public const CORAL_FAN_HANG2_BUBBLE = 0;
|
||||
public const CORAL_FAN_HANG2_FIRE = 1;
|
||||
public const CORAL_FAN_HANG3_HORN = 0;
|
||||
public const CORAL_FAN_HANG_TYPE_MASK = 0x1;
|
||||
|
||||
public const CORAL_VARIANT_TUBE = 0;
|
||||
public const CORAL_VARIANT_BRAIN = 1;
|
||||
public const CORAL_VARIANT_BUBBLE = 2;
|
||||
public const CORAL_VARIANT_FIRE = 3;
|
||||
public const CORAL_VARIANT_HORN = 4;
|
||||
|
||||
public const DIRT_FLAG_COARSE = 0x1;
|
||||
|
||||
public const DOOR_FLAG_TOP = 0x08;
|
||||
public const DOOR_BOTTOM_FLAG_OPEN = 0x04;
|
||||
public const DOOR_TOP_FLAG_RIGHT = 0x01;
|
||||
public const DOOR_TOP_FLAG_POWERED = 0x02;
|
||||
|
||||
public const DOUBLE_PLANT_SUNFLOWER = 0;
|
||||
public const DOUBLE_PLANT_LILAC = 1;
|
||||
public const DOUBLE_PLANT_TALLGRASS = 2;
|
||||
public const DOUBLE_PLANT_LARGE_FERN = 3;
|
||||
public const DOUBLE_PLANT_ROSE_BUSH = 4;
|
||||
public const DOUBLE_PLANT_PEONY = 5;
|
||||
|
||||
public const DOUBLE_PLANT_FLAG_TOP = 0x08;
|
||||
|
||||
public const END_PORTAL_FRAME_FLAG_EYE = 0x04;
|
||||
|
||||
public const FENCE_GATE_FLAG_OPEN = 0x04;
|
||||
public const FENCE_GATE_FLAG_IN_WALL = 0x08;
|
||||
|
||||
public const FLOWER_POPPY = 0;
|
||||
public const FLOWER_BLUE_ORCHID = 1;
|
||||
public const FLOWER_ALLIUM = 2;
|
||||
public const FLOWER_AZURE_BLUET = 3;
|
||||
public const FLOWER_RED_TULIP = 4;
|
||||
public const FLOWER_ORANGE_TULIP = 5;
|
||||
public const FLOWER_WHITE_TULIP = 6;
|
||||
public const FLOWER_PINK_TULIP = 7;
|
||||
public const FLOWER_OXEYE_DAISY = 8;
|
||||
public const FLOWER_CORNFLOWER = 9;
|
||||
public const FLOWER_LILY_OF_THE_VALLEY = 10;
|
||||
|
||||
public const FLOWER_POT_FLAG_OCCUPIED = 0x01;
|
||||
|
||||
public const HOPPER_FLAG_POWERED = 0x08;
|
||||
|
||||
public const INFESTED_STONE = 0;
|
||||
public const INFESTED_COBBLESTONE = 1;
|
||||
public const INFESTED_STONE_BRICK = 2;
|
||||
public const INFESTED_STONE_BRICK_MOSSY = 3;
|
||||
public const INFESTED_STONE_BRICK_CRACKED = 4;
|
||||
public const INFESTED_STONE_BRICK_CHISELED = 5;
|
||||
|
||||
public const ITEM_FRAME_FLAG_HAS_MAP = 0x04;
|
||||
|
||||
public const LANTERN_FLAG_HANGING = 0x01;
|
||||
|
||||
public const LEAVES_FLAG_NO_DECAY = 0x04;
|
||||
public const LEAVES_FLAG_CHECK_DECAY = 0x08;
|
||||
|
||||
public const LECTERN_FLAG_POWERED = 0x04;
|
||||
|
||||
public const LEVER_FLAG_POWERED = 0x08;
|
||||
|
||||
public const LIQUID_FLAG_FALLING = 0x08;
|
||||
|
||||
public const MUSHROOM_BLOCK_ALL_PORES = 0;
|
||||
public const MUSHROOM_BLOCK_CAP_NORTHWEST_CORNER = 1;
|
||||
public const MUSHROOM_BLOCK_CAP_NORTH_SIDE = 2;
|
||||
public const MUSHROOM_BLOCK_CAP_NORTHEAST_CORNER = 3;
|
||||
public const MUSHROOM_BLOCK_CAP_WEST_SIDE = 4;
|
||||
public const MUSHROOM_BLOCK_CAP_TOP_ONLY = 5;
|
||||
public const MUSHROOM_BLOCK_CAP_EAST_SIDE = 6;
|
||||
public const MUSHROOM_BLOCK_CAP_SOUTHWEST_CORNER = 7;
|
||||
public const MUSHROOM_BLOCK_CAP_SOUTH_SIDE = 8;
|
||||
public const MUSHROOM_BLOCK_CAP_SOUTHEAST_CORNER = 9;
|
||||
public const MUSHROOM_BLOCK_STEM = 10;
|
||||
//11, 12 and 13 appear the same as 0
|
||||
public const MUSHROOM_BLOCK_ALL_CAP = 14;
|
||||
public const MUSHROOM_BLOCK_ALL_STEM = 15;
|
||||
|
||||
public const NETHER_PORTAL_AXIS_X = 1;
|
||||
public const NETHER_PORTAL_AXIS_Z = 2;
|
||||
|
||||
public const NETHER_REACTOR_INACTIVE = 0;
|
||||
public const NETHER_REACTOR_ACTIVE = 1;
|
||||
public const NETHER_REACTOR_USED = 2;
|
||||
|
||||
public const PRESSURE_PLATE_FLAG_POWERED = 0x01;
|
||||
|
||||
public const PRISMARINE_NORMAL = 0;
|
||||
public const PRISMARINE_DARK = 1;
|
||||
public const PRISMARINE_BRICKS = 2;
|
||||
|
||||
public const PURPUR_NORMAL = 0;
|
||||
public const PURPUR_PILLAR = 2;
|
||||
|
||||
public const QUARTZ_NORMAL = 0;
|
||||
public const QUARTZ_CHISELED = 1;
|
||||
public const QUARTZ_PILLAR = 2;
|
||||
public const QUARTZ_SMOOTH = 3;
|
||||
|
||||
public const RAIL_STRAIGHT_NORTH_SOUTH = 0;
|
||||
public const RAIL_STRAIGHT_EAST_WEST = 1;
|
||||
public const RAIL_ASCENDING_EAST = 2;
|
||||
public const RAIL_ASCENDING_WEST = 3;
|
||||
public const RAIL_ASCENDING_NORTH = 4;
|
||||
public const RAIL_ASCENDING_SOUTH = 5;
|
||||
public const RAIL_CURVE_SOUTHEAST = 6;
|
||||
public const RAIL_CURVE_SOUTHWEST = 7;
|
||||
public const RAIL_CURVE_NORTHWEST = 8;
|
||||
public const RAIL_CURVE_NORTHEAST = 9;
|
||||
|
||||
public const REDSTONE_COMPARATOR_FLAG_SUBTRACT = 0x04;
|
||||
public const REDSTONE_COMPARATOR_FLAG_POWERED = 0x08;
|
||||
|
||||
public const REDSTONE_RAIL_FLAG_POWERED = 0x08;
|
||||
|
||||
public const SANDSTONE_NORMAL = 0;
|
||||
public const SANDSTONE_CHISELED = 1;
|
||||
public const SANDSTONE_CUT = 2;
|
||||
public const SANDSTONE_SMOOTH = 3;
|
||||
|
||||
public const SAPLING_FLAG_READY = 0x08;
|
||||
|
||||
public const SEA_PICKLE_FLAG_NOT_UNDERWATER = 0x04;
|
||||
|
||||
public const SKULL_FLAG_NO_DROPS = 0x08;
|
||||
|
||||
public const SLAB_FLAG_UPPER = 0x08;
|
||||
|
||||
public const SPONGE_FLAG_WET = 0x01;
|
||||
|
||||
public const STAIR_FLAG_UPSIDE_DOWN = 0x04;
|
||||
|
||||
public const STONE_NORMAL = 0;
|
||||
public const STONE_GRANITE = 1;
|
||||
public const STONE_POLISHED_GRANITE = 2;
|
||||
public const STONE_DIORITE = 3;
|
||||
public const STONE_POLISHED_DIORITE = 4;
|
||||
public const STONE_ANDESITE = 5;
|
||||
public const STONE_POLISHED_ANDESITE = 6;
|
||||
|
||||
public const STONE_BRICK_NORMAL = 0;
|
||||
public const STONE_BRICK_MOSSY = 1;
|
||||
public const STONE_BRICK_CRACKED = 2;
|
||||
public const STONE_BRICK_CHISELED = 3;
|
||||
|
||||
public const STONE_SLAB_SMOOTH_STONE = 0;
|
||||
public const STONE_SLAB_SANDSTONE = 1;
|
||||
public const STONE_SLAB_FAKE_WOODEN = 2;
|
||||
public const STONE_SLAB_COBBLESTONE = 3;
|
||||
public const STONE_SLAB_BRICK = 4;
|
||||
public const STONE_SLAB_STONE_BRICK = 5;
|
||||
public const STONE_SLAB_QUARTZ = 6;
|
||||
public const STONE_SLAB_NETHER_BRICK = 7;
|
||||
public const STONE_SLAB2_RED_SANDSTONE = 0;
|
||||
public const STONE_SLAB2_PURPUR = 1;
|
||||
public const STONE_SLAB2_PRISMARINE = 2;
|
||||
public const STONE_SLAB2_DARK_PRISMARINE = 3;
|
||||
public const STONE_SLAB2_PRISMARINE_BRICKS = 4;
|
||||
public const STONE_SLAB2_MOSSY_COBBLESTONE = 5;
|
||||
public const STONE_SLAB2_SMOOTH_SANDSTONE = 6;
|
||||
public const STONE_SLAB2_RED_NETHER_BRICK = 7;
|
||||
public const STONE_SLAB3_END_STONE_BRICK = 0;
|
||||
public const STONE_SLAB3_SMOOTH_RED_SANDSTONE = 1;
|
||||
public const STONE_SLAB3_POLISHED_ANDESITE = 2;
|
||||
public const STONE_SLAB3_ANDESITE = 3;
|
||||
public const STONE_SLAB3_DIORITE = 4;
|
||||
public const STONE_SLAB3_POLISHED_DIORITE = 5;
|
||||
public const STONE_SLAB3_GRANITE = 6;
|
||||
public const STONE_SLAB3_POLISHED_GRANITE = 7;
|
||||
public const STONE_SLAB4_MOSSY_STONE_BRICK = 0;
|
||||
public const STONE_SLAB4_SMOOTH_QUARTZ = 1;
|
||||
public const STONE_SLAB4_STONE = 2;
|
||||
public const STONE_SLAB4_CUT_SANDSTONE = 3;
|
||||
public const STONE_SLAB4_CUT_RED_SANDSTONE = 4;
|
||||
|
||||
public const TALLGRASS_NORMAL = 1;
|
||||
public const TALLGRASS_FERN = 2;
|
||||
|
||||
public const TNT_FLAG_UNSTABLE = 0x01;
|
||||
public const TNT_FLAG_UNDERWATER = 0x02;
|
||||
|
||||
public const TRAPDOOR_FLAG_UPPER = 0x04;
|
||||
public const TRAPDOOR_FLAG_OPEN = 0x08;
|
||||
|
||||
public const TRIPWIRE_FLAG_TRIGGERED = 0x01;
|
||||
public const TRIPWIRE_FLAG_SUSPENDED = 0x02;
|
||||
public const TRIPWIRE_FLAG_CONNECTED = 0x04;
|
||||
public const TRIPWIRE_FLAG_DISARMED = 0x08;
|
||||
|
||||
public const TRIPWIRE_HOOK_FLAG_CONNECTED = 0x04;
|
||||
public const TRIPWIRE_HOOK_FLAG_POWERED = 0x08;
|
||||
|
||||
public const VINE_FLAG_SOUTH = 0x01;
|
||||
public const VINE_FLAG_WEST = 0x02;
|
||||
public const VINE_FLAG_NORTH = 0x04;
|
||||
public const VINE_FLAG_EAST = 0x08;
|
||||
|
||||
public const WALL_COBBLESTONE = 0;
|
||||
public const WALL_MOSSY_COBBLESTONE = 1;
|
||||
public const WALL_GRANITE = 2;
|
||||
public const WALL_DIORITE = 3;
|
||||
public const WALL_ANDESITE = 4;
|
||||
public const WALL_SANDSTONE = 5;
|
||||
public const WALL_BRICK = 6;
|
||||
public const WALL_STONE_BRICK = 7;
|
||||
public const WALL_MOSSY_STONE_BRICK = 8;
|
||||
public const WALL_NETHER_BRICK = 9;
|
||||
public const WALL_END_STONE_BRICK = 10;
|
||||
public const WALL_PRISMARINE = 11;
|
||||
public const WALL_RED_SANDSTONE = 12;
|
||||
public const WALL_RED_NETHER_BRICK = 13;
|
||||
|
||||
public const WOOD_FLAG_STRIPPED = 0x8;
|
||||
}
|
727
src/block/BlockTypeIds.php
Normal file
727
src/block/BlockTypeIds.php
Normal file
@ -0,0 +1,727 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
/**
|
||||
* Enum of all the block runtime IDs used by PocketMine-MP. These IDs are specific to PocketMine-MP and have no
|
||||
* relevance to any Minecraft vanilla things.
|
||||
*
|
||||
* WARNING: DO NOT STORE THESE IDS. They can and will change without warning.
|
||||
* They should ONLY be used to IDENTIFY blocks at runtime.
|
||||
*/
|
||||
final class BlockTypeIds{
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
}
|
||||
|
||||
public const AIR = 10000;
|
||||
|
||||
public const ACACIA_BUTTON = 10001;
|
||||
public const ACACIA_DOOR = 10002;
|
||||
public const ACACIA_FENCE = 10003;
|
||||
public const ACACIA_FENCE_GATE = 10004;
|
||||
public const ACACIA_LEAVES = 10005;
|
||||
public const ACACIA_LOG = 10006;
|
||||
public const ACACIA_PLANKS = 10007;
|
||||
public const ACACIA_PRESSURE_PLATE = 10008;
|
||||
public const ACACIA_SAPLING = 10009;
|
||||
public const ACACIA_SIGN = 10010;
|
||||
public const ACACIA_SLAB = 10011;
|
||||
public const ACACIA_STAIRS = 10012;
|
||||
public const ACACIA_TRAPDOOR = 10013;
|
||||
public const ACACIA_WALL_SIGN = 10014;
|
||||
public const ACACIA_WOOD = 10015;
|
||||
public const ACTIVATOR_RAIL = 10016;
|
||||
public const ALL_SIDED_MUSHROOM_STEM = 10017;
|
||||
public const ALLIUM = 10018;
|
||||
public const ANDESITE = 10019;
|
||||
public const ANDESITE_SLAB = 10020;
|
||||
public const ANDESITE_STAIRS = 10021;
|
||||
public const ANDESITE_WALL = 10022;
|
||||
public const ANVIL = 10023;
|
||||
public const AZURE_BLUET = 10024;
|
||||
public const BAMBOO = 10025;
|
||||
public const BAMBOO_SAPLING = 10026;
|
||||
public const BANNER = 10027;
|
||||
public const BARREL = 10028;
|
||||
public const BARRIER = 10029;
|
||||
public const BEACON = 10030;
|
||||
public const BED = 10031;
|
||||
public const BEDROCK = 10032;
|
||||
public const BEETROOTS = 10033;
|
||||
public const BELL = 10034;
|
||||
public const BIRCH_BUTTON = 10035;
|
||||
public const BIRCH_DOOR = 10036;
|
||||
public const BIRCH_FENCE = 10037;
|
||||
public const BIRCH_FENCE_GATE = 10038;
|
||||
public const BIRCH_LEAVES = 10039;
|
||||
public const BIRCH_LOG = 10040;
|
||||
public const BIRCH_PLANKS = 10041;
|
||||
public const BIRCH_PRESSURE_PLATE = 10042;
|
||||
public const BIRCH_SAPLING = 10043;
|
||||
public const BIRCH_SIGN = 10044;
|
||||
public const BIRCH_SLAB = 10045;
|
||||
public const BIRCH_STAIRS = 10046;
|
||||
public const BIRCH_TRAPDOOR = 10047;
|
||||
public const BIRCH_WALL_SIGN = 10048;
|
||||
public const BIRCH_WOOD = 10049;
|
||||
|
||||
public const BLAST_FURNACE = 10051;
|
||||
|
||||
public const BLUE_ICE = 10053;
|
||||
public const BLUE_ORCHID = 10054;
|
||||
public const BLUE_TORCH = 10055;
|
||||
public const BONE_BLOCK = 10056;
|
||||
public const BOOKSHELF = 10057;
|
||||
public const BREWING_STAND = 10058;
|
||||
public const BRICK_SLAB = 10059;
|
||||
public const BRICK_STAIRS = 10060;
|
||||
public const BRICK_WALL = 10061;
|
||||
public const BRICKS = 10062;
|
||||
|
||||
public const BROWN_MUSHROOM = 10064;
|
||||
public const BROWN_MUSHROOM_BLOCK = 10065;
|
||||
public const CACTUS = 10066;
|
||||
public const CAKE = 10067;
|
||||
public const CARPET = 10068;
|
||||
public const CARROTS = 10069;
|
||||
public const CARVED_PUMPKIN = 10070;
|
||||
public const CHEMICAL_HEAT = 10071;
|
||||
public const CHEST = 10072;
|
||||
public const CHISELED_QUARTZ = 10073;
|
||||
public const CHISELED_RED_SANDSTONE = 10074;
|
||||
public const CHISELED_SANDSTONE = 10075;
|
||||
public const CHISELED_STONE_BRICKS = 10076;
|
||||
public const CLAY = 10077;
|
||||
public const COAL = 10078;
|
||||
public const COAL_ORE = 10079;
|
||||
public const COBBLESTONE = 10080;
|
||||
public const COBBLESTONE_SLAB = 10081;
|
||||
public const COBBLESTONE_STAIRS = 10082;
|
||||
public const COBBLESTONE_WALL = 10083;
|
||||
public const COBWEB = 10084;
|
||||
public const COCOA_POD = 10085;
|
||||
public const COMPOUND_CREATOR = 10086;
|
||||
public const CONCRETE = 10087;
|
||||
public const CONCRETE_POWDER = 10088;
|
||||
public const CORAL = 10089;
|
||||
public const CORAL_BLOCK = 10090;
|
||||
public const CORAL_FAN = 10091;
|
||||
public const CORNFLOWER = 10092;
|
||||
public const CRACKED_STONE_BRICKS = 10093;
|
||||
public const CRAFTING_TABLE = 10094;
|
||||
public const CUT_RED_SANDSTONE = 10095;
|
||||
public const CUT_RED_SANDSTONE_SLAB = 10096;
|
||||
public const CUT_SANDSTONE = 10097;
|
||||
public const CUT_SANDSTONE_SLAB = 10098;
|
||||
|
||||
public const DANDELION = 10100;
|
||||
public const DARK_OAK_BUTTON = 10101;
|
||||
public const DARK_OAK_DOOR = 10102;
|
||||
public const DARK_OAK_FENCE = 10103;
|
||||
public const DARK_OAK_FENCE_GATE = 10104;
|
||||
public const DARK_OAK_LEAVES = 10105;
|
||||
public const DARK_OAK_LOG = 10106;
|
||||
public const DARK_OAK_PLANKS = 10107;
|
||||
public const DARK_OAK_PRESSURE_PLATE = 10108;
|
||||
public const DARK_OAK_SAPLING = 10109;
|
||||
public const DARK_OAK_SIGN = 10110;
|
||||
public const DARK_OAK_SLAB = 10111;
|
||||
public const DARK_OAK_STAIRS = 10112;
|
||||
public const DARK_OAK_TRAPDOOR = 10113;
|
||||
public const DARK_OAK_WALL_SIGN = 10114;
|
||||
public const DARK_OAK_WOOD = 10115;
|
||||
public const DARK_PRISMARINE = 10116;
|
||||
public const DARK_PRISMARINE_SLAB = 10117;
|
||||
public const DARK_PRISMARINE_STAIRS = 10118;
|
||||
public const DAYLIGHT_SENSOR = 10119;
|
||||
public const DEAD_BUSH = 10120;
|
||||
public const DETECTOR_RAIL = 10121;
|
||||
public const DIAMOND = 10122;
|
||||
public const DIAMOND_ORE = 10123;
|
||||
public const DIORITE = 10124;
|
||||
public const DIORITE_SLAB = 10125;
|
||||
public const DIORITE_STAIRS = 10126;
|
||||
public const DIORITE_WALL = 10127;
|
||||
public const DIRT = 10128;
|
||||
public const DOUBLE_TALLGRASS = 10129;
|
||||
public const DRAGON_EGG = 10130;
|
||||
public const DRIED_KELP = 10131;
|
||||
public const DYED_SHULKER_BOX = 10132;
|
||||
public const ELEMENT_ACTINIUM = 10133;
|
||||
public const ELEMENT_ALUMINUM = 10134;
|
||||
public const ELEMENT_AMERICIUM = 10135;
|
||||
public const ELEMENT_ANTIMONY = 10136;
|
||||
public const ELEMENT_ARGON = 10137;
|
||||
public const ELEMENT_ARSENIC = 10138;
|
||||
public const ELEMENT_ASTATINE = 10139;
|
||||
public const ELEMENT_BARIUM = 10140;
|
||||
public const ELEMENT_BERKELIUM = 10141;
|
||||
public const ELEMENT_BERYLLIUM = 10142;
|
||||
public const ELEMENT_BISMUTH = 10143;
|
||||
public const ELEMENT_BOHRIUM = 10144;
|
||||
public const ELEMENT_BORON = 10145;
|
||||
public const ELEMENT_BROMINE = 10146;
|
||||
public const ELEMENT_CADMIUM = 10147;
|
||||
public const ELEMENT_CALCIUM = 10148;
|
||||
public const ELEMENT_CALIFORNIUM = 10149;
|
||||
public const ELEMENT_CARBON = 10150;
|
||||
public const ELEMENT_CERIUM = 10151;
|
||||
public const ELEMENT_CESIUM = 10152;
|
||||
public const ELEMENT_CHLORINE = 10153;
|
||||
public const ELEMENT_CHROMIUM = 10154;
|
||||
public const ELEMENT_COBALT = 10155;
|
||||
public const ELEMENT_CONSTRUCTOR = 10156;
|
||||
public const ELEMENT_COPERNICIUM = 10157;
|
||||
public const ELEMENT_COPPER = 10158;
|
||||
public const ELEMENT_CURIUM = 10159;
|
||||
public const ELEMENT_DARMSTADTIUM = 10160;
|
||||
public const ELEMENT_DUBNIUM = 10161;
|
||||
public const ELEMENT_DYSPROSIUM = 10162;
|
||||
public const ELEMENT_EINSTEINIUM = 10163;
|
||||
public const ELEMENT_ERBIUM = 10164;
|
||||
public const ELEMENT_EUROPIUM = 10165;
|
||||
public const ELEMENT_FERMIUM = 10166;
|
||||
public const ELEMENT_FLEROVIUM = 10167;
|
||||
public const ELEMENT_FLUORINE = 10168;
|
||||
public const ELEMENT_FRANCIUM = 10169;
|
||||
public const ELEMENT_GADOLINIUM = 10170;
|
||||
public const ELEMENT_GALLIUM = 10171;
|
||||
public const ELEMENT_GERMANIUM = 10172;
|
||||
public const ELEMENT_GOLD = 10173;
|
||||
public const ELEMENT_HAFNIUM = 10174;
|
||||
public const ELEMENT_HASSIUM = 10175;
|
||||
public const ELEMENT_HELIUM = 10176;
|
||||
public const ELEMENT_HOLMIUM = 10177;
|
||||
public const ELEMENT_HYDROGEN = 10178;
|
||||
public const ELEMENT_INDIUM = 10179;
|
||||
public const ELEMENT_IODINE = 10180;
|
||||
public const ELEMENT_IRIDIUM = 10181;
|
||||
public const ELEMENT_IRON = 10182;
|
||||
public const ELEMENT_KRYPTON = 10183;
|
||||
public const ELEMENT_LANTHANUM = 10184;
|
||||
public const ELEMENT_LAWRENCIUM = 10185;
|
||||
public const ELEMENT_LEAD = 10186;
|
||||
public const ELEMENT_LITHIUM = 10187;
|
||||
public const ELEMENT_LIVERMORIUM = 10188;
|
||||
public const ELEMENT_LUTETIUM = 10189;
|
||||
public const ELEMENT_MAGNESIUM = 10190;
|
||||
public const ELEMENT_MANGANESE = 10191;
|
||||
public const ELEMENT_MEITNERIUM = 10192;
|
||||
public const ELEMENT_MENDELEVIUM = 10193;
|
||||
public const ELEMENT_MERCURY = 10194;
|
||||
public const ELEMENT_MOLYBDENUM = 10195;
|
||||
public const ELEMENT_MOSCOVIUM = 10196;
|
||||
public const ELEMENT_NEODYMIUM = 10197;
|
||||
public const ELEMENT_NEON = 10198;
|
||||
public const ELEMENT_NEPTUNIUM = 10199;
|
||||
public const ELEMENT_NICKEL = 10200;
|
||||
public const ELEMENT_NIHONIUM = 10201;
|
||||
public const ELEMENT_NIOBIUM = 10202;
|
||||
public const ELEMENT_NITROGEN = 10203;
|
||||
public const ELEMENT_NOBELIUM = 10204;
|
||||
public const ELEMENT_OGANESSON = 10205;
|
||||
public const ELEMENT_OSMIUM = 10206;
|
||||
public const ELEMENT_OXYGEN = 10207;
|
||||
public const ELEMENT_PALLADIUM = 10208;
|
||||
public const ELEMENT_PHOSPHORUS = 10209;
|
||||
public const ELEMENT_PLATINUM = 10210;
|
||||
public const ELEMENT_PLUTONIUM = 10211;
|
||||
public const ELEMENT_POLONIUM = 10212;
|
||||
public const ELEMENT_POTASSIUM = 10213;
|
||||
public const ELEMENT_PRASEODYMIUM = 10214;
|
||||
public const ELEMENT_PROMETHIUM = 10215;
|
||||
public const ELEMENT_PROTACTINIUM = 10216;
|
||||
public const ELEMENT_RADIUM = 10217;
|
||||
public const ELEMENT_RADON = 10218;
|
||||
public const ELEMENT_RHENIUM = 10219;
|
||||
public const ELEMENT_RHODIUM = 10220;
|
||||
public const ELEMENT_ROENTGENIUM = 10221;
|
||||
public const ELEMENT_RUBIDIUM = 10222;
|
||||
public const ELEMENT_RUTHENIUM = 10223;
|
||||
public const ELEMENT_RUTHERFORDIUM = 10224;
|
||||
public const ELEMENT_SAMARIUM = 10225;
|
||||
public const ELEMENT_SCANDIUM = 10226;
|
||||
public const ELEMENT_SEABORGIUM = 10227;
|
||||
public const ELEMENT_SELENIUM = 10228;
|
||||
public const ELEMENT_SILICON = 10229;
|
||||
public const ELEMENT_SILVER = 10230;
|
||||
public const ELEMENT_SODIUM = 10231;
|
||||
public const ELEMENT_STRONTIUM = 10232;
|
||||
public const ELEMENT_SULFUR = 10233;
|
||||
public const ELEMENT_TANTALUM = 10234;
|
||||
public const ELEMENT_TECHNETIUM = 10235;
|
||||
public const ELEMENT_TELLURIUM = 10236;
|
||||
public const ELEMENT_TENNESSINE = 10237;
|
||||
public const ELEMENT_TERBIUM = 10238;
|
||||
public const ELEMENT_THALLIUM = 10239;
|
||||
public const ELEMENT_THORIUM = 10240;
|
||||
public const ELEMENT_THULIUM = 10241;
|
||||
public const ELEMENT_TIN = 10242;
|
||||
public const ELEMENT_TITANIUM = 10243;
|
||||
public const ELEMENT_TUNGSTEN = 10244;
|
||||
public const ELEMENT_URANIUM = 10245;
|
||||
public const ELEMENT_VANADIUM = 10246;
|
||||
public const ELEMENT_XENON = 10247;
|
||||
public const ELEMENT_YTTERBIUM = 10248;
|
||||
public const ELEMENT_YTTRIUM = 10249;
|
||||
public const ELEMENT_ZERO = 10250;
|
||||
public const ELEMENT_ZINC = 10251;
|
||||
public const ELEMENT_ZIRCONIUM = 10252;
|
||||
public const EMERALD = 10253;
|
||||
public const EMERALD_ORE = 10254;
|
||||
public const ENCHANTING_TABLE = 10255;
|
||||
public const END_PORTAL_FRAME = 10256;
|
||||
public const END_ROD = 10257;
|
||||
public const END_STONE = 10258;
|
||||
public const END_STONE_BRICK_SLAB = 10259;
|
||||
public const END_STONE_BRICK_STAIRS = 10260;
|
||||
public const END_STONE_BRICK_WALL = 10261;
|
||||
public const END_STONE_BRICKS = 10262;
|
||||
public const ENDER_CHEST = 10263;
|
||||
public const FAKE_WOODEN_SLAB = 10264;
|
||||
public const FARMLAND = 10265;
|
||||
public const FERN = 10266;
|
||||
public const FIRE = 10267;
|
||||
public const FLETCHING_TABLE = 10268;
|
||||
public const FLOWER_POT = 10269;
|
||||
public const FROSTED_ICE = 10270;
|
||||
public const FURNACE = 10271;
|
||||
public const GLASS = 10272;
|
||||
public const GLASS_PANE = 10273;
|
||||
public const GLOWING_OBSIDIAN = 10274;
|
||||
public const GLOWSTONE = 10275;
|
||||
public const GOLD = 10276;
|
||||
public const GOLD_ORE = 10277;
|
||||
public const GRANITE = 10278;
|
||||
public const GRANITE_SLAB = 10279;
|
||||
public const GRANITE_STAIRS = 10280;
|
||||
public const GRANITE_WALL = 10281;
|
||||
public const GRASS = 10282;
|
||||
public const GRASS_PATH = 10283;
|
||||
public const GRAVEL = 10284;
|
||||
|
||||
public const GREEN_TORCH = 10287;
|
||||
public const HARDENED_CLAY = 10288;
|
||||
public const HARDENED_GLASS = 10289;
|
||||
public const HARDENED_GLASS_PANE = 10290;
|
||||
public const HAY_BALE = 10291;
|
||||
public const HOPPER = 10292;
|
||||
public const ICE = 10293;
|
||||
public const INFESTED_CHISELED_STONE_BRICK = 10294;
|
||||
public const INFESTED_COBBLESTONE = 10295;
|
||||
public const INFESTED_CRACKED_STONE_BRICK = 10296;
|
||||
public const INFESTED_MOSSY_STONE_BRICK = 10297;
|
||||
public const INFESTED_STONE = 10298;
|
||||
public const INFESTED_STONE_BRICK = 10299;
|
||||
public const INFO_UPDATE = 10300;
|
||||
public const INFO_UPDATE2 = 10301;
|
||||
public const INVISIBLE_BEDROCK = 10302;
|
||||
public const IRON = 10303;
|
||||
public const IRON_BARS = 10304;
|
||||
public const IRON_DOOR = 10305;
|
||||
public const IRON_ORE = 10306;
|
||||
public const IRON_TRAPDOOR = 10307;
|
||||
public const ITEM_FRAME = 10308;
|
||||
public const JUKEBOX = 10309;
|
||||
public const JUNGLE_BUTTON = 10310;
|
||||
public const JUNGLE_DOOR = 10311;
|
||||
public const JUNGLE_FENCE = 10312;
|
||||
public const JUNGLE_FENCE_GATE = 10313;
|
||||
public const JUNGLE_LEAVES = 10314;
|
||||
public const JUNGLE_LOG = 10315;
|
||||
public const JUNGLE_PLANKS = 10316;
|
||||
public const JUNGLE_PRESSURE_PLATE = 10317;
|
||||
public const JUNGLE_SAPLING = 10318;
|
||||
public const JUNGLE_SIGN = 10319;
|
||||
public const JUNGLE_SLAB = 10320;
|
||||
public const JUNGLE_STAIRS = 10321;
|
||||
public const JUNGLE_TRAPDOOR = 10322;
|
||||
public const JUNGLE_WALL_SIGN = 10323;
|
||||
public const JUNGLE_WOOD = 10324;
|
||||
public const LAB_TABLE = 10325;
|
||||
public const LADDER = 10326;
|
||||
public const LANTERN = 10327;
|
||||
public const LAPIS_LAZULI = 10328;
|
||||
public const LAPIS_LAZULI_ORE = 10329;
|
||||
public const LARGE_FERN = 10330;
|
||||
public const LAVA = 10331;
|
||||
public const LECTERN = 10332;
|
||||
public const LEGACY_STONECUTTER = 10333;
|
||||
public const LEVER = 10334;
|
||||
|
||||
public const LILAC = 10337;
|
||||
public const LILY_OF_THE_VALLEY = 10338;
|
||||
public const LILY_PAD = 10339;
|
||||
|
||||
public const LIT_PUMPKIN = 10341;
|
||||
public const LOOM = 10342;
|
||||
|
||||
public const MAGMA = 10344;
|
||||
public const MATERIAL_REDUCER = 10345;
|
||||
public const MELON = 10346;
|
||||
public const MELON_STEM = 10347;
|
||||
public const MOB_HEAD = 10348;
|
||||
public const MONSTER_SPAWNER = 10349;
|
||||
public const MOSSY_COBBLESTONE = 10350;
|
||||
public const MOSSY_COBBLESTONE_SLAB = 10351;
|
||||
public const MOSSY_COBBLESTONE_STAIRS = 10352;
|
||||
public const MOSSY_COBBLESTONE_WALL = 10353;
|
||||
public const MOSSY_STONE_BRICK_SLAB = 10354;
|
||||
public const MOSSY_STONE_BRICK_STAIRS = 10355;
|
||||
public const MOSSY_STONE_BRICK_WALL = 10356;
|
||||
public const MOSSY_STONE_BRICKS = 10357;
|
||||
public const MUSHROOM_STEM = 10358;
|
||||
public const MYCELIUM = 10359;
|
||||
public const NETHER_BRICK_FENCE = 10360;
|
||||
public const NETHER_BRICK_SLAB = 10361;
|
||||
public const NETHER_BRICK_STAIRS = 10362;
|
||||
public const NETHER_BRICK_WALL = 10363;
|
||||
public const NETHER_BRICKS = 10364;
|
||||
public const NETHER_PORTAL = 10365;
|
||||
public const NETHER_QUARTZ_ORE = 10366;
|
||||
public const NETHER_REACTOR_CORE = 10367;
|
||||
public const NETHER_WART = 10368;
|
||||
public const NETHER_WART_BLOCK = 10369;
|
||||
public const NETHERRACK = 10370;
|
||||
public const NOTE_BLOCK = 10371;
|
||||
public const OAK_BUTTON = 10372;
|
||||
public const OAK_DOOR = 10373;
|
||||
public const OAK_FENCE = 10374;
|
||||
public const OAK_FENCE_GATE = 10375;
|
||||
public const OAK_LEAVES = 10376;
|
||||
public const OAK_LOG = 10377;
|
||||
public const OAK_PLANKS = 10378;
|
||||
public const OAK_PRESSURE_PLATE = 10379;
|
||||
public const OAK_SAPLING = 10380;
|
||||
public const OAK_SIGN = 10381;
|
||||
public const OAK_SLAB = 10382;
|
||||
public const OAK_STAIRS = 10383;
|
||||
public const OAK_TRAPDOOR = 10384;
|
||||
public const OAK_WALL_SIGN = 10385;
|
||||
public const OAK_WOOD = 10386;
|
||||
public const OBSIDIAN = 10387;
|
||||
|
||||
public const ORANGE_TULIP = 10389;
|
||||
public const OXEYE_DAISY = 10390;
|
||||
public const PACKED_ICE = 10391;
|
||||
public const PEONY = 10392;
|
||||
|
||||
public const PINK_TULIP = 10394;
|
||||
public const PODZOL = 10395;
|
||||
public const POLISHED_ANDESITE = 10396;
|
||||
public const POLISHED_ANDESITE_SLAB = 10397;
|
||||
public const POLISHED_ANDESITE_STAIRS = 10398;
|
||||
public const POLISHED_DIORITE = 10399;
|
||||
public const POLISHED_DIORITE_SLAB = 10400;
|
||||
public const POLISHED_DIORITE_STAIRS = 10401;
|
||||
public const POLISHED_GRANITE = 10402;
|
||||
public const POLISHED_GRANITE_SLAB = 10403;
|
||||
public const POLISHED_GRANITE_STAIRS = 10404;
|
||||
public const POPPY = 10405;
|
||||
public const POTATOES = 10406;
|
||||
public const POWERED_RAIL = 10407;
|
||||
public const PRISMARINE = 10408;
|
||||
public const PRISMARINE_BRICKS = 10409;
|
||||
public const PRISMARINE_BRICKS_SLAB = 10410;
|
||||
public const PRISMARINE_BRICKS_STAIRS = 10411;
|
||||
public const PRISMARINE_SLAB = 10412;
|
||||
public const PRISMARINE_STAIRS = 10413;
|
||||
public const PRISMARINE_WALL = 10414;
|
||||
public const PUMPKIN = 10415;
|
||||
public const PUMPKIN_STEM = 10416;
|
||||
|
||||
public const PURPLE_TORCH = 10418;
|
||||
public const PURPUR = 10419;
|
||||
public const PURPUR_PILLAR = 10420;
|
||||
public const PURPUR_SLAB = 10421;
|
||||
public const PURPUR_STAIRS = 10422;
|
||||
public const QUARTZ = 10423;
|
||||
public const QUARTZ_PILLAR = 10424;
|
||||
public const QUARTZ_SLAB = 10425;
|
||||
public const QUARTZ_STAIRS = 10426;
|
||||
public const RAIL = 10427;
|
||||
|
||||
public const RED_MUSHROOM = 10429;
|
||||
public const RED_MUSHROOM_BLOCK = 10430;
|
||||
public const RED_NETHER_BRICK_SLAB = 10431;
|
||||
public const RED_NETHER_BRICK_STAIRS = 10432;
|
||||
public const RED_NETHER_BRICK_WALL = 10433;
|
||||
public const RED_NETHER_BRICKS = 10434;
|
||||
public const RED_SAND = 10435;
|
||||
public const RED_SANDSTONE = 10436;
|
||||
public const RED_SANDSTONE_SLAB = 10437;
|
||||
public const RED_SANDSTONE_STAIRS = 10438;
|
||||
public const RED_SANDSTONE_WALL = 10439;
|
||||
public const RED_TORCH = 10440;
|
||||
public const RED_TULIP = 10441;
|
||||
public const REDSTONE = 10442;
|
||||
public const REDSTONE_COMPARATOR = 10443;
|
||||
public const REDSTONE_LAMP = 10444;
|
||||
public const REDSTONE_ORE = 10445;
|
||||
public const REDSTONE_REPEATER = 10446;
|
||||
public const REDSTONE_TORCH = 10447;
|
||||
public const REDSTONE_WIRE = 10448;
|
||||
public const RESERVED6 = 10449;
|
||||
public const ROSE_BUSH = 10450;
|
||||
public const SAND = 10451;
|
||||
public const SANDSTONE = 10452;
|
||||
public const SANDSTONE_SLAB = 10453;
|
||||
public const SANDSTONE_STAIRS = 10454;
|
||||
public const SANDSTONE_WALL = 10455;
|
||||
public const SEA_LANTERN = 10456;
|
||||
public const SEA_PICKLE = 10457;
|
||||
public const SHULKER_BOX = 10458;
|
||||
public const SLIME = 10459;
|
||||
public const SMOKER = 10460;
|
||||
public const SMOOTH_QUARTZ = 10461;
|
||||
public const SMOOTH_QUARTZ_SLAB = 10462;
|
||||
public const SMOOTH_QUARTZ_STAIRS = 10463;
|
||||
public const SMOOTH_RED_SANDSTONE = 10464;
|
||||
public const SMOOTH_RED_SANDSTONE_SLAB = 10465;
|
||||
public const SMOOTH_RED_SANDSTONE_STAIRS = 10466;
|
||||
public const SMOOTH_SANDSTONE = 10467;
|
||||
public const SMOOTH_SANDSTONE_SLAB = 10468;
|
||||
public const SMOOTH_SANDSTONE_STAIRS = 10469;
|
||||
public const SMOOTH_STONE = 10470;
|
||||
public const SMOOTH_STONE_SLAB = 10471;
|
||||
public const SNOW = 10472;
|
||||
public const SNOW_LAYER = 10473;
|
||||
public const SOUL_SAND = 10474;
|
||||
public const SPONGE = 10475;
|
||||
public const SPRUCE_BUTTON = 10476;
|
||||
public const SPRUCE_DOOR = 10477;
|
||||
public const SPRUCE_FENCE = 10478;
|
||||
public const SPRUCE_FENCE_GATE = 10479;
|
||||
public const SPRUCE_LEAVES = 10480;
|
||||
public const SPRUCE_LOG = 10481;
|
||||
public const SPRUCE_PLANKS = 10482;
|
||||
public const SPRUCE_PRESSURE_PLATE = 10483;
|
||||
public const SPRUCE_SAPLING = 10484;
|
||||
public const SPRUCE_SIGN = 10485;
|
||||
public const SPRUCE_SLAB = 10486;
|
||||
public const SPRUCE_STAIRS = 10487;
|
||||
public const SPRUCE_TRAPDOOR = 10488;
|
||||
public const SPRUCE_WALL_SIGN = 10489;
|
||||
public const SPRUCE_WOOD = 10490;
|
||||
public const STAINED_CLAY = 10491;
|
||||
public const STAINED_GLASS = 10492;
|
||||
public const STAINED_GLASS_PANE = 10493;
|
||||
public const STAINED_HARDENED_GLASS = 10494;
|
||||
public const STAINED_HARDENED_GLASS_PANE = 10495;
|
||||
public const STONE = 10496;
|
||||
public const STONE_BRICK_SLAB = 10497;
|
||||
public const STONE_BRICK_STAIRS = 10498;
|
||||
public const STONE_BRICK_WALL = 10499;
|
||||
public const STONE_BRICKS = 10500;
|
||||
public const STONE_BUTTON = 10501;
|
||||
public const STONE_PRESSURE_PLATE = 10502;
|
||||
public const STONE_SLAB = 10503;
|
||||
public const STONE_STAIRS = 10504;
|
||||
public const STONECUTTER = 10505;
|
||||
|
||||
public const SUGARCANE = 10518;
|
||||
public const SUNFLOWER = 10519;
|
||||
public const SWEET_BERRY_BUSH = 10520;
|
||||
public const TALL_GRASS = 10521;
|
||||
public const TNT = 10522;
|
||||
public const TORCH = 10523;
|
||||
public const TRAPPED_CHEST = 10524;
|
||||
public const TRIPWIRE = 10525;
|
||||
public const TRIPWIRE_HOOK = 10526;
|
||||
public const UNDERWATER_TORCH = 10527;
|
||||
public const VINES = 10528;
|
||||
public const WALL_BANNER = 10529;
|
||||
public const WALL_CORAL_FAN = 10530;
|
||||
public const WATER = 10531;
|
||||
public const WEIGHTED_PRESSURE_PLATE_HEAVY = 10532;
|
||||
public const WEIGHTED_PRESSURE_PLATE_LIGHT = 10533;
|
||||
public const WHEAT = 10534;
|
||||
|
||||
public const WHITE_TULIP = 10536;
|
||||
public const WOOL = 10537;
|
||||
|
||||
public const GLAZED_TERRACOTTA = 10539;
|
||||
public const AMETHYST = 10540;
|
||||
public const ANCIENT_DEBRIS = 10541;
|
||||
public const BASALT = 10542;
|
||||
public const POLISHED_BASALT = 10543;
|
||||
public const SMOOTH_BASALT = 10544;
|
||||
public const BLACKSTONE = 10545;
|
||||
public const BLACKSTONE_SLAB = 10546;
|
||||
public const BLACKSTONE_STAIRS = 10547;
|
||||
public const BLACKSTONE_WALL = 10548;
|
||||
public const POLISHED_BLACKSTONE = 10549;
|
||||
public const POLISHED_BLACKSTONE_BUTTON = 10550;
|
||||
public const POLISHED_BLACKSTONE_PRESSURE_PLATE = 10551;
|
||||
public const POLISHED_BLACKSTONE_SLAB = 10552;
|
||||
public const POLISHED_BLACKSTONE_STAIRS = 10553;
|
||||
public const POLISHED_BLACKSTONE_WALL = 10554;
|
||||
public const CHISELED_POLISHED_BLACKSTONE = 10555;
|
||||
public const POLISHED_BLACKSTONE_BRICKS = 10556;
|
||||
public const POLISHED_BLACKSTONE_BRICK_SLAB = 10557;
|
||||
public const POLISHED_BLACKSTONE_BRICK_STAIRS = 10558;
|
||||
public const POLISHED_BLACKSTONE_BRICK_WALL = 10559;
|
||||
public const CRACKED_POLISHED_BLACKSTONE_BRICKS = 10560;
|
||||
public const LIGHT = 10561;
|
||||
public const RAW_COPPER = 10562;
|
||||
public const RAW_GOLD = 10563;
|
||||
public const RAW_IRON = 10564;
|
||||
public const CALCITE = 10565;
|
||||
public const DEEPSLATE = 10566;
|
||||
public const DEEPSLATE_BRICKS = 10567;
|
||||
public const DEEPSLATE_BRICK_SLAB = 10568;
|
||||
public const DEEPSLATE_BRICK_STAIRS = 10569;
|
||||
public const DEEPSLATE_BRICK_WALL = 10570;
|
||||
public const CRACKED_DEEPSLATE_BRICKS = 10571;
|
||||
public const DEEPSLATE_TILES = 10572;
|
||||
public const DEEPSLATE_TILE_SLAB = 10573;
|
||||
public const DEEPSLATE_TILE_STAIRS = 10574;
|
||||
public const DEEPSLATE_TILE_WALL = 10575;
|
||||
public const CRACKED_DEEPSLATE_TILES = 10576;
|
||||
public const COBBLED_DEEPSLATE = 10577;
|
||||
public const COBBLED_DEEPSLATE_SLAB = 10578;
|
||||
public const COBBLED_DEEPSLATE_STAIRS = 10579;
|
||||
public const COBBLED_DEEPSLATE_WALL = 10580;
|
||||
public const POLISHED_DEEPSLATE = 10581;
|
||||
public const POLISHED_DEEPSLATE_SLAB = 10582;
|
||||
public const POLISHED_DEEPSLATE_STAIRS = 10583;
|
||||
public const POLISHED_DEEPSLATE_WALL = 10584;
|
||||
public const QUARTZ_BRICKS = 10585;
|
||||
public const CHISELED_DEEPSLATE = 10586;
|
||||
public const CHISELED_NETHER_BRICKS = 10587;
|
||||
public const CRACKED_NETHER_BRICKS = 10588;
|
||||
public const TUFF = 10589;
|
||||
public const SOUL_TORCH = 10590;
|
||||
public const SOUL_LANTERN = 10591;
|
||||
public const SOUL_SOIL = 10592;
|
||||
public const SOUL_FIRE = 10593;
|
||||
public const SHROOMLIGHT = 10594;
|
||||
public const MANGROVE_PLANKS = 10595;
|
||||
public const CRIMSON_PLANKS = 10596;
|
||||
public const WARPED_PLANKS = 10597;
|
||||
public const MANGROVE_FENCE = 10598;
|
||||
public const CRIMSON_FENCE = 10599;
|
||||
public const WARPED_FENCE = 10600;
|
||||
public const MANGROVE_SLAB = 10601;
|
||||
public const CRIMSON_SLAB = 10602;
|
||||
public const WARPED_SLAB = 10603;
|
||||
public const MANGROVE_LOG = 10604;
|
||||
public const CRIMSON_STEM = 10605;
|
||||
public const WARPED_STEM = 10606;
|
||||
public const MANGROVE_WOOD = 10607;
|
||||
public const CRIMSON_HYPHAE = 10608;
|
||||
public const WARPED_HYPHAE = 10609;
|
||||
public const MANGROVE_TRAPDOOR = 10610;
|
||||
public const CRIMSON_TRAPDOOR = 10611;
|
||||
public const WARPED_TRAPDOOR = 10612;
|
||||
public const MANGROVE_BUTTON = 10613;
|
||||
public const CRIMSON_BUTTON = 10614;
|
||||
public const WARPED_BUTTON = 10615;
|
||||
public const MANGROVE_PRESSURE_PLATE = 10616;
|
||||
public const CRIMSON_PRESSURE_PLATE = 10617;
|
||||
public const WARPED_PRESSURE_PLATE = 10618;
|
||||
public const MANGROVE_DOOR = 10619;
|
||||
public const CRIMSON_DOOR = 10620;
|
||||
public const WARPED_DOOR = 10621;
|
||||
public const MANGROVE_FENCE_GATE = 10622;
|
||||
public const CRIMSON_FENCE_GATE = 10623;
|
||||
public const WARPED_FENCE_GATE = 10624;
|
||||
public const MANGROVE_STAIRS = 10625;
|
||||
public const CRIMSON_STAIRS = 10626;
|
||||
public const WARPED_STAIRS = 10627;
|
||||
public const MANGROVE_SIGN = 10628;
|
||||
public const CRIMSON_SIGN = 10629;
|
||||
public const WARPED_SIGN = 10630;
|
||||
public const MANGROVE_WALL_SIGN = 10631;
|
||||
public const CRIMSON_WALL_SIGN = 10632;
|
||||
public const WARPED_WALL_SIGN = 10633;
|
||||
public const TINTED_GLASS = 10634;
|
||||
public const HONEYCOMB = 10635;
|
||||
public const DEEPSLATE_COAL_ORE = 10636;
|
||||
public const DEEPSLATE_DIAMOND_ORE = 10637;
|
||||
public const DEEPSLATE_EMERALD_ORE = 10638;
|
||||
public const DEEPSLATE_LAPIS_LAZULI_ORE = 10639;
|
||||
public const DEEPSLATE_REDSTONE_ORE = 10640;
|
||||
public const DEEPSLATE_IRON_ORE = 10641;
|
||||
public const DEEPSLATE_GOLD_ORE = 10642;
|
||||
public const DEEPSLATE_COPPER_ORE = 10643;
|
||||
public const COPPER_ORE = 10644;
|
||||
public const NETHER_GOLD_ORE = 10645;
|
||||
public const MUD = 10646;
|
||||
public const MUD_BRICKS = 10647;
|
||||
public const MUD_BRICK_SLAB = 10648;
|
||||
public const MUD_BRICK_STAIRS = 10649;
|
||||
public const MUD_BRICK_WALL = 10650;
|
||||
public const PACKED_MUD = 10651;
|
||||
public const WARPED_WART_BLOCK = 10652;
|
||||
public const CRYING_OBSIDIAN = 10653;
|
||||
public const GILDED_BLACKSTONE = 10654;
|
||||
public const LIGHTNING_ROD = 10655;
|
||||
public const COPPER = 10656;
|
||||
public const CUT_COPPER = 10657;
|
||||
public const CUT_COPPER_SLAB = 10658;
|
||||
public const CUT_COPPER_STAIRS = 10659;
|
||||
public const CANDLE = 10660;
|
||||
public const DYED_CANDLE = 10661;
|
||||
public const CAKE_WITH_CANDLE = 10662;
|
||||
public const CAKE_WITH_DYED_CANDLE = 10663;
|
||||
public const WITHER_ROSE = 10664;
|
||||
public const HANGING_ROOTS = 10665;
|
||||
public const CARTOGRAPHY_TABLE = 10666;
|
||||
public const SMITHING_TABLE = 10667;
|
||||
public const NETHERITE = 10668;
|
||||
public const SPORE_BLOSSOM = 10669;
|
||||
public const CAULDRON = 10670;
|
||||
public const WATER_CAULDRON = 10671;
|
||||
public const LAVA_CAULDRON = 10672;
|
||||
public const POTION_CAULDRON = 10673;
|
||||
public const POWDER_SNOW_CAULDRON = 10674;
|
||||
public const CHORUS_FLOWER = 10675;
|
||||
public const CHORUS_PLANT = 10676;
|
||||
public const MANGROVE_ROOTS = 10677;
|
||||
public const MUDDY_MANGROVE_ROOTS = 10678;
|
||||
public const FROGLIGHT = 10679;
|
||||
public const TWISTING_VINES = 10680;
|
||||
public const WEEPING_VINES = 10681;
|
||||
public const CHAIN = 10682;
|
||||
public const SCULK = 10683;
|
||||
public const GLOWING_ITEM_FRAME = 10684;
|
||||
public const MANGROVE_LEAVES = 10685;
|
||||
public const AZALEA_LEAVES = 10686;
|
||||
public const FLOWERING_AZALEA_LEAVES = 10687;
|
||||
public const REINFORCED_DEEPSLATE = 10688;
|
||||
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10689;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;
|
||||
|
||||
/**
|
||||
* Returns a new runtime block type ID, e.g. for use by a custom block.
|
||||
*/
|
||||
public static function newId() : int{
|
||||
return self::$nextDynamicId++;
|
||||
}
|
||||
}
|
52
src/block/BlockTypeInfo.php
Normal file
52
src/block/BlockTypeInfo.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use function array_fill_keys;
|
||||
use function array_keys;
|
||||
|
||||
final class BlockTypeInfo{
|
||||
/**
|
||||
* @var true[]
|
||||
* @phpstan-var array<string, true>
|
||||
*/
|
||||
private array $typeTags;
|
||||
|
||||
/**
|
||||
* @param string[] $typeTags
|
||||
*/
|
||||
public function __construct(
|
||||
private BlockBreakInfo $breakInfo,
|
||||
array $typeTags = []
|
||||
){
|
||||
$this->typeTags = array_fill_keys($typeTags, true);
|
||||
}
|
||||
|
||||
public function getBreakInfo() : BlockBreakInfo{ return $this->breakInfo; }
|
||||
|
||||
/** @return string[] */
|
||||
public function getTypeTags() : array{ return array_keys($this->typeTags); }
|
||||
|
||||
public function hasTypeTag(string $tag) : bool{ return isset($this->typeTags[$tag]); }
|
||||
}
|
34
src/block/BlockTypeTags.php
Normal file
34
src/block/BlockTypeTags.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
final class BlockTypeTags{
|
||||
private const PREFIX = "pocketmine:";
|
||||
|
||||
public const DIRT = self::PREFIX . "dirt";
|
||||
public const MUD = self::PREFIX . "mud";
|
||||
public const SAND = self::PREFIX . "sand";
|
||||
public const POTTABLE_PLANTS = self::PREFIX . "pottable";
|
||||
public const FIRE = self::PREFIX . "fire";
|
||||
}
|
@ -23,8 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\PillarRotationInMetadataTrait;
|
||||
use pocketmine\block\utils\PillarRotationTrait;
|
||||
|
||||
class BoneBlock extends Opaque{
|
||||
use PillarRotationInMetadataTrait;
|
||||
use PillarRotationTrait;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\tile\BrewingStand as TileBrewingStand;
|
||||
use pocketmine\block\utils\BrewingStandSlot;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -42,33 +43,8 @@ class BrewingStand extends Transparent{
|
||||
*/
|
||||
protected array $slots = [];
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
$flags = 0;
|
||||
foreach([
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_EAST => BrewingStandSlot::EAST(),
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST => BrewingStandSlot::NORTHWEST(),
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST => BrewingStandSlot::SOUTHWEST(),
|
||||
] as $flag => $slot){
|
||||
$flags |= (array_key_exists($slot->id(), $this->slots) ? $flag : 0);
|
||||
}
|
||||
return $flags;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->slots = [];
|
||||
foreach([
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_EAST => BrewingStandSlot::EAST(),
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_NORTHWEST => BrewingStandSlot::NORTHWEST(),
|
||||
BlockLegacyMetadata::BREWING_STAND_FLAG_SOUTHWEST => BrewingStandSlot::SOUTHWEST(),
|
||||
] as $flag => $slot){
|
||||
if(($stateMeta & $flag) !== 0){
|
||||
$this->slots[$slot->id()] = $slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->brewingStandSlots($this->slots);
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
@ -118,7 +94,7 @@ class BrewingStand extends Transparent{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player instanceof Player){
|
||||
$stand = $this->position->getWorld()->getTile($this->position);
|
||||
if($stand instanceof TileBrewingStand && $stand->canOpenWith($item->getCustomName())){
|
||||
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\AnyFacingTrait;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -38,18 +38,9 @@ abstract class Button extends Flowable{
|
||||
|
||||
protected bool $pressed = false;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeFacing($this->facing) | ($this->pressed ? BlockLegacyMetadata::BUTTON_FLAG_POWERED : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
//TODO: in PC it's (6 - facing) for every meta except 0 (down)
|
||||
$this->facing = BlockDataSerializer::readFacing($stateMeta & 0x07);
|
||||
$this->pressed = ($stateMeta & BlockLegacyMetadata::BUTTON_FLAG_POWERED) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->facing($this->facing);
|
||||
$w->bool($this->pressed);
|
||||
}
|
||||
|
||||
public function isPressed() : bool{ return $this->pressed; }
|
||||
@ -70,7 +61,7 @@ abstract class Button extends Flowable{
|
||||
|
||||
abstract protected function getActivationTime() : int;
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if(!$this->pressed){
|
||||
$this->pressed = true;
|
||||
$world = $this->position->getWorld();
|
||||
|
@ -23,8 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
@ -41,16 +41,8 @@ class Cactus extends Transparent{
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(4, 0, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
@ -86,10 +78,13 @@ class Cactus extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->isSameType($this) || $block->hasTypeTag(BlockTypeTags::SAND);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
$world = $this->position->getWorld();
|
||||
if($down->getId() !== BlockLegacyIds::SAND && !$down->isSameType($this)){
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
foreach(Facing::HORIZONTAL as $side){
|
||||
@ -115,7 +110,7 @@ class Cactus extends Transparent{
|
||||
break;
|
||||
}
|
||||
$b = $world->getBlockAt($this->position->x, $this->position->y + $y, $this->position->z);
|
||||
if($b->getId() === BlockLegacyIds::AIR){
|
||||
if($b->getTypeId() === BlockTypeIds::AIR){
|
||||
$ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS());
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
@ -136,8 +131,7 @@ class Cactus extends Transparent{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getId() === BlockLegacyIds::SAND || $down->isSameType($this)){
|
||||
if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
foreach(Facing::HORIZONTAL as $side){
|
||||
if($this->getSide($side)->isSolid()){
|
||||
return false;
|
||||
|
@ -23,33 +23,21 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\entity\effect\EffectInstance;
|
||||
use pocketmine\entity\FoodSource;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemBlock;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
class Cake extends Transparent implements FoodSource{
|
||||
class Cake extends BaseCake{
|
||||
public const MAX_BITES = 6;
|
||||
|
||||
protected int $bites = 0;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->bites;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->bites = BlockDataSerializer::readBoundedInt("bites", $stateMeta, 0, self::MAX_BITES);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, 0, self::MAX_BITES, $this->bites);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,10 +52,6 @@ class Cake extends Transparent implements FoodSource{
|
||||
];
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function getBites() : int{ return $this->bites; }
|
||||
|
||||
/** @return $this */
|
||||
@ -79,49 +63,27 @@ class Cake extends Transparent implements FoodSource{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getId() !== BlockLegacyIds::AIR){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof ItemBlock){
|
||||
$block = $item->getBlock();
|
||||
$resultBlock = null;
|
||||
if($block->getTypeId() === BlockTypeIds::CANDLE){
|
||||
$resultBlock = VanillaBlocks::CAKE_WITH_CANDLE();
|
||||
}elseif($block instanceof DyedCandle){
|
||||
$resultBlock = VanillaBlocks::CAKE_WITH_DYED_CANDLE()->setColor($block->getColor());
|
||||
}
|
||||
|
||||
if($resultBlock !== null){
|
||||
$this->position->getWorld()->setBlock($this->position, $resultBlock);
|
||||
$item->pop();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return parent::onInteract($item, $face, $clickVector, $player, $returnedItems);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){ //Replace with common break method
|
||||
$this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR());
|
||||
}
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
return $player->consumeObject($this);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFoodRestore() : int{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getSaturationRestore() : float{
|
||||
return 0.4;
|
||||
}
|
||||
|
||||
public function requiresHunger() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Block
|
||||
*/
|
||||
public function getResidue(){
|
||||
public function getResidue() : Block{
|
||||
$clone = clone $this;
|
||||
$clone->bites++;
|
||||
if($clone->bites > self::MAX_BITES){
|
||||
@ -129,15 +91,4 @@ class Cake extends Transparent implements FoodSource{
|
||||
}
|
||||
return $clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EffectInstance[]
|
||||
*/
|
||||
public function getAdditionalEffects() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onConsume(Living $consumer) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, $this->getResidue());
|
||||
}
|
||||
}
|
||||
|
78
src/block/CakeWithCandle.php
Normal file
78
src/block/CakeWithCandle.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CandleTrait;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
class CakeWithCandle extends BaseCake{
|
||||
use CandleTrait {
|
||||
onInteract as onInteractCandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [
|
||||
AxisAlignedBB::one()
|
||||
->contract(1 / 16, 0, 1 / 16)
|
||||
->trim(Facing::UP, 0.5) //TODO: not sure if the candle affects height
|
||||
];
|
||||
}
|
||||
|
||||
public function getCandle() : Candle{
|
||||
return VanillaBlocks::CANDLE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($this->onInteractCandle($item, $face, $clickVector, $player, $returnedItems)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::onInteract($item, $face, $clickVector, $player, $returnedItems);
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [$this->getCandle()->asItem()];
|
||||
}
|
||||
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
return VanillaBlocks::CAKE()->getPickedItem($addUserData);
|
||||
}
|
||||
|
||||
public function getResidue() : Block{
|
||||
return VanillaBlocks::CAKE()->setBites(1);
|
||||
}
|
||||
|
||||
public function onConsume(Living $consumer) : void{
|
||||
parent::onConsume($consumer);
|
||||
$this->position->getWorld()->dropItem($this->position->add(0.5, 0.5, 0.5), $this->getCandle()->asItem());
|
||||
}
|
||||
}
|
40
src/block/CakeWithDyedCandle.php
Normal file
40
src/block/CakeWithDyedCandle.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
|
||||
class CakeWithDyedCandle extends CakeWithCandle{
|
||||
use ColoredTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function getCandle() : Candle{
|
||||
return VanillaBlocks::DYED_CANDLE()->setColor($this->color);
|
||||
}
|
||||
}
|
126
src/block/Candle.php
Normal file
126
src/block/Candle.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CandleTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
class Candle extends Transparent{
|
||||
use CandleTrait {
|
||||
describeState as encodeLitState;
|
||||
getLightLevel as getBaseLightLevel;
|
||||
}
|
||||
|
||||
public const MIN_COUNT = 1;
|
||||
public const MAX_COUNT = 4;
|
||||
|
||||
private int $count = self::MIN_COUNT;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$this->encodeLitState($w);
|
||||
$w->boundedInt(2, self::MIN_COUNT, self::MAX_COUNT, $this->count);
|
||||
}
|
||||
|
||||
public function getCount() : int{ return $this->count; }
|
||||
|
||||
/** @return $this */
|
||||
public function setCount(int $count) : self{
|
||||
if($count < self::MIN_COUNT || $count > self::MAX_COUNT){
|
||||
throw new \InvalidArgumentException("Count must be in range " . self::MIN_COUNT . " ... " . self::MAX_COUNT);
|
||||
}
|
||||
$this->count = $count;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return $this->getBaseLightLevel() * $this->count;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [
|
||||
(match($this->count){
|
||||
1 => AxisAlignedBB::one()
|
||||
->squash(Axis::X, 7 / 16)
|
||||
->squash(Axis::Z, 7 / 16),
|
||||
2 => AxisAlignedBB::one()
|
||||
->squash(Axis::X, 5 / 16)
|
||||
->trim(Facing::NORTH, 7 / 16) //0.3 thick on the Z axis
|
||||
->trim(Facing::SOUTH, 6 / 16),
|
||||
3 => AxisAlignedBB::one()
|
||||
->trim(Facing::WEST, 5 / 16)
|
||||
->trim(Facing::EAST, 6 / 16)
|
||||
->trim(Facing::NORTH, 6 / 16)
|
||||
->trim(Facing::SOUTH, 5 / 16),
|
||||
4 => AxisAlignedBB::one()
|
||||
->squash(Axis::X, 5 / 16)
|
||||
->trim(Facing::NORTH, 5 / 16)
|
||||
->trim(Facing::SOUTH, 6 / 16),
|
||||
default => throw new AssumptionFailedError("Unreachable")
|
||||
})->trim(Facing::UP, 10 / 16)
|
||||
];
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
protected function getCandleIfCompatibleType(Block $block) : ?Candle{
|
||||
return $block instanceof Candle && $block->isSameType($this) ? $block : null;
|
||||
}
|
||||
|
||||
public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{
|
||||
$candle = $this->getCandleIfCompatibleType($blockReplace);
|
||||
return $candle !== null ? $candle->count < self::MAX_COUNT : parent::canBePlacedAt($blockReplace, $clickVector, $face, $isClickedBlock);
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $blockReplace->getSide(Facing::DOWN);
|
||||
if(!$down->getSupportType(Facing::UP)->hasCenterSupport()){
|
||||
return false;
|
||||
}
|
||||
$existing = $this->getCandleIfCompatibleType($blockReplace);
|
||||
if($existing !== null){
|
||||
if($existing->count >= self::MAX_COUNT){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->count = $existing->count + 1;
|
||||
$this->lit = $existing->lit;
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [$this->asItem()->setCount($this->count)];
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorInMetadataTrait;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -33,11 +33,11 @@ use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
class Carpet extends Flowable{
|
||||
use ColorInMetadataTrait;
|
||||
use ColoredTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function isSolid() : bool{
|
||||
@ -53,7 +53,7 @@ class Carpet extends Flowable{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getId() !== BlockLegacyIds::AIR){
|
||||
if($down->getTypeId() !== BlockTypeIds::AIR){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ class Carpet extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->getId() === BlockLegacyIds::AIR){
|
||||
if($this->getSide(Facing::DOWN)->getTypeId() === BlockTypeIds::AIR){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class Carrot extends Crops{
|
||||
];
|
||||
}
|
||||
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::CARROT();
|
||||
}
|
||||
}
|
||||
|
44
src/block/CartographyTable.php
Normal file
44
src/block/CartographyTable.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\inventory\CartographyTableInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
final class CartographyTable extends Opaque{
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player !== null){
|
||||
$player->setCurrentWindow(new CartographyTableInventory($this->position));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
@ -23,23 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
|
||||
class CarvedPumpkin extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b11;
|
||||
}
|
||||
}
|
||||
|
104
src/block/Cauldron.php
Normal file
104
src/block/Cauldron.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Cauldron as TileCauldron;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemTypeIds;
|
||||
use pocketmine\item\Potion;
|
||||
use pocketmine\item\PotionType;
|
||||
use pocketmine\item\SplashPotion;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use function assert;
|
||||
|
||||
final class Cauldron extends Transparent{
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
parent::writeStateToWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
assert($tile instanceof TileCauldron);
|
||||
|
||||
//empty cauldrons don't use this information
|
||||
$tile->setCustomWaterColor(null);
|
||||
$tile->setPotionItem(null);
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$result = [
|
||||
AxisAlignedBB::one()->trim(Facing::UP, 11 / 16) //bottom of the cauldron
|
||||
];
|
||||
|
||||
foreach(Facing::HORIZONTAL as $f){ //add the frame parts around the bowl
|
||||
$result[] = AxisAlignedBB::one()->trim($f, 14 / 16);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return $facing === Facing::UP ? SupportType::EDGE() : SupportType::NONE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] &$returnedItems
|
||||
*/
|
||||
private function fill(int $amount, FillableCauldron $result, Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, $result->setFillLevel($amount));
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $result->getFillSound());
|
||||
|
||||
$usedItem->pop();
|
||||
$returnedItems[] = $returnedItem;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item->getTypeId() === ItemTypeIds::WATER_BUCKET){
|
||||
$this->fill(FillableCauldron::MAX_FILL_LEVEL, VanillaBlocks::WATER_CAULDRON(), $item, VanillaItems::BUCKET(), $returnedItems);
|
||||
}elseif($item->getTypeId() === ItemTypeIds::LAVA_BUCKET){
|
||||
$this->fill(FillableCauldron::MAX_FILL_LEVEL, VanillaBlocks::LAVA_CAULDRON(), $item, VanillaItems::BUCKET(), $returnedItems);
|
||||
}elseif($item->getTypeId() === ItemTypeIds::POWDER_SNOW_BUCKET){
|
||||
//TODO: powder snow cauldron
|
||||
}elseif($item instanceof Potion || $item instanceof SplashPotion){ //TODO: lingering potion
|
||||
if($item->getType()->equals(PotionType::WATER())){
|
||||
$this->fill(WaterCauldron::WATER_BOTTLE_FILL_AMOUNT, VanillaBlocks::WATER_CAULDRON(), $item, VanillaItems::GLASS_BOTTLE(), $returnedItems);
|
||||
}else{
|
||||
$this->fill(PotionCauldron::POTION_FILL_AMOUNT, VanillaBlocks::POTION_CAULDRON()->setPotionItem($item), $item, VanillaItems::GLASS_BOTTLE(), $returnedItems);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if($world->getBlock($this->position->up())->getTypeId() === BlockTypeIds::WATER){
|
||||
$cauldron = VanillaBlocks::WATER_CAULDRON()->setFillLevel(FillableCauldron::MAX_FILL_LEVEL);
|
||||
$world->setBlock($this->position, $cauldron);
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), $cauldron->getFillSound());
|
||||
}
|
||||
}
|
||||
}
|
48
src/block/Chain.php
Normal file
48
src/block/Chain.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\PillarRotationTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
|
||||
final class Chain extends Transparent{
|
||||
use PillarRotationTrait;
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return $this->axis === Axis::Y && Facing::axis($facing) === Axis::Y ? SupportType::CENTER() : SupportType::NONE();
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$bb = AxisAlignedBB::one();
|
||||
foreach([Axis::Y, Axis::Z, Axis::X] as $axis){
|
||||
if($axis !== $this->axis){
|
||||
$bb->squash($axis, 13 / 32);
|
||||
}
|
||||
}
|
||||
return [$bb];
|
||||
}
|
||||
}
|
@ -23,11 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
@ -35,19 +33,7 @@ final class ChemistryTable extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = Facing::opposite(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x3));
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::opposite($this->facing));
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b0011;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
//TODO
|
||||
return false;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Chest as TileChest;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\event\block\ChestPairEvent;
|
||||
use pocketmine\item\Item;
|
||||
@ -36,7 +36,7 @@ use pocketmine\player\Player;
|
||||
|
||||
class Chest extends Transparent{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use NormalHorizontalFacingInMetadataTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
@ -74,7 +74,7 @@ class Chest extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player instanceof Player){
|
||||
|
||||
$chest = $this->position->getWorld()->getTile($this->position);
|
||||
|
233
src/block/ChorusFlower.php
Normal file
233
src/block/ChorusFlower.php
Normal file
@ -0,0 +1,233 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\projectile\Projectile;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\Position;
|
||||
use pocketmine\world\sound\ChorusFlowerDieSound;
|
||||
use pocketmine\world\sound\ChorusFlowerGrowSound;
|
||||
use pocketmine\world\World;
|
||||
use function array_rand;
|
||||
use function mt_rand;
|
||||
|
||||
final class ChorusFlower extends Flowable{
|
||||
public const MIN_AGE = 0;
|
||||
public const MAX_AGE = 5;
|
||||
|
||||
private const MAX_STEM_HEIGHT = 5;
|
||||
|
||||
private int $age = self::MIN_AGE;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, self::MIN_AGE, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
|
||||
/** @return $this */
|
||||
public function setAge(int $age) : self{
|
||||
if($age < self::MIN_AGE || $age > self::MAX_AGE){
|
||||
throw new \InvalidArgumentException("Age must be in the range " . self::MIN_AGE . " ... " . self::MAX_AGE);
|
||||
}
|
||||
$this->age = $age;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [AxisAlignedBB::one()];
|
||||
}
|
||||
|
||||
private function canBeSupportedAt(Position $position) : bool{
|
||||
$world = $position->getWorld();
|
||||
$down = $world->getBlock($position->down());
|
||||
|
||||
if($down->getTypeId() === BlockTypeIds::END_STONE || $down->getTypeId() === BlockTypeIds::CHORUS_PLANT){
|
||||
return true;
|
||||
}
|
||||
|
||||
$plantAdjacent = false;
|
||||
foreach($position->sidesAroundAxis(Axis::Y) as $sidePosition){
|
||||
$block = $world->getBlock($sidePosition);
|
||||
|
||||
if($block->getTypeId() === BlockTypeIds::CHORUS_PLANT){
|
||||
if($plantAdjacent){ //at most one plant may be horizontally adjacent
|
||||
return false;
|
||||
}
|
||||
$plantAdjacent = true;
|
||||
}elseif($block->getTypeId() !== BlockTypeIds::AIR){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $plantAdjacent;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedAt($blockReplace->getPosition())){
|
||||
return false;
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedAt($this->position)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{ return $this->age < self::MAX_AGE; }
|
||||
|
||||
/**
|
||||
* @phpstan-return array{int, bool}
|
||||
*/
|
||||
private function scanStem() : array{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
$stemHeight = 0;
|
||||
$endStoneBelow = false;
|
||||
for($yOffset = 0; $yOffset < self::MAX_STEM_HEIGHT; $yOffset++, $stemHeight++){
|
||||
$down = $world->getBlock($this->position->down($yOffset + 1));
|
||||
|
||||
if($down->getTypeId() !== BlockTypeIds::CHORUS_PLANT){
|
||||
if($down->getTypeId() === BlockTypeIds::END_STONE){
|
||||
$endStoneBelow = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [$stemHeight, $endStoneBelow];
|
||||
}
|
||||
|
||||
private function allHorizontalBlocksEmpty(World $world, Vector3 $position, ?int $except) : bool{
|
||||
foreach($position->sidesAroundAxis(Axis::Y) as $facing => $sidePosition){
|
||||
if($facing === $except){
|
||||
continue;
|
||||
}
|
||||
if($world->getBlock($sidePosition)->getTypeId() !== BlockTypeIds::AIR){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function canGrowUpwards(int $stemHeight, bool $endStoneBelow) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
$up = $this->position->up();
|
||||
if(
|
||||
//the space above must be empty and writable
|
||||
!$world->isInWorld($up->x, $up->y, $up->z) ||
|
||||
$world->getBlock($up)->getTypeId() !== BlockTypeIds::AIR ||
|
||||
(
|
||||
//the space above that must be empty, but doesn't need to be writable
|
||||
$world->isInWorld($up->x, $up->y + 1, $up->z) &&
|
||||
$world->getBlock($up->up())->getTypeId() !== BlockTypeIds::AIR
|
||||
)
|
||||
){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->getSide(Facing::DOWN)->getTypeId() !== BlockTypeIds::AIR){
|
||||
if($stemHeight >= self::MAX_STEM_HEIGHT){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($stemHeight > 1 && $stemHeight > mt_rand(0, $endStoneBelow ? 4 : 3)){ //chance decreases for each added block of chorus plant
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->allHorizontalBlocksEmpty($world, $up, null);
|
||||
}
|
||||
|
||||
private function grow(int $facing, int $ageChange, ?BlockTransaction $tx) : BlockTransaction{
|
||||
if($tx === null){
|
||||
$tx = new BlockTransaction($this->position->getWorld());
|
||||
}
|
||||
$tx->addBlock($this->position->getSide($facing), (clone $this)->setAge($this->getAge() + $ageChange));
|
||||
|
||||
return $tx;
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
if($this->age >= self::MAX_AGE){
|
||||
return;
|
||||
}
|
||||
|
||||
$tx = null;
|
||||
|
||||
[$stemHeight, $endStoneBelow] = $this->scanStem();
|
||||
if($this->canGrowUpwards($stemHeight, $endStoneBelow)){
|
||||
$tx = $this->grow(Facing::UP, 0, $tx);
|
||||
}else{
|
||||
$facingVisited = [];
|
||||
for($attempts = 0, $maxAttempts = mt_rand(0, $endStoneBelow ? 4 : 3); $attempts < $maxAttempts; $attempts++){
|
||||
$facing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)];
|
||||
if(isset($facingVisited[$facing])){
|
||||
continue;
|
||||
}
|
||||
$facingVisited[$facing] = true;
|
||||
|
||||
$sidePosition = $this->position->getSide($facing);
|
||||
if(
|
||||
$world->getBlock($sidePosition)->getTypeId() === BlockTypeIds::AIR &&
|
||||
$world->getBlock($sidePosition->down())->getTypeId() === BlockTypeIds::AIR &&
|
||||
$this->allHorizontalBlocksEmpty($world, $sidePosition, Facing::opposite($facing))
|
||||
){
|
||||
$tx = $this->grow($facing, 1, $tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($tx !== null){
|
||||
$tx->addBlock($this->position, VanillaBlocks::CHORUS_PLANT());
|
||||
$ev = new StructureGrowEvent($this, $tx, null);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled() && $tx->apply()){
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ChorusFlowerGrowSound());
|
||||
}
|
||||
}else{
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ChorusFlowerDieSound());
|
||||
$this->position->getWorld()->setBlock($this->position, $this->setAge(self::MAX_AGE));
|
||||
}
|
||||
}
|
||||
}
|
102
src/block/ChorusPlant.php
Normal file
102
src/block/ChorusPlant.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\Position;
|
||||
use function mt_rand;
|
||||
|
||||
final class ChorusPlant extends Flowable{
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$bb = AxisAlignedBB::one();
|
||||
foreach($this->getAllSides() as $facing => $block){
|
||||
$id = $block->getTypeId();
|
||||
if($id !== BlockTypeIds::END_STONE && $id !== BlockTypeIds::CHORUS_FLOWER && !$block->isSameType($this)){
|
||||
$bb->trim($facing, 2 / 16);
|
||||
}
|
||||
}
|
||||
|
||||
return [$bb];
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->isSameType($this) || $block->getTypeId() === BlockTypeIds::END_STONE;
|
||||
}
|
||||
|
||||
private function canStay(Position $position) : bool{
|
||||
$world = $position->getWorld();
|
||||
|
||||
$down = $world->getBlock($position->down());
|
||||
$verticalAir = $down->getTypeId() === BlockTypeIds::AIR || $world->getBlock($position->up())->getTypeId() === BlockTypeIds::AIR;
|
||||
|
||||
foreach($position->sidesAroundAxis(Axis::Y) as $sidePosition){
|
||||
$block = $world->getBlock($sidePosition);
|
||||
|
||||
if($block->getTypeId() === BlockTypeIds::CHORUS_PLANT){
|
||||
if(!$verticalAir){
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->canBeSupportedBy($block->getSide(Facing::DOWN))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->canBeSupportedBy($down)){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canStay($blockReplace->getPosition())){
|
||||
return false;
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canStay($this->position)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(mt_rand(0, 1) === 1){
|
||||
return [VanillaItems::CHORUS_FRUIT()];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -23,10 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\block\utils\TreeType;
|
||||
use pocketmine\block\utils\WoodType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
@ -46,17 +46,9 @@ class CocoaBlock extends Transparent{
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::opposite($this->facing)) | ($this->age << 2);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = Facing::opposite(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03));
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta >> 2, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->boundedInt(2, 0, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
@ -89,7 +81,7 @@ class CocoaBlock extends Transparent{
|
||||
}
|
||||
|
||||
private function canAttachTo(Block $block) : bool{
|
||||
return $block instanceof Wood && $block->getTreeType()->equals(TreeType::JUNGLE());
|
||||
return $block instanceof Wood && $block->getWoodType()->equals(WoodType::JUNGLE());
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
@ -101,7 +93,7 @@ class CocoaBlock extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof Fertilizer && $this->grow()){
|
||||
$item->pop();
|
||||
|
||||
@ -147,7 +139,7 @@ class CocoaBlock extends Transparent{
|
||||
];
|
||||
}
|
||||
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::COCOA_BEANS();
|
||||
}
|
||||
}
|
||||
|
@ -23,14 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorInMetadataTrait;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
|
||||
class Concrete extends Opaque{
|
||||
use ColorInMetadataTrait;
|
||||
use ColoredTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorInMetadataTrait;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\Fallable;
|
||||
use pocketmine\block\utils\FallableTrait;
|
||||
@ -31,19 +31,19 @@ use pocketmine\event\block\BlockFormEvent;
|
||||
use pocketmine\math\Facing;
|
||||
|
||||
class ConcretePowder extends Opaque implements Fallable{
|
||||
use ColorInMetadataTrait;
|
||||
use ColoredTrait;
|
||||
use FallableTrait {
|
||||
onNearbyBlockChange as protected startFalling;
|
||||
}
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(($block = $this->checkAdjacentWater()) !== null){
|
||||
$ev = new BlockFormEvent($this, $block);
|
||||
if(($water = $this->getAdjacentWater()) !== null){
|
||||
$ev = new BlockFormEvent($this, VanillaBlocks::CONCRETE()->setColor($this->color), $water);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->position->getWorld()->setBlock($this->position, $ev->getNewState());
|
||||
@ -54,16 +54,20 @@ class ConcretePowder extends Opaque implements Fallable{
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return $this->checkAdjacentWater();
|
||||
if($this->getAdjacentWater() === null){
|
||||
return null;
|
||||
}
|
||||
return VanillaBlocks::CONCRETE()->setColor($this->color);
|
||||
}
|
||||
|
||||
private function checkAdjacentWater() : ?Block{
|
||||
private function getAdjacentWater() : ?Water{
|
||||
foreach(Facing::ALL as $i){
|
||||
if($i === Facing::DOWN){
|
||||
continue;
|
||||
}
|
||||
if($this->getSide($i) instanceof Water){
|
||||
return VanillaBlocks::CONCRETE()->setColor($this->color);
|
||||
$block = $this->getSide($i);
|
||||
if($block instanceof Water){
|
||||
return $block;
|
||||
}
|
||||
}
|
||||
|
||||
|
30
src/block/Copper.php
Normal file
30
src/block/Copper.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CopperTrait;
|
||||
|
||||
class Copper extends Opaque{
|
||||
use CopperTrait;
|
||||
}
|
36
src/block/CopperOre.php
Normal file
36
src/block/CopperOre.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
|
||||
final class CopperOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [VanillaItems::RAW_COPPER()];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{ return true; }
|
||||
}
|
30
src/block/CopperSlab.php
Normal file
30
src/block/CopperSlab.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CopperTrait;
|
||||
|
||||
class CopperSlab extends Slab{
|
||||
use CopperTrait;
|
||||
}
|
36
src/block/CopperStairs.php
Normal file
36
src/block/CopperStairs.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CopperOxidation;
|
||||
use pocketmine\block\utils\CopperTrait;
|
||||
|
||||
class CopperStairs extends Stair{
|
||||
use CopperTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->oxidation = CopperOxidation::NONE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
}
|
@ -23,8 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\data\bedrock\CoralTypeIdMap;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -33,38 +31,6 @@ use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class Coral extends BaseCoral{
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta);
|
||||
if($coralType === null){
|
||||
throw new InvalidBlockStateException("No such coral type");
|
||||
}
|
||||
$this->coralType = $coralType;
|
||||
}
|
||||
|
||||
public function writeStateToMeta() : int{
|
||||
return CoralTypeIdMap::getInstance()->toId($this->coralType);
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return $this->writeStateToMeta();
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b0111;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
//TODO: this hack ensures correct state of coral plants, because they don't retain their dead flag in metadata
|
||||
$world = $this->position->getWorld();
|
||||
$this->dead = true;
|
||||
foreach($this->position->sides() as $vector3){
|
||||
if($world->getBlock($vector3) instanceof Water){
|
||||
$this->dead = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($tx->fetchBlock($blockReplace->getPosition()->down()))){
|
||||
return false;
|
||||
|
@ -25,8 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\CoralTypeTrait;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\data\bedrock\CoralTypeIdMap;
|
||||
use pocketmine\event\block\BlockDeathEvent;
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
@ -34,30 +32,9 @@ use function mt_rand;
|
||||
final class CoralBlock extends Opaque{
|
||||
use CoralTypeTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->coralType = CoralType::TUBE();
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta & 0x7);
|
||||
if($coralType === null){
|
||||
throw new InvalidBlockStateException("No such coral type");
|
||||
}
|
||||
$this->coralType = $coralType;
|
||||
$this->dead = ($stateMeta & BlockLegacyMetadata::CORAL_BLOCK_FLAG_DEAD) !== 0;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return ($this->dead ? BlockLegacyMetadata::CORAL_BLOCK_FLAG_DEAD : 0) | CoralTypeIdMap::getInstance()->toId($this->coralType);
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return $this->writeStateToMeta();
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
|
@ -30,7 +30,7 @@ use pocketmine\player\Player;
|
||||
|
||||
class CraftingTable extends Opaque{
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player instanceof Player){
|
||||
$player->setCurrentWindow(new CraftingTableInventory($this->position));
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
@ -38,16 +38,8 @@ abstract class Crops extends Flowable{
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, 0, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
@ -62,14 +54,14 @@ abstract class Crops extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($blockReplace->getSide(Facing::DOWN)->getId() === BlockLegacyIds::FARMLAND){
|
||||
if($blockReplace->getSide(Facing::DOWN)->getTypeId() === BlockTypeIds::FARMLAND){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($this->age < self::MAX_AGE && $item instanceof Fertilizer){
|
||||
$block = clone $this;
|
||||
$block->age += mt_rand(2, 5);
|
||||
@ -91,7 +83,7 @@ abstract class Crops extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->getId() !== BlockLegacyIds::FARMLAND){
|
||||
if($this->getSide(Facing::DOWN)->getTypeId() !== BlockTypeIds::FARMLAND){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\AnalogRedstoneSignalEmitterTrait;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
@ -39,30 +39,11 @@ use const M_PI;
|
||||
class DaylightSensor extends Transparent{
|
||||
use AnalogRedstoneSignalEmitterTrait;
|
||||
|
||||
protected BlockIdentifierFlattened $idInfoFlattened;
|
||||
|
||||
protected bool $inverted = false;
|
||||
|
||||
public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->idInfoFlattened = $idInfo;
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function getId() : int{
|
||||
return $this->inverted ? $this->idInfoFlattened->getSecondId() : parent::getId();
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->signalStrength;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->signalStrength = BlockDataSerializer::readBoundedInt("signalStrength", $stateMeta, 0, 15);
|
||||
$this->inverted = $id === $this->idInfoFlattened->getSecondId();
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(4, 0, 15, $this->signalStrength);
|
||||
$w->bool($this->inverted);
|
||||
}
|
||||
|
||||
public function isInverted() : bool{
|
||||
@ -92,7 +73,7 @@ class DaylightSensor extends Transparent{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$this->inverted = !$this->inverted;
|
||||
$this->signalStrength = $this->recalculateSignalStrength();
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
|
@ -66,12 +66,13 @@ class DeadBush extends Flowable{
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
$blockId = $block->getId();
|
||||
return $blockId === BlockLegacyIds::SAND
|
||||
|| $blockId === BlockLegacyIds::PODZOL
|
||||
|| $blockId === BlockLegacyIds::MYCELIUM
|
||||
|| $blockId === BlockLegacyIds::DIRT
|
||||
|| $blockId === BlockLegacyIds::HARDENED_CLAY
|
||||
|| $blockId === BlockLegacyIds::STAINED_HARDENED_CLAY;
|
||||
$blockId = $block->getTypeId();
|
||||
return $blockId === BlockTypeIds::SAND
|
||||
|| $blockId === BlockTypeIds::RED_SAND
|
||||
|| $blockId === BlockTypeIds::PODZOL
|
||||
|| $blockId === BlockTypeIds::MYCELIUM
|
||||
|| $blockId === BlockTypeIds::DIRT
|
||||
|| $blockId === BlockTypeIds::HARDENED_CLAY
|
||||
|| $blockId === BlockTypeIds::STAINED_CLAY;
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
|
||||
class DetectorRail extends StraightOnlyRail{
|
||||
protected bool $activated = false;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
parent::describeState($w);
|
||||
$w->bool($this->activated);
|
||||
}
|
||||
|
||||
public function isActivated() : bool{ return $this->activated; }
|
||||
|
||||
/** @return $this */
|
||||
@ -33,19 +40,5 @@ class DetectorRail extends StraightOnlyRail{
|
||||
$this->activated = $activated;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
parent::readStateFromData($id, $stateMeta & ~BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED);
|
||||
$this->activated = ($stateMeta & BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED) !== 0;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return parent::writeStateToMeta() | ($this->activated ? BlockLegacyMetadata::REDSTONE_RAIL_FLAG_POWERED : 0);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -23,50 +23,67 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\DirtType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Hoe;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Potion;
|
||||
use pocketmine\item\PotionType;
|
||||
use pocketmine\item\SplashPotion;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\sound\ItemUseOnBlockSound;
|
||||
use pocketmine\world\sound\WaterSplashSound;
|
||||
|
||||
class Dirt extends Opaque{
|
||||
protected DirtType $dirtType;
|
||||
|
||||
protected bool $coarse = false;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->coarse = ($stateMeta & BlockLegacyMetadata::DIRT_FLAG_COARSE) !== 0;
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->dirtType = DirtType::NORMAL();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->coarse ? BlockLegacyMetadata::DIRT_FLAG_COARSE : 0;
|
||||
protected function describeType(RuntimeDataDescriber $w) : void{
|
||||
$w->dirtType($this->dirtType);
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return $this->writeStateToMeta();
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1;
|
||||
}
|
||||
|
||||
public function isCoarse() : bool{ return $this->coarse; }
|
||||
public function getDirtType() : DirtType{ return $this->dirtType; }
|
||||
|
||||
/** @return $this */
|
||||
public function setCoarse(bool $coarse) : self{
|
||||
$this->coarse = $coarse;
|
||||
public function setDirtType(DirtType $dirtType) : self{
|
||||
$this->dirtType = $dirtType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
if($face === Facing::UP && $item instanceof Hoe){
|
||||
$item->applyDamage(1);
|
||||
|
||||
$newBlock = $this->coarse ? VanillaBlocks::DIRT() : VanillaBlocks::FARMLAND();
|
||||
$world = $this->position->getWorld();
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock));
|
||||
$newBlock = $this->dirtType->equals(DirtType::NORMAL()) ? VanillaBlocks::FARMLAND() : VanillaBlocks::DIRT();
|
||||
$center = $this->position->add(0.5, 0.5, 0.5);
|
||||
$world->addSound($center, new ItemUseOnBlockSound($newBlock));
|
||||
$world->setBlock($this->position, $newBlock);
|
||||
if($this->dirtType->equals(DirtType::ROOTED())){
|
||||
$world->dropItem($center, VanillaBlocks::HANGING_ROOTS()->asItem());
|
||||
}
|
||||
|
||||
return true;
|
||||
}elseif($this->dirtType->equals(DirtType::ROOTED()) && $item instanceof Fertilizer){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getTypeId() !== BlockTypeIds::AIR){
|
||||
return true;
|
||||
}
|
||||
|
||||
$item->pop();
|
||||
$world->setBlock($down->position, VanillaBlocks::HANGING_ROOTS());
|
||||
//TODO: bonemeal particles, growth sounds
|
||||
}elseif(($item instanceof Potion || $item instanceof SplashPotion) && $item->getType()->equals(PotionType::WATER())){
|
||||
$item->pop();
|
||||
$world->setBlock($this->position, VanillaBlocks::MUD());
|
||||
$world->addSound($this->position, new WaterSplashSound(0.5));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\PoweredByRedstoneTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
@ -37,38 +36,19 @@ use pocketmine\world\sound\DoorSound;
|
||||
|
||||
class Door extends Transparent{
|
||||
use HorizontalFacingTrait;
|
||||
use PoweredByRedstoneTrait;
|
||||
|
||||
protected bool $top = false;
|
||||
protected bool $hingeRight = false;
|
||||
protected bool $open = false;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
if($this->top){
|
||||
return BlockLegacyMetadata::DOOR_FLAG_TOP |
|
||||
($this->hingeRight ? BlockLegacyMetadata::DOOR_TOP_FLAG_RIGHT : 0) |
|
||||
($this->powered ? BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED : 0);
|
||||
}
|
||||
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing(Facing::rotateY($this->facing, true)) | ($this->open ? BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN : 0);
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->top);
|
||||
$w->bool($this->hingeRight);
|
||||
$w->bool($this->open);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->top = ($stateMeta & BlockLegacyMetadata::DOOR_FLAG_TOP) !== 0;
|
||||
if($this->top){
|
||||
$this->hingeRight = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_RIGHT) !== 0;
|
||||
$this->powered = ($stateMeta & BlockLegacyMetadata::DOOR_TOP_FLAG_POWERED) !== 0;
|
||||
}else{
|
||||
$this->facing = Facing::rotateY(BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03), false);
|
||||
$this->open = ($stateMeta & BlockLegacyMetadata::DOOR_BOTTOM_FLAG_OPEN) !== 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
public function readStateFromWorld() : Block{
|
||||
parent::readStateFromWorld();
|
||||
|
||||
//copy door properties from other half
|
||||
@ -79,9 +59,10 @@ class Door extends Transparent{
|
||||
$this->open = $other->open;
|
||||
}else{
|
||||
$this->hingeRight = $other->hingeRight;
|
||||
$this->powered = $other->powered;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isTop() : bool{ return $this->top; }
|
||||
@ -159,7 +140,7 @@ class Door extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$this->open = !$this->open;
|
||||
|
||||
$other = $this->getSide($this->top ? Facing::DOWN : Facing::UP);
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -30,19 +31,10 @@ use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
class DoublePlant extends Flowable{
|
||||
|
||||
protected bool $top = false;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return ($this->top ? BlockLegacyMetadata::DOUBLE_PLANT_FLAG_TOP : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->top = ($stateMeta & BlockLegacyMetadata::DOUBLE_PLANT_FLAG_TOP) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1000;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->bool($this->top);
|
||||
}
|
||||
|
||||
public function isTop() : bool{ return $this->top; }
|
||||
@ -54,8 +46,8 @@ class DoublePlant extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$id = $blockReplace->getSide(Facing::DOWN)->getId();
|
||||
if(($id === BlockLegacyIds::GRASS || $id === BlockLegacyIds::DIRT) && $blockReplace->getSide(Facing::UP)->canBeReplaced()){
|
||||
$down = $blockReplace->getSide(Facing::DOWN);
|
||||
if($down->hasTypeTag(BlockTypeTags::DIRT) && $blockReplace->getSide(Facing::UP)->canBeReplaced()){
|
||||
$top = clone $this;
|
||||
$top->top = true;
|
||||
$tx->addBlock($blockReplace->position, $this)->addBlock($blockReplace->position->getSide(Facing::UP), $top);
|
||||
@ -79,7 +71,8 @@ class DoublePlant extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->isValidHalfPlant() || (!$this->top && $this->getSide(Facing::DOWN)->isTransparent())){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(!$this->isValidHalfPlant() || (!$this->top && !$down->hasTypeTag(BlockTypeTags::DIRT) && !$down->hasTypeTag(BlockTypeTags::MUD))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -44,11 +44,7 @@ class DragonEgg extends Transparent implements Fallable{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$this->teleport();
|
||||
return true;
|
||||
}
|
||||
|
42
src/block/DyedCandle.php
Normal file
42
src/block/DyedCandle.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
|
||||
class DyedCandle extends Candle{
|
||||
use ColoredTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
protected function getCandleIfCompatibleType(Block $block) : ?Candle{
|
||||
$result = parent::getCandleIfCompatibleType($block);
|
||||
//different coloured candles can't be combined in the same block
|
||||
return $result instanceof DyedCandle && $result->color->equals($this->color) ? $result : null;
|
||||
}
|
||||
}
|
@ -23,14 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorInMetadataTrait;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
|
||||
final class DyedShulkerBox extends ShulkerBox{
|
||||
use ColorInMetadataTrait;
|
||||
use ColoredTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::WHITE();
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
}
|
||||
|
@ -27,12 +27,12 @@ class Element extends Opaque{
|
||||
public function __construct(
|
||||
BlockIdentifier $idInfo,
|
||||
string $name,
|
||||
BlockBreakInfo $breakInfo,
|
||||
BlockTypeInfo $typeInfo,
|
||||
private string $symbol,
|
||||
private int $atomicWeight,
|
||||
private int $group
|
||||
){
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
public function getAtomicWeight() : int{
|
||||
|
@ -44,7 +44,7 @@ class EnchantingTable extends Transparent{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player instanceof Player){
|
||||
//TODO lock
|
||||
|
||||
|
@ -23,9 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
|
||||
@ -35,17 +35,9 @@ class EndPortalFrame extends Opaque{
|
||||
|
||||
protected bool $eye = false;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) | ($this->eye ? BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03);
|
||||
$this->eye = ($stateMeta & BlockLegacyMetadata::END_PORTAL_FRAME_FLAG_EYE) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->eye);
|
||||
}
|
||||
|
||||
public function hasEye() : bool{ return $this->eye; }
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\AnyFacingTrait;
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -36,27 +35,6 @@ use pocketmine\world\BlockTransaction;
|
||||
class EndRod extends Flowable{
|
||||
use AnyFacingTrait;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
$result = BlockDataSerializer::writeFacing($this->facing);
|
||||
if(Facing::axis($this->facing) !== Axis::Y){
|
||||
$result ^= 1; //TODO: in PC this is always the same as facing, just PE is stupid
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
if($stateMeta !== 0 && $stateMeta !== 1){
|
||||
$stateMeta ^= 1;
|
||||
}
|
||||
|
||||
$this->facing = BlockDataSerializer::readFacing($stateMeta);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$this->facing = $face;
|
||||
if($blockClicked instanceof EndRod && $blockClicked->facing === $this->facing){
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\inventory\EnderChestInventory;
|
||||
use pocketmine\block\tile\EnderChest as TileEnderChest;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -36,7 +36,7 @@ use pocketmine\player\Player;
|
||||
|
||||
class EnderChest extends Transparent{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use NormalHorizontalFacingInMetadataTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 7;
|
||||
@ -54,7 +54,7 @@ class EnderChest extends Transparent{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player instanceof Player){
|
||||
$enderChest = $this->position->getWorld()->getTile($this->position);
|
||||
if($enderChest instanceof TileEnderChest && $this->getSide(Facing::UP)->isTransparent()){
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\event\entity\EntityTrampleFarmlandEvent;
|
||||
@ -37,16 +37,8 @@ class Farmland extends Transparent{
|
||||
|
||||
protected int $wetness = 0; //"moisture" blockstate property in PC
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->wetness;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->wetness = BlockDataSerializer::readBoundedInt("wetness", $stateMeta, 0, self::MAX_WETNESS);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, 0, self::MAX_WETNESS, $this->wetness);
|
||||
}
|
||||
|
||||
public function getWetness() : int{ return $this->wetness; }
|
||||
|
@ -37,7 +37,7 @@ class Fence extends Transparent{
|
||||
return 0.25;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
public function readStateFromWorld() : Block{
|
||||
parent::readStateFromWorld();
|
||||
|
||||
foreach(Facing::HORIZONTAL as $facing){
|
||||
@ -48,6 +48,8 @@ class Fence extends Transparent{
|
||||
unset($this->connections[$facing]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,9 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\block\utils\WoodTypeTrait;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
@ -35,25 +36,16 @@ use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\DoorSound;
|
||||
|
||||
class FenceGate extends Transparent{
|
||||
use WoodTypeTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected bool $open = false;
|
||||
protected bool $inWall = false;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return BlockDataSerializer::writeLegacyHorizontalFacing($this->facing) |
|
||||
($this->open ? BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN : 0) |
|
||||
($this->inWall ? BlockLegacyMetadata::FENCE_GATE_FLAG_IN_WALL : 0);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->facing = BlockDataSerializer::readLegacyHorizontalFacing($stateMeta & 0x03);
|
||||
$this->open = ($stateMeta & BlockLegacyMetadata::FENCE_GATE_FLAG_OPEN) !== 0;
|
||||
$this->inWall = ($stateMeta & BlockLegacyMetadata::FENCE_GATE_FLAG_IN_WALL) !== 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->open);
|
||||
$w->bool($this->inWall);
|
||||
}
|
||||
|
||||
public function isOpen() : bool{ return $this->open; }
|
||||
@ -108,7 +100,7 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$this->open = !$this->open;
|
||||
if($this->open && $player !== null){
|
||||
$playerFacing = $player->getHorizontalFacing();
|
||||
@ -124,14 +116,14 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
return $this->woodType->isFlammable() ? 300 : 0;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 5;
|
||||
return $this->woodType->isFlammable() ? 5 : 0;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 20;
|
||||
return $this->woodType->isFlammable() ? 20 : 0;
|
||||
}
|
||||
}
|
||||
|
127
src/block/FillableCauldron.php
Normal file
127
src/block/FillableCauldron.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\world\sound\Sound;
|
||||
use function min;
|
||||
|
||||
abstract class FillableCauldron extends Transparent{
|
||||
public const MIN_FILL_LEVEL = 1;
|
||||
public const MAX_FILL_LEVEL = 6;
|
||||
|
||||
private int $fillLevel = self::MIN_FILL_LEVEL;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(3, self::MIN_FILL_LEVEL, self::MAX_FILL_LEVEL, $this->fillLevel);
|
||||
}
|
||||
|
||||
public function getFillLevel() : int{ return $this->fillLevel; }
|
||||
|
||||
/** @return $this */
|
||||
public function setFillLevel(int $fillLevel) : self{
|
||||
if($fillLevel < self::MIN_FILL_LEVEL || $fillLevel > self::MAX_FILL_LEVEL){
|
||||
throw new \InvalidArgumentException("Fill level must be in range " . self::MIN_FILL_LEVEL . " ... " . self::MAX_FILL_LEVEL);
|
||||
}
|
||||
$this->fillLevel = $fillLevel;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
$result = [
|
||||
AxisAlignedBB::one()->trim(Facing::UP, 11 / 16) //bottom of the cauldron
|
||||
];
|
||||
|
||||
foreach(Facing::HORIZONTAL as $f){ //add the frame parts around the bowl
|
||||
$result[] = AxisAlignedBB::one()->trim($f, 14 / 16);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return $facing === Facing::UP ? SupportType::EDGE() : SupportType::NONE();
|
||||
}
|
||||
|
||||
protected function withFillLevel(int $fillLevel) : Block{
|
||||
return $fillLevel === 0 ? VanillaBlocks::CAULDRON() : $this->setFillLevel(min(self::MAX_FILL_LEVEL, $fillLevel));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] &$returnedItems
|
||||
*/
|
||||
protected function addFillLevels(int $amount, Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
|
||||
if($this->fillLevel >= self::MAX_FILL_LEVEL){
|
||||
return;
|
||||
}
|
||||
$this->position->getWorld()->setBlock($this->position, $this->withFillLevel($this->fillLevel + $amount));
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $this->getFillSound());
|
||||
|
||||
$usedItem->pop();
|
||||
$returnedItems[] = $returnedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Item[] &$returnedItems
|
||||
*/
|
||||
protected function removeFillLevels(int $amount, Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
|
||||
if($this->fillLevel < $amount){
|
||||
return;
|
||||
}
|
||||
|
||||
$this->position->getWorld()->setBlock($this->position, $this->withFillLevel($this->fillLevel - $amount));
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), $this->getEmptySound());
|
||||
|
||||
$usedItem->pop();
|
||||
$returnedItems[] = $returnedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sound played when adding levels to the cauldron liquid.
|
||||
*/
|
||||
abstract public function getFillSound() : Sound;
|
||||
|
||||
/**
|
||||
* Returns the sound played when removing levels from the cauldron liquid.
|
||||
*/
|
||||
abstract public function getEmptySound() : Sound;
|
||||
|
||||
/**
|
||||
* @param Item[] &$returnedItems
|
||||
*/
|
||||
protected function mix(Item $usedItem, Item $returnedItem, array &$returnedItems) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, VanillaBlocks::CAULDRON());
|
||||
//TODO: sounds and particles
|
||||
|
||||
$usedItem->pop();
|
||||
$returnedItems[] = $returnedItem;
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaBlocks::CAULDRON()->asItem();
|
||||
}
|
||||
}
|
@ -23,15 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\projectile\Arrow;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockBurnEvent;
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\world\format\Chunk;
|
||||
use pocketmine\world\World;
|
||||
@ -40,21 +34,13 @@ use function max;
|
||||
use function min;
|
||||
use function mt_rand;
|
||||
|
||||
class Fire extends Flowable{
|
||||
class Fire extends BaseFire{
|
||||
public const MAX_AGE = 15;
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(4, 0, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
@ -68,40 +54,16 @@ class Fire extends Flowable{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityInside(Entity $entity) : bool{
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
|
||||
$entity->attack($ev);
|
||||
|
||||
$ev = new EntityCombustByBlockEvent($this, $entity, 8);
|
||||
if($entity instanceof Arrow){
|
||||
$ev->cancel();
|
||||
}
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$entity->setOnFire($ev->getDuration());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
protected function getFireDamage() : int{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if($this->getSide(Facing::DOWN)->isTransparent() && !$this->hasAdjacentFlammableBlocks()){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(SoulFire::canBeSupportedBy($down)){
|
||||
$world->setBlock($this->position, VanillaBlocks::SOUL_FIRE());
|
||||
}elseif($down->isTransparent() && !$this->hasAdjacentFlammableBlocks()){
|
||||
$world->setBlock($this->position, VanillaBlocks::AIR());
|
||||
}else{
|
||||
$world->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40));
|
||||
@ -227,7 +189,7 @@ class Fire extends Flowable{
|
||||
continue;
|
||||
}
|
||||
$block = $world->getBlockAt($targetX, $targetY, $targetZ);
|
||||
if($block->getId() !== BlockLegacyIds::AIR){
|
||||
if($block->getTypeId() !== BlockTypeIds::AIR){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -33,18 +33,6 @@ use pocketmine\world\BlockTransaction;
|
||||
final class FloorBanner extends BaseBanner{
|
||||
use SignLikeRotationTrait;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->rotation = $stateMeta;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->rotation;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::DOWN;
|
||||
}
|
||||
|
@ -23,11 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\data\bedrock\CoralTypeIdMap;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\ItemIds;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -37,49 +35,10 @@ use function atan2;
|
||||
use function rad2deg;
|
||||
|
||||
final class FloorCoralFan extends BaseCoral{
|
||||
|
||||
protected BlockIdentifierFlattened $idInfoFlattened;
|
||||
|
||||
private int $axis = Axis::X;
|
||||
|
||||
public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->idInfoFlattened = $idInfo;
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->dead = $id === $this->idInfoFlattened->getSecondId();
|
||||
$this->axis = ($stateMeta >> 3) === BlockLegacyMetadata::CORAL_FAN_EAST_WEST ? Axis::X : Axis::Z;
|
||||
$coralType = CoralTypeIdMap::getInstance()->fromId($stateMeta & BlockLegacyMetadata::CORAL_FAN_TYPE_MASK);
|
||||
if($coralType === null){
|
||||
throw new InvalidBlockStateException("No such coral type");
|
||||
}
|
||||
$this->coralType = $coralType;
|
||||
}
|
||||
|
||||
public function getId() : int{
|
||||
return $this->dead ? $this->idInfoFlattened->getSecondId() : parent::getId();
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
//TODO: HACK! workaround dead flag being lost when broken / blockpicked (original impl only uses first ID)
|
||||
return ItemFactory::getInstance()->get(
|
||||
$this->dead ? ItemIds::CORAL_FAN_DEAD : ItemIds::CORAL_FAN,
|
||||
$this->writeStateToItemMeta()
|
||||
);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return (($this->axis === Axis::X ? BlockLegacyMetadata::CORAL_FAN_EAST_WEST : BlockLegacyMetadata::CORAL_FAN_NORTH_SOUTH) << 3) |
|
||||
CoralTypeIdMap::getInstance()->toId($this->coralType);
|
||||
}
|
||||
|
||||
protected function writeStateToItemMeta() : int{
|
||||
return CoralTypeIdMap::getInstance()->toId($this->coralType);
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalAxis($this->axis);
|
||||
}
|
||||
|
||||
public function getAxis() : int{ return $this->axis; }
|
||||
@ -108,6 +67,9 @@ final class FloorCoralFan extends BaseCoral{
|
||||
$this->axis = Axis::Z;
|
||||
}
|
||||
}
|
||||
|
||||
$this->dead = !$this->isCoveredWithWater();
|
||||
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -124,4 +86,7 @@ final class FloorCoralFan extends BaseCoral{
|
||||
return $block->getSupportType(Facing::UP)->hasCenterSupport();
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaItems::CORAL_FAN()->setCoralType($this->coralType)->setDead($this->dead);
|
||||
}
|
||||
}
|
||||
|
@ -33,18 +33,6 @@ use pocketmine\world\BlockTransaction;
|
||||
final class FloorSign extends BaseSign{
|
||||
use SignLikeRotationTrait;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->rotation = $stateMeta;
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->rotation;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1111;
|
||||
}
|
||||
|
||||
protected function getSupportingFace() : int{
|
||||
return Facing::DOWN;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class Flower extends Flowable{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if($down->getId() === BlockLegacyIds::GRASS || $down->getId() === BlockLegacyIds::DIRT || $down->getId() === BlockLegacyIds::FARMLAND){
|
||||
if($down->hasTypeTag(BlockTypeTags::DIRT) || $down->hasTypeTag(BlockTypeTags::MUD)){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -41,7 +41,8 @@ class Flower extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->isTransparent()){
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(!$down->hasTypeTag(BlockTypeTags::DIRT) && !$down->hasTypeTag(BlockTypeTags::MUD)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -36,16 +36,7 @@ class FlowerPot extends Flowable{
|
||||
|
||||
protected ?Block $plant = null;
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
//TODO: HACK! this is just to make the client actually render the plant - we purposely don't read the flag back
|
||||
return $this->plant !== null ? BlockLegacyMetadata::FLOWER_POT_FLAG_OCCUPIED : 0;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b1;
|
||||
}
|
||||
|
||||
public function readStateFromWorld() : void{
|
||||
public function readStateFromWorld() : Block{
|
||||
parent::readStateFromWorld();
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
if($tile instanceof TileFlowerPot){
|
||||
@ -53,6 +44,8 @@ class FlowerPot extends Flowable{
|
||||
}else{
|
||||
$this->setPlant(null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function writeStateToWorld() : void{
|
||||
@ -86,14 +79,7 @@ class FlowerPot extends Flowable{
|
||||
}
|
||||
|
||||
private function isValidPlant(Block $block) : bool{
|
||||
return
|
||||
$block instanceof Cactus ||
|
||||
$block instanceof DeadBush ||
|
||||
$block instanceof Flower ||
|
||||
$block instanceof RedMushroom ||
|
||||
$block instanceof Sapling ||
|
||||
($block instanceof TallGrass && $block->getIdInfo()->getVariant() === BlockLegacyMetadata::TALLGRASS_FERN); //TODO: clean up
|
||||
//TODO: bamboo
|
||||
return $block->hasTypeTag(BlockTypeTags::POTTABLE_PLANTS);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,7 +107,7 @@ class FlowerPot extends Flowable{
|
||||
return $block->getSupportType(Facing::UP)->hasCenterSupport();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
$plant = $item->getBlock();
|
||||
if($this->plant !== null){
|
||||
|
53
src/block/Froglight.php
Normal file
53
src/block/Froglight.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FroglightType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
|
||||
final class Froglight extends SimplePillar{
|
||||
|
||||
private FroglightType $froglightType;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->froglightType = FroglightType::OCHRE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
protected function describeType(RuntimeDataDescriber $w) : void{
|
||||
$w->froglightType($this->froglightType);
|
||||
}
|
||||
|
||||
public function getFroglightType() : FroglightType{ return $this->froglightType; }
|
||||
|
||||
/** @return $this */
|
||||
public function setFroglightType(FroglightType $froglightType) : self{
|
||||
$this->froglightType = $froglightType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 15;
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\BlockDataSerializer;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockMeltEvent;
|
||||
use function mt_rand;
|
||||
|
||||
@ -32,16 +32,8 @@ class FrostedIce extends Ice{
|
||||
|
||||
protected int $age = 0;
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->age = BlockDataSerializer::readBoundedInt("age", $stateMeta, 0, self::MAX_AGE);
|
||||
}
|
||||
|
||||
protected function writeStateToMeta() : int{
|
||||
return $this->age;
|
||||
}
|
||||
|
||||
public function getStateBitmask() : int{
|
||||
return 0b11;
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->boundedInt(2, 0, self::MAX_AGE, $this->age);
|
||||
}
|
||||
|
||||
public function getAge() : int{ return $this->age; }
|
||||
|
@ -25,7 +25,9 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Furnace as TileFurnace;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\crafting\FurnaceType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
@ -33,26 +35,24 @@ use function mt_rand;
|
||||
|
||||
class Furnace extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use NormalHorizontalFacingInMetadataTrait {
|
||||
readStateFromData as readFacingStateFromData;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected FurnaceType $furnaceType;
|
||||
|
||||
protected bool $lit = false;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo, FurnaceType $furnaceType){
|
||||
$this->furnaceType = $furnaceType;
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
protected BlockIdentifierFlattened $idInfoFlattened;
|
||||
|
||||
protected bool $lit = false; //this is set based on the blockID
|
||||
|
||||
public function __construct(BlockIdentifierFlattened $idInfo, string $name, BlockBreakInfo $breakInfo){
|
||||
$this->idInfoFlattened = $idInfo;
|
||||
parent::__construct($idInfo, $name, $breakInfo);
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->lit);
|
||||
}
|
||||
|
||||
public function getId() : int{
|
||||
return $this->lit ? $this->idInfoFlattened->getSecondId() : parent::getId();
|
||||
}
|
||||
|
||||
public function readStateFromData(int $id, int $stateMeta) : void{
|
||||
$this->readFacingStateFromData($id, $stateMeta);
|
||||
$this->lit = $id === $this->idInfoFlattened->getSecondId();
|
||||
public function getFurnaceType() : FurnaceType{
|
||||
return $this->furnaceType;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
@ -71,7 +71,7 @@ class Furnace extends Opaque{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player instanceof Player){
|
||||
$furnace = $this->position->getWorld()->getTile($this->position);
|
||||
if($furnace instanceof TileFurnace && $furnace->canOpenWith($item->getCustomName())){
|
||||
|
41
src/block/GildedBlackstone.php
Normal file
41
src/block/GildedBlackstone.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
|
||||
final class GildedBlackstone extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(mt_rand(1, 10) === 1){
|
||||
return [VanillaItems::GOLD_NUGGET()->setCount(mt_rand(2, 5))];
|
||||
}
|
||||
|
||||
return parent::getDropsForCompatibleTool($item);
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{ return true; }
|
||||
}
|
@ -23,10 +23,18 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\NormalHorizontalFacingInMetadataTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
|
||||
class GlazedTerracotta extends Opaque{
|
||||
use ColoredTrait;
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use NormalHorizontalFacingInMetadataTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::BLACK();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
}
|
||||
|
36
src/block/GoldOre.php
Normal file
36
src/block/GoldOre.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
|
||||
final class GoldOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [VanillaItems::RAW_GOLD()];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{ return true; }
|
||||
}
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\DirtType;
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Hoe;
|
||||
@ -72,7 +73,7 @@ class Grass extends Opaque{
|
||||
$b = $world->getBlockAt($x, $y, $z);
|
||||
if(
|
||||
!($b instanceof Dirt) ||
|
||||
$b->isCoarse() ||
|
||||
!$b->getDirtType()->equals(DirtType::NORMAL()) ||
|
||||
$world->getFullLightAt($x, $y + 1, $z) < 4 ||
|
||||
$world->getBlockAt($x, $y + 1, $z)->getLightFilter() >= 2
|
||||
){
|
||||
@ -88,7 +89,7 @@ class Grass extends Opaque{
|
||||
}
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($face !== Facing::UP){
|
||||
return false;
|
||||
}
|
||||
@ -105,7 +106,7 @@ class Grass extends Opaque{
|
||||
$world->setBlock($this->position, $newBlock);
|
||||
|
||||
return true;
|
||||
}elseif($item instanceof Shovel && $this->getSide(Facing::UP)->getId() === BlockLegacyIds::AIR){
|
||||
}elseif($item instanceof Shovel && $this->getSide(Facing::UP)->getTypeId() === BlockTypeIds::AIR){
|
||||
$item->applyDamage(1);
|
||||
$newBlock = VanillaBlocks::GRASS_PATH();
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock));
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user