mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 02:42:58 +00:00
Compare commits
600 Commits
api/3.0.0-
...
1.6.2dev-5
Author | SHA1 | Date | |
---|---|---|---|
2c6205e3f3 | |||
2215543e39 | |||
b310959fd1 | |||
d065e76a41 | |||
f0c1ea7dd7 | |||
6aaef1660a | |||
815c697767 | |||
231617b9d0 | |||
90cb3c010f | |||
2398e2450a | |||
bb9299070d | |||
58bf5d6679 | |||
cb7911ee9c | |||
aa9fd1b4f9 | |||
7483f22e8b | |||
89f5567476 | |||
4df261b75a | |||
41780fd195 | |||
0b83c61494 | |||
1d338bfdf9 | |||
2f614c5dc2 | |||
4d8d57ca5e | |||
62aba15f9e | |||
22d8626e23 | |||
b071ce9c5a | |||
2603f5cc63 | |||
14ea76ecd7 | |||
c81b76cbf6 | |||
517609dc2e | |||
506118e28f | |||
6e8631347d | |||
138d85307b | |||
226175f961 | |||
297cfcf168 | |||
9ea39ea3d7 | |||
b9c4a65307 | |||
23752548fe | |||
120cf56a47 | |||
21f09d5fdb | |||
bde6d7db8d | |||
adc6b03d4c | |||
fd52022065 | |||
ea5bd0348a | |||
c3cf82ab26 | |||
6abef6b22d | |||
9902d29734 | |||
7475aa3a18 | |||
6a717d8050 | |||
37b050f864 | |||
d07b5ba1e1 | |||
697ea55fb7 | |||
8b3fad8a7b | |||
f2402f2122 | |||
b548c4fdbe | |||
a982344b96 | |||
0b2b9126a2 | |||
f4f2323518 | |||
badd669b3d | |||
a5f5502380 | |||
6d5620606e | |||
20f34fba53 | |||
61968cca28 | |||
13187e1749 | |||
7c212d3d53 | |||
9e142655ea | |||
1fec16f167 | |||
4ab286a142 | |||
44dd7c2222 | |||
97911aa9cf | |||
7ff143c793 | |||
cd7724d94a | |||
76e213ae73 | |||
8ce833bf74 | |||
ba27fff853 | |||
80f2519d7d | |||
ebda6ec19b | |||
6553c82320 | |||
1b0ed0f1b8 | |||
3ee8f2b182 | |||
238b3ca4c1 | |||
90edb8ebe7 | |||
55e32424a0 | |||
d6266d19b6 | |||
84c8ac03fb | |||
0f2ca99c67 | |||
a7674c52e6 | |||
a52fa93998 | |||
d1852834de | |||
eb4594348b | |||
5a3ce42f74 | |||
0712979908 | |||
ae715cf2f2 | |||
3a5fc78c53 | |||
50580f4408 | |||
8229410e27 | |||
938af60733 | |||
8a35b9da29 | |||
c32b75fa18 | |||
b8ade18888 | |||
592ce3c9e9 | |||
876659cc73 | |||
604d11a8fd | |||
d2ace6bdd2 | |||
672b7610a9 | |||
456ddd3fb3 | |||
b62597fe63 | |||
9e54980ded | |||
2f3c77c68a | |||
02f42eba48 | |||
9451dd361e | |||
da83b879c0 | |||
d1fd6aef44 | |||
cd02f1e4be | |||
eeedcf7332 | |||
216fc6fe31 | |||
17053389b0 | |||
8475c63426 | |||
f2ff0198cc | |||
c394aea803 | |||
e1d894057c | |||
5b3bed8b06 | |||
bed68a012d | |||
e88053faf4 | |||
e51106e64c | |||
0e24596aed | |||
276fccf4bb | |||
64f2e7587d | |||
bedfca8698 | |||
4a3f01703e | |||
41c6cb6f97 | |||
384a4b3a09 | |||
a7ad26426f | |||
f73d3d086e | |||
41f5cba971 | |||
d8f0dd6db8 | |||
c8ed2406d7 | |||
a4ec2b7f2c | |||
9efd350e78 | |||
be4f48a119 | |||
83f29e5639 | |||
e825ebd8fa | |||
83af4dcd59 | |||
f6c31680f6 | |||
6320a63ca5 | |||
9e02f3c4e3 | |||
2cd05bf5b5 | |||
5b4035253b | |||
77376d3e33 | |||
56e45a031b | |||
21a1e0eb6b | |||
670a9fe44f | |||
6efa4343b1 | |||
dc3f13cd30 | |||
b4c4005009 | |||
eebc52e00b | |||
20aa519f3a | |||
741394dab1 | |||
ea414ea72d | |||
696c67f541 | |||
021dbd65d7 | |||
8510be062c | |||
7b142d4742 | |||
0257432afc | |||
4950157f1d | |||
c4d8c28338 | |||
9a0b3a6e22 | |||
ebb71fc6c5 | |||
ae3a8a5493 | |||
0c798222a4 | |||
e8bd0c3e09 | |||
82fd3b540e | |||
06083d6dc4 | |||
2d8395f70e | |||
6b5c0af161 | |||
c84218c55b | |||
6b7a382625 | |||
54b6a5710e | |||
44f1dedbf8 | |||
23eb8600ab | |||
10ff2948ac | |||
0d0df3390a | |||
e4a5cb6021 | |||
71e354cf1d | |||
7d3fca83f0 | |||
3fdbcee10f | |||
4e9af1ac45 | |||
475066c9f5 | |||
d5f6966ce3 | |||
0ad4a59d5a | |||
5f6dc25c9f | |||
3b7fc21839 | |||
ecba80fd63 | |||
fb59b57bdf | |||
2b4e303f52 | |||
2103c981a9 | |||
3188f1c053 | |||
fdf71841e1 | |||
11fae493a5 | |||
3135fe3c69 | |||
561d8e7a39 | |||
3048a3b39b | |||
63c12440dc | |||
b912b9173c | |||
ca3cf3e067 | |||
8a02dbb15a | |||
f0b4a33e2e | |||
306bf7be5f | |||
0b47324fe3 | |||
17be06a56d | |||
caff686827 | |||
210bdc2436 | |||
acaa0d2740 | |||
ffefcd4473 | |||
8957dbf08e | |||
2d626d1d90 | |||
253db40a11 | |||
8a3b31077e | |||
1f4e6535bb | |||
6ae24c5c19 | |||
036663e0b5 | |||
344500785c | |||
a95d173989 | |||
e72d8cf8f5 | |||
c0e0730923 | |||
b6fe231bc1 | |||
3bd94c9da7 | |||
2e5e016b87 | |||
822c048af0 | |||
6e4b8ba677 | |||
a5a8732800 | |||
21887b283f | |||
3e141afe48 | |||
aa6eef26e9 | |||
87c16dab23 | |||
c1542d853f | |||
8274f5b3cc | |||
e8be8550a0 | |||
b3dada4cb9 | |||
ed5f69f170 | |||
7d777510c5 | |||
6ff92f2adf | |||
f32e880542 | |||
6cacb368ce | |||
6fa59230db | |||
1a7f567a70 | |||
42fb1d1fef | |||
cca9cf2c86 | |||
7c00982fff | |||
3150c50cac | |||
57e7c3d91f | |||
3e8825f826 | |||
ab3b50f062 | |||
dbb92096e4 | |||
24bdf330d5 | |||
b28128f835 | |||
fb5587350d | |||
e6a2b0f270 | |||
bb230c5812 | |||
6de8415c79 | |||
2018ad6376 | |||
b5790d19bf | |||
9390866a13 | |||
c3b8be3f60 | |||
b9355387da | |||
7f99d9019a | |||
8bb0c53797 | |||
46a2e6cbf8 | |||
8fc1501e89 | |||
6a191b5069 | |||
08b8debd78 | |||
2a7b736f18 | |||
c2a7c2c6cd | |||
4d874e7e78 | |||
23866359c9 | |||
3a214b7ce6 | |||
6341d3a0dc | |||
72d1948f30 | |||
a7f5ee2f3e | |||
6b773dc04d | |||
6af87b7b30 | |||
5283975f20 | |||
a5c6c8b973 | |||
caa229a25f | |||
4731bf0a16 | |||
30df0c2418 | |||
e485999218 | |||
650afe2d94 | |||
fa58736360 | |||
c33972aa67 | |||
6bcc8cea8e | |||
f2467d3dbc | |||
be7e97e0bb | |||
767f0dcbf6 | |||
c9fdb66c78 | |||
8a28dfa64d | |||
c6a6571c07 | |||
6d7b76f356 | |||
8cca8e1256 | |||
30c5487f94 | |||
728851594b | |||
2726f2a011 | |||
1a5e3b2ad0 | |||
1493cde07f | |||
6cd4d2c5a2 | |||
6504fdabab | |||
394f420059 | |||
b8a30309bb | |||
1a6517ea4e | |||
9c9095060f | |||
97f6a32557 | |||
409fc282d2 | |||
d474f73665 | |||
c2dfef700f | |||
dca7efa03c | |||
b4a149cce8 | |||
2a67507997 | |||
70bd9afd37 | |||
56dfa7d000 | |||
390df00966 | |||
82fd0e8d47 | |||
6259f42d81 | |||
08d4d7fe0e | |||
ae612b913e | |||
adbc298909 | |||
d92a6240d8 | |||
4a7c40edd5 | |||
1dd8fc008b | |||
ec079b68a6 | |||
ecfcf49984 | |||
f7aad8e2fe | |||
a73c6f1861 | |||
a365c831a8 | |||
c0377fc63a | |||
22d148a59d | |||
a1ce535d02 | |||
993af0fa30 | |||
b83c135c3f | |||
8bf1cc9e48 | |||
c70690a600 | |||
4b4f2af9e3 | |||
9047c2c1ef | |||
89ca2ac2d5 | |||
6a2a74a457 | |||
7ba807fd42 | |||
19410754c6 | |||
8cd31c2dc4 | |||
c09a5ab301 | |||
a0ef15b15e | |||
03826d9cbc | |||
080b35bf53 | |||
e9c46da7f0 | |||
0f79b19fdc | |||
69ae37d191 | |||
86742fcf30 | |||
a4b8dd43e6 | |||
e11f1e94e9 | |||
938452bfe9 | |||
a724395148 | |||
bc10edfdd3 | |||
f7d07ca155 | |||
be7b057fa5 | |||
8637e0224f | |||
8919d4a372 | |||
0cf3914f5d | |||
e9a638d84a | |||
e3b3f60c66 | |||
1bae973502 | |||
e0f8a02bb8 | |||
846be84324 | |||
8ef24423d1 | |||
8fc38c36f9 | |||
eb05f2ecde | |||
478e954b3f | |||
313fdb9e87 | |||
1bf18ba8d2 | |||
5011198a4e | |||
e96fa8b682 | |||
bf3868c078 | |||
3167817e34 | |||
433b8369f5 | |||
0612244b5e | |||
487233a101 | |||
4341fb8347 | |||
789df942b6 | |||
9e99252817 | |||
75cc2d6914 | |||
61b857a81c | |||
2024e9ecdf | |||
4765242397 | |||
3687b149b9 | |||
1aae9e03b6 | |||
c43ab12a9a | |||
cd66f58526 | |||
7870a8672e | |||
eac756470a | |||
a302b4988f | |||
2193adf844 | |||
890f72dbf2 | |||
595e1ab52f | |||
4a7abb7033 | |||
d358e13868 | |||
1f630e57f2 | |||
cc1d1b0f45 | |||
78c09267e5 | |||
c445db421f | |||
e18a3ac933 | |||
75863e2a44 | |||
5aea9220c9 | |||
bd7205dd64 | |||
82a63ed18e | |||
cf07af8b55 | |||
b775e8c88a | |||
51091fe87b | |||
7c14ffbcfa | |||
db93827650 | |||
c2186041d6 | |||
481114281e | |||
51b0673b4b | |||
606b9b687d | |||
45618c7cfe | |||
3f03d9e683 | |||
f0d12a0b30 | |||
9cc27b2719 | |||
87e54d7a3a | |||
29e88d8592 | |||
c6e800cf42 | |||
b7b7bcee4f | |||
6ea0eb47ec | |||
b9a87ed147 | |||
742f593758 | |||
1e9ff44890 | |||
55c4e35407 | |||
e83ffd5afe | |||
54453d0b0a | |||
51d510aa4f | |||
4cd97a7c7a | |||
d586ad03ec | |||
61d354a4ea | |||
6f126ad239 | |||
efea39e0a4 | |||
d4bb078566 | |||
6686bd4442 | |||
2b02fcfe2c | |||
138fb88431 | |||
26577d9d5b | |||
2f4943ac90 | |||
eda7965f86 | |||
4666560731 | |||
b01ad01eff | |||
4ba3a3af3d | |||
5baf59ca56 | |||
902957cb53 | |||
3463bea932 | |||
105917a534 | |||
b83082f224 | |||
840a3883b1 | |||
ad4659365a | |||
8d858e3e6d | |||
22ba017965 | |||
8bb0e8d398 | |||
087a994393 | |||
e4e4ef5f2a | |||
3ac51e1095 | |||
2db6ea6b18 | |||
b6ae92e1a7 | |||
31e2c1d26c | |||
846e3b6f1e | |||
0e525ac1c3 | |||
8382970d56 | |||
db3cd1829c | |||
caced595d2 | |||
86f3b257a7 | |||
1ed5de1d3b | |||
63358a8065 | |||
f6ff03fc31 | |||
0ad16c1919 | |||
38b8f14758 | |||
8779259734 | |||
2f306c3a38 | |||
57379b93ce | |||
954271b90f | |||
645d744e05 | |||
4c764072b2 | |||
3446f68c74 | |||
ca6826898b | |||
76ab3d4288 | |||
b6c1139b27 | |||
af06d78725 | |||
8cc1003956 | |||
92281da514 | |||
5c8297f4a1 | |||
23ed3334c2 | |||
674394c4f5 | |||
4e381ab033 | |||
c5527db424 | |||
aecff7c782 | |||
0207b22110 | |||
a77c1ce13c | |||
afd90adb1c | |||
2e480b5ea1 | |||
d4cc7d13cd | |||
f6c0ba9846 | |||
f3c38700f5 | |||
77b1b565a4 | |||
36c95660e6 | |||
905d3f1610 | |||
0f174f7605 | |||
60f5c7ccef | |||
85c1535c75 | |||
568e2760f1 | |||
fe8cb8cd86 | |||
15b47fcb2f | |||
00e6d6a6b1 | |||
8887a92d4b | |||
a9afad10bc | |||
b41fef0276 | |||
fe3b5bac51 | |||
0a4d62b405 | |||
0935855def | |||
c7c7a40899 | |||
162a08b8cb | |||
b9ad0b99a5 | |||
576702ffa9 | |||
dbb8e8ad0a | |||
4a9acf564c | |||
69f64dd802 | |||
11169b0777 | |||
71af694cc1 | |||
c51c8ae700 | |||
713f3facf9 | |||
df577bddc2 | |||
046f17c9e2 | |||
50f7d04044 | |||
4ccd955647 | |||
c383c7b0dd | |||
adbb53929e | |||
8a7259aa73 | |||
76ceddf266 | |||
11f35d28c2 | |||
c4f461f65d | |||
702c129a97 | |||
56306f6636 | |||
18f1376c65 | |||
49eb0eb050 | |||
13fd8b681e | |||
40f2d7fcdc | |||
c537cea87e | |||
eaef2bd169 | |||
966e4bf8a1 | |||
f889bf9cf5 | |||
6d90f91be0 | |||
0a52e210db | |||
971703a618 | |||
de359a2bce | |||
1266f8f1aa | |||
a22306d418 | |||
b542277eca | |||
edf1fbb6e6 | |||
653b6b55a9 | |||
7f09a2a26e | |||
7aeb3129ac | |||
dc71eb5246 | |||
bf9b8722c9 | |||
4d897b824b | |||
caf4937222 | |||
2f87dfdcb0 | |||
ffcada88f3 | |||
946d7e2bb1 | |||
7a2ed232cc | |||
1be4bd67e4 | |||
fcff6961a8 | |||
db4027cdb2 | |||
e22bb213af | |||
179210aa27 | |||
be631ad6f7 | |||
3f1790bcb8 | |||
a0ba8f0098 | |||
feb538900b | |||
5ce860c2f5 | |||
6c5ca9b256 | |||
17e4f45e97 | |||
6828ce66b6 | |||
b7b7a93e4e | |||
a34573643f | |||
dab73d8950 | |||
5e6a0e7ba0 | |||
c5eccc8e1c | |||
b55929b382 | |||
d7378fe6f4 | |||
66924729ff | |||
f12a6eed29 | |||
a327a74ece | |||
f3ab45e7d5 | |||
cdf6d200ef | |||
894beed59b | |||
022f33b256 | |||
90f1efc667 | |||
f7e959d602 | |||
9c25ec3afd | |||
e47c7ea55f |
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -6,6 +6,7 @@
|
||||
*.properties text eol=lf
|
||||
*.bat text eol=crlf
|
||||
*.cmd text eol=crlf
|
||||
*.ps1 text eol=crlf
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
27
.github/ISSUE_TEMPLATE.md
vendored
27
.github/ISSUE_TEMPLATE.md
vendored
@ -1,5 +1,9 @@
|
||||
### Issue description
|
||||
<!--- use our forum https://forums.pmmp.io for questions -->
|
||||
<!---
|
||||
THIS ISSUE TRACKER IS FOR BUG REPORTING, NOT FOR HELP & SUPPORT. If you need help, use the links below.
|
||||
- http://pmmp.readthedocs.io/en/rtfd/ - Documentation
|
||||
- https://forums.pmmp.io - PMMP Forums
|
||||
-->
|
||||
<!--- Any issues requesting updates to new versions of MCPE will be treated as spam. We do not need issues to tell us that there is a new version available. -->
|
||||
<!---
|
||||
Write a short description about the issue
|
||||
@ -16,15 +20,28 @@ Actual result: What actually happened?
|
||||
|
||||
### OS and versions
|
||||
<!--- use the 'version' command in PocketMine-MP
|
||||
NOTE: LATEST is not a valid version.
|
||||
PocketMine version should include Jenkins build number and/or git commit hash.
|
||||
ALSO NOTE: NO support whatsoever will be provided for forks or spoons of PocketMine. Issues relating to non-official distributions will be closed as spam. Please send such issues to whoever is responsible for the fork or spoon you are using.
|
||||
|
||||
NOTE: LATEST is not a valid version. PocketMine version should include Jenkins build number and/or git commit hash.
|
||||
|
||||
NO support whatsoever will be provided for forks or spoons of PocketMine. Issues relating to non-official distributions will be closed as spam. Please send such issues to whoever is responsible for the fork or spoon you are using.
|
||||
|
||||
Note that 32-bit platforms are no longer supported by PocketMine-MP and issues concerning 32-bit platforms will be closed.
|
||||
-->
|
||||
* PocketMine-MP:
|
||||
* PHP:
|
||||
* Server OS:
|
||||
* Game version: PE/Win10 (delete as appropriate)
|
||||
|
||||
### Plugins
|
||||
- Test on a clean server without plugins: is the issue reproducible without any plugins loaded?
|
||||
|
||||
If the issue is **not** reproducible without plugins:
|
||||
- Have you asked for help on our forums before creating an issue?
|
||||
- Can you provide sample, *minimal* reproducing code for the issue? If so, paste it in the bottom section
|
||||
- Paste your list of plugins here (use the 'plugins' command in PocketMine-MP)
|
||||
|
||||
### Crashdump, backtrace or other files
|
||||
<!--- please use gist or anything else and add links here -->
|
||||
- Do not paste crashdumps into an issue - please use our Crash Archive at https://crash.pmmp.io for submitting crash reports to not spam the issue tracker. Add links to your reports in the Crash Archive here.
|
||||
- Please use gist or anything else to add other files and add links here
|
||||
|
||||
* ...
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -14,3 +14,6 @@
|
||||
[submodule "tests/plugins/PocketMine-DevTools"]
|
||||
path = tests/plugins/PocketMine-DevTools
|
||||
url = https://github.com/pmmp/PocketMine-DevTools.git
|
||||
[submodule "tests/plugins/PocketMine-TesterPlugin"]
|
||||
path = tests/plugins/PocketMine-TesterPlugin
|
||||
url = https://github.com/pmmp/PocketMine-TesterPlugin.git
|
||||
|
@ -18,8 +18,10 @@
|
||||
|
||||
- Information must be provided in the issue body, not in the title. No tags like `[BUG]` are allowed in the title, including `[SOLVED]` for solved issues.
|
||||
|
||||
- Similarly, no generic issue reports. For bugs, it is the issue author's responsibility to provide us an issue that is **trackable, debuggable, reproducible, reported professionally and is an actual bug**. If you do not provide us with a summary or instructions on how to reproduce the issue, it will be treated as spam and will therefore be closed.
|
||||
<br>In simple words, if your issue does not appear to be a bug or a feature request, or if the issue cannot be properly confirmed to be valid, the issue will be closed until further information is provided.
|
||||
- Similarly, no generic issue reports. For bugs, it is the issue author's responsibility to provide us an issue that is **trackable, debuggable, reproducible, reported professionally and is an actual bug**.
|
||||
<br><br>Valid issue reports must include instructions how to reproduce the issue or a crashdump/backtrace (unless the cause of the issue is obvious).
|
||||
<br><br>**If you do not provide us with a summary or instructions on how to reproduce the issue, it will be treated as spam and will therefore be closed.**
|
||||
<br><br>In simple words, if the issue cannot be properly confirmed to be valid or lacks required information, the issue will be closed until further information is provided.
|
||||
|
||||
- To express appreciation, objection, confusion or other supported reactions on pull requests, issues or comments on them, use GitHub [reactions](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) rather than posting an individual comment with an emoji only. This helps keeping the issue/pull request conversation clean and readable.
|
||||
|
||||
|
@ -13,7 +13,7 @@ If you don't find what you're looking for there, [talk to a human](#discussion).
|
||||
- [#pmmp + #pocketmine channel IRC](http://webchat.freenode.net/?channels=pmmp,pocketmine)
|
||||
|
||||
### Plugins
|
||||
There are a very wide range of already-written plugins available which you can use to customise your server. Check out [the old plugin repository](http://plugins.pocketmine.net/) and [Poggit](https://poggit.pmmp.io), or just search GitHub.
|
||||
There are a very wide range of already-written plugins available which you can use to customise your server. Check out [Poggit](https://poggit.pmmp.io), or just search GitHub.
|
||||
|
||||
### For developers
|
||||
* [Latest API documentation](https://jenkins.pmmp.io/job/PocketMine-MP-doc/doxygen/) - Doxygen documentation generated from development
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\event\TranslationContainer;
|
||||
@ -39,76 +41,82 @@ abstract class Achievement{
|
||||
"mineWood" => [
|
||||
"name" => "Getting Wood",
|
||||
"requires" => [ //"openInventory",
|
||||
],
|
||||
]
|
||||
],
|
||||
"buildWorkBench" => [
|
||||
"name" => "Benchmarking",
|
||||
"requires" => [
|
||||
"mineWood",
|
||||
],
|
||||
"mineWood"
|
||||
]
|
||||
],
|
||||
"buildPickaxe" => [
|
||||
"name" => "Time to Mine!",
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
],
|
||||
"buildWorkBench"
|
||||
]
|
||||
],
|
||||
"buildFurnace" => [
|
||||
"name" => "Hot Topic",
|
||||
"requires" => [
|
||||
"buildPickaxe",
|
||||
],
|
||||
"buildPickaxe"
|
||||
]
|
||||
],
|
||||
"acquireIron" => [
|
||||
"name" => "Acquire hardware",
|
||||
"requires" => [
|
||||
"buildFurnace",
|
||||
],
|
||||
"buildFurnace"
|
||||
]
|
||||
],
|
||||
"buildHoe" => [
|
||||
"name" => "Time to Farm!",
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
],
|
||||
"buildWorkBench"
|
||||
]
|
||||
],
|
||||
"makeBread" => [
|
||||
"name" => "Bake Bread",
|
||||
"requires" => [
|
||||
"buildHoe",
|
||||
],
|
||||
"buildHoe"
|
||||
]
|
||||
],
|
||||
"bakeCake" => [
|
||||
"name" => "The Lie",
|
||||
"requires" => [
|
||||
"buildHoe",
|
||||
],
|
||||
"buildHoe"
|
||||
]
|
||||
],
|
||||
"buildBetterPickaxe" => [
|
||||
"name" => "Getting an Upgrade",
|
||||
"requires" => [
|
||||
"buildPickaxe",
|
||||
],
|
||||
"buildPickaxe"
|
||||
]
|
||||
],
|
||||
"buildSword" => [
|
||||
"name" => "Time to Strike!",
|
||||
"requires" => [
|
||||
"buildWorkBench",
|
||||
],
|
||||
"buildWorkBench"
|
||||
]
|
||||
],
|
||||
"diamonds" => [
|
||||
"name" => "DIAMONDS!",
|
||||
"requires" => [
|
||||
"acquireIron",
|
||||
],
|
||||
],
|
||||
"acquireIron"
|
||||
]
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
|
||||
public static function broadcast(Player $player, $achievementId){
|
||||
/**
|
||||
* @param Player $player
|
||||
* @param string $achievementId
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function broadcast(Player $player, string $achievementId) : bool{
|
||||
if(isset(Achievement::$list[$achievementId])){
|
||||
$translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"]]);
|
||||
if(Server::getInstance()->getConfigString("announce-player-achievements", true) === true){
|
||||
$translation = new TranslationContainer("chat.type.achievement", [$player->getDisplayName(), TextFormat::GREEN . Achievement::$list[$achievementId]["name"] . TextFormat::RESET]);
|
||||
if(Server::getInstance()->getConfigBoolean("announce-player-achievements", true) === true){
|
||||
Server::getInstance()->broadcastMessage($translation);
|
||||
}else{
|
||||
$player->sendMessage($translation);
|
||||
@ -120,11 +128,18 @@ abstract class Achievement{
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function add($achievementId, $achievementName, array $requires = []){
|
||||
/**
|
||||
* @param string $achievementId
|
||||
* @param string $achievementName
|
||||
* @param array $requires
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function add(string $achievementId, string $achievementName, array $requires = []) : bool{
|
||||
if(!isset(Achievement::$list[$achievementId])){
|
||||
Achievement::$list[$achievementId] = [
|
||||
"name" => $achievementName,
|
||||
"requires" => $requires,
|
||||
"requires" => $requires
|
||||
];
|
||||
|
||||
return true;
|
||||
|
@ -19,9 +19,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
abstract class Collectable extends \Threaded implements \Collectable{
|
||||
abstract class Collectable extends \Threaded{
|
||||
|
||||
private $isGarbage = false;
|
||||
|
||||
|
@ -19,11 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\plugin\PluginBase;
|
||||
use pocketmine\plugin\PluginLoadOrder;
|
||||
use pocketmine\plugin\PluginManager;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\utils\VersionString;
|
||||
use raklib\RakLib;
|
||||
@ -35,7 +38,9 @@ class CrashDump{
|
||||
private $fp;
|
||||
private $time;
|
||||
private $data = [];
|
||||
private $encodedData = null;
|
||||
/** @var string */
|
||||
private $encodedData = "";
|
||||
/** @var string */
|
||||
private $path;
|
||||
|
||||
public function __construct(Server $server){
|
||||
@ -61,7 +66,7 @@ class CrashDump{
|
||||
$this->encodeData();
|
||||
}
|
||||
|
||||
public function getPath(){
|
||||
public function getPath() : string{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
@ -69,7 +74,7 @@ class CrashDump{
|
||||
return $this->encodedData;
|
||||
}
|
||||
|
||||
public function getData(){
|
||||
public function getData() : array{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
@ -86,7 +91,7 @@ class CrashDump{
|
||||
}
|
||||
|
||||
private function pluginsData(){
|
||||
if(class_exists("pocketmine\\plugin\\PluginManager", false)){
|
||||
if($this->server->getPluginManager() instanceof PluginManager){
|
||||
$this->addLine();
|
||||
$this->addLine("Loaded plugins:");
|
||||
$this->data["plugins"] = [];
|
||||
@ -159,7 +164,7 @@ class CrashDump{
|
||||
E_STRICT => "E_STRICT",
|
||||
E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR",
|
||||
E_DEPRECATED => "E_DEPRECATED",
|
||||
E_USER_DEPRECATED => "E_USER_DEPRECATED",
|
||||
E_USER_DEPRECATED => "E_USER_DEPRECATED"
|
||||
];
|
||||
$error["fullFile"] = $error["file"];
|
||||
$error["file"] = cleanPath($error["file"]);
|
||||
@ -224,6 +229,7 @@ class CrashDump{
|
||||
private function generalData(){
|
||||
$version = new VersionString();
|
||||
$this->data["general"] = [];
|
||||
$this->data["general"]["name"] = $this->server->getName();
|
||||
$this->data["general"]["version"] = $version->get(false);
|
||||
$this->data["general"]["build"] = $version->getBuild();
|
||||
$this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL;
|
||||
@ -235,7 +241,7 @@ class CrashDump{
|
||||
$this->data["general"]["zend"] = zend_version();
|
||||
$this->data["general"]["php_os"] = PHP_OS;
|
||||
$this->data["general"]["os"] = Utils::getOS();
|
||||
$this->addLine("PocketMine-MP version: " . $version->get(false) . " #" . $version->getBuild() . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
||||
$this->addLine($this->server->getName() . " version: " . $version->get(false) . " #" . $version->getBuild() . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
||||
$this->addLine("Git commit: " . GIT_COMMIT);
|
||||
$this->addLine("uname -a: " . php_uname("a"));
|
||||
$this->addLine("PHP Version: " . phpversion());
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\permission\ServerOperator;
|
||||
@ -28,32 +30,32 @@ interface IPlayer extends ServerOperator{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOnline();
|
||||
public function isOnline() : bool;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName();
|
||||
public function getName() : string;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isBanned();
|
||||
public function isBanned() : bool;
|
||||
|
||||
/**
|
||||
* @param bool $banned
|
||||
*/
|
||||
public function setBanned($banned);
|
||||
public function setBanned(bool $banned);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isWhitelisted();
|
||||
public function isWhitelisted() : bool;
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setWhitelisted($value);
|
||||
public function setWhitelisted(bool $value);
|
||||
|
||||
/**
|
||||
* @return Player|null
|
||||
@ -61,18 +63,18 @@ interface IPlayer extends ServerOperator{
|
||||
public function getPlayer();
|
||||
|
||||
/**
|
||||
* @return int|double
|
||||
* @return int|null
|
||||
*/
|
||||
public function getFirstPlayed();
|
||||
|
||||
/**
|
||||
* @return int|double
|
||||
* @return int|null
|
||||
*/
|
||||
public function getLastPlayed();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPlayedBefore();
|
||||
public function hasPlayedBefore() : bool;
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\event\server\LowMemoryEvent;
|
||||
@ -31,27 +33,45 @@ class MemoryManager{
|
||||
/** @var Server */
|
||||
private $server;
|
||||
|
||||
/** @var int */
|
||||
private $memoryLimit;
|
||||
/** @var int */
|
||||
private $globalMemoryLimit;
|
||||
/** @var int */
|
||||
private $checkRate;
|
||||
/** @var int */
|
||||
private $checkTicker = 0;
|
||||
/** @var bool */
|
||||
private $lowMemory = false;
|
||||
|
||||
/** @var bool */
|
||||
private $continuousTrigger = true;
|
||||
/** @var int */
|
||||
private $continuousTriggerRate;
|
||||
/** @var int */
|
||||
private $continuousTriggerCount = 0;
|
||||
/** @var int */
|
||||
private $continuousTriggerTicker = 0;
|
||||
|
||||
/** @var int */
|
||||
private $garbageCollectionPeriod;
|
||||
/** @var int */
|
||||
private $garbageCollectionTicker = 0;
|
||||
/** @var bool */
|
||||
private $garbageCollectionTrigger;
|
||||
/** @var bool */
|
||||
private $garbageCollectionAsync;
|
||||
|
||||
/** @var int */
|
||||
private $chunkRadiusOverride;
|
||||
/** @var bool */
|
||||
private $chunkCollect;
|
||||
/** @var bool */
|
||||
private $chunkTrigger;
|
||||
|
||||
/** @var bool */
|
||||
private $chunkCache;
|
||||
/** @var bool */
|
||||
private $cacheTrigger;
|
||||
|
||||
public function __construct(Server $server){
|
||||
@ -90,7 +110,7 @@ class MemoryManager{
|
||||
$hardLimit = ((int) $this->server->getProperty("memory.main-hard-limit", $defaultMemory));
|
||||
|
||||
if($hardLimit <= 0){
|
||||
ini_set("memory_limit", -1);
|
||||
ini_set("memory_limit", '-1');
|
||||
}else{
|
||||
ini_set("memory_limit", $hardLimit . "M");
|
||||
}
|
||||
@ -114,11 +134,17 @@ class MemoryManager{
|
||||
gc_enable();
|
||||
}
|
||||
|
||||
public function isLowMemory(){
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isLowMemory() : bool{
|
||||
return $this->lowMemory;
|
||||
}
|
||||
|
||||
public function canUseChunkCache(){
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function canUseChunkCache() : bool{
|
||||
return !($this->lowMemory and $this->chunkTrigger);
|
||||
}
|
||||
|
||||
@ -130,10 +156,18 @@ class MemoryManager{
|
||||
* @return int
|
||||
*/
|
||||
public function getViewDistance(int $distance) : int{
|
||||
return $this->lowMemory ? min($this->chunkRadiusOverride, $distance) : $distance;
|
||||
return $this->lowMemory ? (int) min($this->chunkRadiusOverride, $distance) : $distance;
|
||||
}
|
||||
|
||||
public function trigger($memory, $limit, $global = false, $triggerCount = 0){
|
||||
/**
|
||||
* Triggers garbage collection and cache cleanup to try and free memory.
|
||||
*
|
||||
* @param int $memory
|
||||
* @param int $limit
|
||||
* @param bool $global
|
||||
* @param int $triggerCount
|
||||
*/
|
||||
public function trigger(int $memory, int $limit, bool $global = false, int $triggerCount = 0){
|
||||
$this->server->getLogger()->debug(sprintf("[Memory Manager] %sLow memory triggered, limit %gMB, using %gMB",
|
||||
$global ? "Global " : "", round(($limit / 1024) / 1024, 2), round(($memory / 1024) / 1024, 2)));
|
||||
if($this->cacheTrigger){
|
||||
@ -159,6 +193,9 @@ class MemoryManager{
|
||||
$this->server->getLogger()->debug(sprintf("[Memory Manager] Freed %gMB, $cycles cycles", round(($ev->getMemoryFreed() / 1024) / 1024, 2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every tick to update the memory manager state.
|
||||
*/
|
||||
public function check(){
|
||||
Timings::$memoryManagerTimer->startTiming();
|
||||
|
||||
@ -196,7 +233,10 @@ class MemoryManager{
|
||||
Timings::$memoryManagerTimer->stopTiming();
|
||||
}
|
||||
|
||||
public function triggerGarbageCollector(){
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function triggerGarbageCollector() : int{
|
||||
Timings::$garbageCollectorTimer->startTiming();
|
||||
|
||||
if($this->garbageCollectionAsync){
|
||||
@ -213,7 +253,16 @@ class MemoryManager{
|
||||
return $cycles;
|
||||
}
|
||||
|
||||
public function dumpServerMemory($outputFolder, $maxNesting, $maxStringSize){
|
||||
/**
|
||||
* Dumps the server memory into the specified output folder.
|
||||
*
|
||||
* @param string $outputFolder
|
||||
* @param int $maxNesting
|
||||
* @param int $maxStringSize
|
||||
*/
|
||||
public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){
|
||||
$hardLimit = ini_get('memory_limit');
|
||||
ini_set('memory_limit', '-1');
|
||||
gc_disable();
|
||||
|
||||
if(!file_exists($outputFolder)){
|
||||
@ -232,6 +281,32 @@ class MemoryManager{
|
||||
|
||||
$refCounts = [];
|
||||
|
||||
$instanceCounts = [];
|
||||
|
||||
$staticCount = 0;
|
||||
foreach($this->server->getLoader()->getClasses() as $className){
|
||||
$reflection = new \ReflectionClass($className);
|
||||
$staticProperties[$className] = [];
|
||||
foreach($reflection->getProperties() as $property){
|
||||
if(!$property->isStatic() or $property->getDeclaringClass()->getName() !== $className){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!$property->isPublic()){
|
||||
$property->setAccessible(true);
|
||||
}
|
||||
|
||||
$staticCount++;
|
||||
$this->continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
}
|
||||
|
||||
if(count($staticProperties[$className]) === 0){
|
||||
unset($staticProperties[$className]);
|
||||
}
|
||||
}
|
||||
|
||||
echo "[Dump] Wrote $staticCount static properties\n";
|
||||
|
||||
$this->continueDump($this->server, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
|
||||
do{
|
||||
@ -243,6 +318,11 @@ class MemoryManager{
|
||||
$continue = true;
|
||||
|
||||
$className = get_class($object);
|
||||
if(!isset($instanceCounts[$className])){
|
||||
$instanceCounts[$className] = 1;
|
||||
}else{
|
||||
$instanceCounts[$className]++;
|
||||
}
|
||||
|
||||
$objects[$hash] = true;
|
||||
|
||||
@ -273,37 +353,36 @@ class MemoryManager{
|
||||
}
|
||||
|
||||
fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n");
|
||||
|
||||
if(!isset($objects["staticProperties"][$className])){
|
||||
$staticProperties[$className] = [];
|
||||
foreach($reflection->getProperties() as $property){
|
||||
if(!$property->isStatic() or $property->getDeclaringClass()->getName() !== $className){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!$property->isPublic()){
|
||||
$property->setAccessible(true);
|
||||
}
|
||||
$this->continueDump($property->getValue($object), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "[Dump] Wrote " . count($objects) . " objects\n";
|
||||
}while($continue);
|
||||
|
||||
|
||||
fclose($obData);
|
||||
|
||||
file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
file_put_contents($outputFolder . "/serverEntry.js", json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
file_put_contents($outputFolder . "/referenceCounts.js", json_encode($refCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
|
||||
arsort($instanceCounts, SORT_NUMERIC);
|
||||
file_put_contents($outputFolder . "/instanceCounts.js", json_encode($instanceCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
|
||||
echo "[Dump] Finished!\n";
|
||||
|
||||
ini_set('memory_limit', $hardLimit);
|
||||
gc_enable();
|
||||
}
|
||||
|
||||
private function continueDump($from, &$data, &$objects, &$refCounts, $recursion, $maxNesting, $maxStringSize){
|
||||
/**
|
||||
* @param mixed $from
|
||||
* @param mixed &$data
|
||||
* @param object[] &$objects
|
||||
* @param int[] &$refCounts
|
||||
* @param int $recursion
|
||||
* @param int $maxNesting
|
||||
* @param int $maxStringSize
|
||||
*/
|
||||
private function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
|
||||
if($maxNesting <= 0){
|
||||
$data = "(error) NESTING LIMIT REACHED";
|
||||
return;
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\metadata\Metadatable;
|
||||
@ -28,15 +30,18 @@ use pocketmine\plugin\Plugin;
|
||||
|
||||
class OfflinePlayer implements IPlayer, Metadatable{
|
||||
|
||||
/** @var string */
|
||||
private $name;
|
||||
/** @var Server */
|
||||
private $server;
|
||||
/** @var CompoundTag|null */
|
||||
private $namedtag;
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(Server $server, $name){
|
||||
public function __construct(Server $server, string $name){
|
||||
$this->server = $server;
|
||||
$this->name = $name;
|
||||
if(file_exists($this->server->getDataPath() . "players/" . strtolower($this->getName()) . ".dat")){
|
||||
@ -46,11 +51,11 @@ class OfflinePlayer implements IPlayer, Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
public function isOnline(){
|
||||
public function isOnline() : bool{
|
||||
return $this->getPlayer() !== null;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
@ -58,11 +63,11 @@ class OfflinePlayer implements IPlayer, Metadatable{
|
||||
return $this->server;
|
||||
}
|
||||
|
||||
public function isOp(){
|
||||
public function isOp() : bool{
|
||||
return $this->server->isOp(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setOp($value){
|
||||
public function setOp(bool $value){
|
||||
if($value === $this->isOp()){
|
||||
return;
|
||||
}
|
||||
@ -74,11 +79,11 @@ class OfflinePlayer implements IPlayer, Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
public function isBanned(){
|
||||
public function isBanned() : bool{
|
||||
return $this->server->getNameBans()->isBanned(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setBanned($value){
|
||||
public function setBanned(bool $value){
|
||||
if($value === true){
|
||||
$this->server->getNameBans()->addBan($this->getName(), null, null, null);
|
||||
}else{
|
||||
@ -86,11 +91,11 @@ class OfflinePlayer implements IPlayer, Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
public function isWhitelisted(){
|
||||
public function isWhitelisted() : bool{
|
||||
return $this->server->isWhitelisted(strtolower($this->getName()));
|
||||
}
|
||||
|
||||
public function setWhitelisted($value){
|
||||
public function setWhitelisted(bool $value){
|
||||
if($value === true){
|
||||
$this->server->addWhitelist(strtolower($this->getName()));
|
||||
}else{
|
||||
@ -110,24 +115,24 @@ class OfflinePlayer implements IPlayer, Metadatable{
|
||||
return $this->namedtag instanceof CompoundTag ? $this->namedtag["lastPlayed"] : null;
|
||||
}
|
||||
|
||||
public function hasPlayedBefore(){
|
||||
public function hasPlayedBefore() : bool{
|
||||
return $this->namedtag instanceof CompoundTag;
|
||||
}
|
||||
|
||||
public function setMetadata($metadataKey, MetadataValue $metadataValue){
|
||||
$this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $metadataValue);
|
||||
public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){
|
||||
$this->server->getPlayerMetadata()->setMetadata($this, $metadataKey, $newMetadataValue);
|
||||
}
|
||||
|
||||
public function getMetadata($metadataKey){
|
||||
public function getMetadata(string $metadataKey){
|
||||
return $this->server->getPlayerMetadata()->getMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
public function hasMetadata($metadataKey){
|
||||
public function hasMetadata(string $metadataKey) : bool{
|
||||
return $this->server->getPlayerMetadata()->hasMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
public function removeMetadata($metadataKey, Plugin $plugin){
|
||||
$this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $plugin);
|
||||
public function removeMetadata(string $metadataKey, Plugin $owningPlugin){
|
||||
$this->server->getPlayerMetadata()->removeMetadata($this, $metadataKey, $owningPlugin);
|
||||
}
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace {
|
||||
const INT32_MIN = -0x80000000;
|
||||
const INT32_MAX = 0x7fffffff;
|
||||
|
||||
function safe_var_dump(){
|
||||
static $cnt = 0;
|
||||
foreach(func_get_args() as $var){
|
||||
@ -74,7 +79,7 @@ namespace pocketmine {
|
||||
use raklib\RakLib;
|
||||
|
||||
const VERSION = "1.6.2dev";
|
||||
const API_VERSION = "3.0.0-ALPHA5";
|
||||
const API_VERSION = "3.0.0-ALPHA7";
|
||||
const CODENAME = "Unleashed";
|
||||
|
||||
/*
|
||||
@ -84,14 +89,8 @@ namespace pocketmine {
|
||||
* Enjoy it as much as I did writing it. I don't want to do it again.
|
||||
*/
|
||||
|
||||
if(\Phar::running(true) !== ""){
|
||||
@define('pocketmine\PATH', \Phar::running(true) . "/");
|
||||
}else{
|
||||
@define('pocketmine\PATH', \getcwd() . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
if(version_compare("7.0", PHP_VERSION) > 0){
|
||||
echo "[CRITICAL] You must use PHP >= 7.0" . PHP_EOL;
|
||||
if(version_compare("7.0", PHP_VERSION) > 0 or version_compare("7.1", PHP_VERSION) <= 0){
|
||||
echo "[CRITICAL] You must use PHP 7.0" . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
@ -102,6 +101,35 @@ namespace pocketmine {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
error_reporting(-1);
|
||||
|
||||
set_error_handler(function($severity, $message, $file, $line){
|
||||
if(error_reporting() & $severity){
|
||||
throw new \ErrorException($message, 0, $severity, $file, $line);
|
||||
}else{ //stfu operator
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if(!extension_loaded("phar")){
|
||||
echo "[CRITICAL] Unable to find the Phar extension." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use the installer provided on the homepage." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(\Phar::running(true) !== ""){
|
||||
define('pocketmine\PATH', \Phar::running(true) . "/");
|
||||
}else{
|
||||
define('pocketmine\PATH', realpath(getcwd()) . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
$requiredSplVer = "0.0.1";
|
||||
if(!is_file(\pocketmine\PATH . "src/spl/version.php") or version_compare($requiredSplVer, require(\pocketmine\PATH . "src/spl/version.php")) > 0){
|
||||
echo "[CRITICAL] Incompatible PocketMine-SPL submodule version ($requiredSplVer is required)." . PHP_EOL;
|
||||
echo "[CRITICAL] Please update your submodules or use provided builds." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!class_exists("ClassLoader", false)){
|
||||
if(!is_file(\pocketmine\PATH . "src/spl/ClassLoader.php")){
|
||||
echo "[CRITICAL] Unable to find the PocketMine-SPL library." . PHP_EOL;
|
||||
@ -117,24 +145,26 @@ namespace pocketmine {
|
||||
$autoloader->addPath(\pocketmine\PATH . "src" . DIRECTORY_SEPARATOR . "spl");
|
||||
$autoloader->register(true);
|
||||
|
||||
try{
|
||||
if(!class_exists(RakLib::class)){
|
||||
throw new \Exception;
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
if(!class_exists(RakLib::class)){
|
||||
echo "[CRITICAL] Unable to find the RakLib library." . PHP_EOL;
|
||||
echo "[CRITICAL] Please use provided builds or clone the repository recursively." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(version_compare(RakLib::VERSION, "0.8.1") < 0){
|
||||
echo "[CRITICAL] RakLib version 0.8.1 is required, while you have version " . RakLib::VERSION . "." . PHP_EOL;
|
||||
echo "[CRITICAL] Please update your submodules or use provided builds." . PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
set_time_limit(0); //Who set it to 30 seconds?!?!
|
||||
|
||||
error_reporting(-1);
|
||||
ini_set("allow_url_fopen", 1);
|
||||
ini_set("display_errors", 1);
|
||||
ini_set("display_startup_errors", 1);
|
||||
ini_set("allow_url_fopen", '1');
|
||||
ini_set("display_errors", '1');
|
||||
ini_set("display_startup_errors", '1');
|
||||
ini_set("default_charset", "utf-8");
|
||||
|
||||
ini_set("memory_limit", -1);
|
||||
ini_set("memory_limit", '-1');
|
||||
define('pocketmine\START_TIME', microtime(true));
|
||||
|
||||
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-profiler"]);
|
||||
@ -153,7 +183,8 @@ namespace pocketmine {
|
||||
//Logger has a dependency on timezone, so we'll set it to UTC until we can get the actual timezone.
|
||||
date_default_timezone_set("UTC");
|
||||
|
||||
$logger = new MainLogger(\pocketmine\DATA . "server.log", \pocketmine\ANSI);
|
||||
$logger = new MainLogger(\pocketmine\DATA . "server.log");
|
||||
$logger->registerStatic();
|
||||
|
||||
if(!ini_get("date.timezone")){
|
||||
if(($timezone = detect_system_timezone()) and date_default_timezone_set($timezone)){
|
||||
@ -227,7 +258,6 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
return parse_offset($offset);
|
||||
break;
|
||||
case 'linux':
|
||||
// Ubuntu / Debian.
|
||||
if(file_exists('/etc/timezone')){
|
||||
@ -254,7 +284,6 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
return parse_offset($offset);
|
||||
break;
|
||||
case 'mac':
|
||||
if(is_link('/etc/localtime')){
|
||||
$filename = readlink('/etc/localtime');
|
||||
@ -265,17 +294,15 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $offset In the format of +09:00, +02:00, -04:00 etc.
|
||||
*
|
||||
* @return string
|
||||
* @return string|bool
|
||||
*/
|
||||
function parse_offset($offset){
|
||||
//Make signed offsets unsigned for date_parse
|
||||
@ -376,150 +403,163 @@ namespace pocketmine {
|
||||
}else{
|
||||
$args = $trace[$i]["params"];
|
||||
}
|
||||
foreach($args as $name => $value){
|
||||
$params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value)))) . ", ";
|
||||
}
|
||||
|
||||
$params = implode(", ", array_map(function($value){
|
||||
return (is_object($value) ? get_class($value) . " object" : gettype($value) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value))));
|
||||
}, $args));
|
||||
}
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable(substr($params, 0, -2)) . ")";
|
||||
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . ($trace[$i]["line"] ?? "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . Utils::printable($params) . ")";
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
function cleanPath($path){
|
||||
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
|
||||
return str_replace(["\\", ".php", "phar://", str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH)], ["/", "", "", "", ""], $path);
|
||||
}
|
||||
|
||||
$errors = 0;
|
||||
$exitCode = 0;
|
||||
|
||||
if(php_sapi_name() !== "cli"){
|
||||
$logger->critical("You must run PocketMine-MP using the CLI.");
|
||||
++$errors;
|
||||
}
|
||||
do{
|
||||
$errors = 0;
|
||||
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "3.1.5") < 0){
|
||||
$logger->critical("pthreads >= 3.1.5 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
if(PHP_INT_SIZE < 8){
|
||||
$logger->critical("Running PocketMine-MP with 32-bit systems/PHP is no longer supported. Please upgrade to a 64-bit system or use a 64-bit PHP binary.");
|
||||
$exitCode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(extension_loaded("pocketmine")){
|
||||
if(version_compare(phpversion("pocketmine"), "0.0.1") < 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is lower than 0.0.1.");
|
||||
++$errors;
|
||||
}elseif(version_compare(phpversion("pocketmine"), "0.0.4") > 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is higher than 0.0.4.");
|
||||
if(php_sapi_name() !== "cli"){
|
||||
$logger->critical("You must run PocketMine-MP using the CLI.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if(extension_loaded("xdebug")){
|
||||
$logger->warning("
|
||||
|
||||
|
||||
You are running PocketMine with xdebug enabled. This has a major impact on performance.
|
||||
|
||||
");
|
||||
}
|
||||
|
||||
$extensions = [
|
||||
"curl" => "cURL",
|
||||
"json" => "JSON",
|
||||
"mbstring" => "Multibyte String",
|
||||
"yaml" => "YAML",
|
||||
"sockets" => "Sockets",
|
||||
"zip" => "Zip",
|
||||
"zlib" => "Zlib"
|
||||
];
|
||||
|
||||
foreach($extensions as $ext => $name){
|
||||
if(!extension_loaded($ext)){
|
||||
$logger->critical("Unable to find the $name ($ext) extension.");
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "3.1.5") < 0){
|
||||
$logger->critical("pthreads >= 3.1.5 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
$logger->critical("Please use the installer provided on the homepage, or recompile PHP again.");
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
exit(1); //Exit with error
|
||||
}
|
||||
|
||||
if(PHP_INT_SIZE < 8){
|
||||
$logger->warning("Running PocketMine-MP with 32-bit systems/PHP is deprecated. Support for 32-bit may be dropped in the future.");
|
||||
}
|
||||
|
||||
$gitHash = str_repeat("00", 20);
|
||||
if(file_exists(\pocketmine\PATH . ".git/HEAD")){ //Found Git information!
|
||||
$ref = trim(file_get_contents(\pocketmine\PATH . ".git/HEAD"));
|
||||
if(preg_match('/^[0-9a-f]{40}$/i', $ref)){
|
||||
$gitHash = strtolower($ref);
|
||||
}elseif(substr($ref, 0, 5) === "ref: "){
|
||||
$refFile = \pocketmine\PATH . ".git/" . substr($ref, 5);
|
||||
if(is_file($refFile)){
|
||||
$gitHash = strtolower(trim(file_get_contents($refFile)));
|
||||
if(extension_loaded("leveldb")){
|
||||
$leveldb_version = phpversion("leveldb");
|
||||
if(version_compare($leveldb_version, "0.2.0") < 0){
|
||||
$logger->critical("php-leveldb >= 0.2.0 is required, while you have $leveldb_version");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define('pocketmine\GIT_COMMIT', $gitHash);
|
||||
|
||||
|
||||
@define("ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? Binary::BIG_ENDIAN : Binary::LITTLE_ENDIAN));
|
||||
@define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1);
|
||||
@ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors
|
||||
|
||||
|
||||
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
|
||||
$installer = new SetupWizard();
|
||||
if(!$installer->run()){
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
exit(-1);
|
||||
if(extension_loaded("pocketmine")){
|
||||
if(version_compare(phpversion("pocketmine"), "0.0.1") < 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is lower than 0.0.1.");
|
||||
++$errors;
|
||||
}elseif(version_compare(phpversion("pocketmine"), "0.0.4") > 0){
|
||||
$logger->critical("You have the native PocketMine extension, but your version is higher than 0.0.4.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(\Phar::running(true) === ""){
|
||||
$logger->warning("Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||
}
|
||||
|
||||
ThreadManager::init();
|
||||
new Server($autoloader, $logger, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
|
||||
$logger->info("Stopping other threads");
|
||||
|
||||
$killer = new ServerKiller(8);
|
||||
$killer->start();
|
||||
|
||||
$erroredThreads = 0;
|
||||
foreach(ThreadManager::getInstance()->getAll() as $id => $thread){
|
||||
$logger->debug("Stopping " . $thread->getThreadName() . " thread");
|
||||
try{
|
||||
$thread->quit();
|
||||
$logger->debug($thread->getThreadName() . " thread stopped successfully.");
|
||||
}catch(\ThreadException $e){
|
||||
++$erroredThreads;
|
||||
$logger->debug("Could not stop " . $thread->getThreadName() . " thread: " . $e->getMessage());
|
||||
if(extension_loaded("xdebug")){
|
||||
$logger->warning(PHP_EOL . PHP_EOL . PHP_EOL . "\tYou are running PocketMine with xdebug enabled. This has a major impact on performance." . PHP_EOL . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
$extensions = [
|
||||
"bcmath" => "BC Math",
|
||||
"curl" => "cURL",
|
||||
"json" => "JSON",
|
||||
"mbstring" => "Multibyte String",
|
||||
"yaml" => "YAML",
|
||||
"sockets" => "Sockets",
|
||||
"zip" => "Zip",
|
||||
"zlib" => "Zlib"
|
||||
];
|
||||
|
||||
foreach($extensions as $ext => $name){
|
||||
if(!extension_loaded($ext)){
|
||||
$logger->critical("Unable to find the $name ($ext) extension.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
$logger->critical("Please use the installer provided on the homepage, or recompile PHP again.");
|
||||
$exitCode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
$gitHash = str_repeat("00", 20);
|
||||
|
||||
if(\Phar::running(true) === ""){
|
||||
if(Utils::execute("git rev-parse HEAD", $out) === 0){
|
||||
$gitHash = trim($out);
|
||||
if(Utils::execute("git diff --quiet") === 1 or Utils::execute("git diff --cached --quiet") === 1){ //Locally-modified
|
||||
$gitHash .= "-dirty";
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$phar = new \Phar(\Phar::running(false));
|
||||
$meta = $phar->getMetadata();
|
||||
if(isset($meta["git"])){
|
||||
$gitHash = $meta["git"];
|
||||
}
|
||||
}
|
||||
|
||||
define('pocketmine\GIT_COMMIT', $gitHash);
|
||||
|
||||
|
||||
@define("ENDIANNESS", (pack("d", 1) === "\77\360\0\0\0\0\0\0" ? Binary::BIG_ENDIAN : Binary::LITTLE_ENDIAN));
|
||||
@define("INT32_MASK", is_int(0xffffffff) ? 0xffffffff : -1);
|
||||
@ini_set("opcache.mmap_base", bin2hex(random_bytes(8))); //Fix OPCache address errors
|
||||
|
||||
|
||||
if(!file_exists(\pocketmine\DATA . "server.properties") and !isset($opts["no-wizard"])){
|
||||
$installer = new SetupWizard();
|
||||
if(!$installer->run()){
|
||||
$exitCode = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(\Phar::running(true) === ""){
|
||||
$logger->warning("Non-packaged PocketMine-MP installation detected, do not use on production.");
|
||||
}
|
||||
|
||||
ThreadManager::init();
|
||||
new Server($autoloader, $logger, \pocketmine\PATH, \pocketmine\DATA, \pocketmine\PLUGIN_PATH);
|
||||
|
||||
$logger->info("Stopping other threads");
|
||||
|
||||
$killer = new ServerKiller(8);
|
||||
$killer->start();
|
||||
usleep(10000); //Fixes ServerKiller not being able to start on single-core machines
|
||||
|
||||
$erroredThreads = 0;
|
||||
foreach(ThreadManager::getInstance()->getAll() as $id => $thread){
|
||||
$logger->debug("Stopping " . $thread->getThreadName() . " thread");
|
||||
try{
|
||||
$thread->quit();
|
||||
$logger->debug($thread->getThreadName() . " thread stopped successfully.");
|
||||
}catch(\ThreadException $e){
|
||||
++$erroredThreads;
|
||||
$logger->debug("Could not stop " . $thread->getThreadName() . " thread: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if($erroredThreads > 0){
|
||||
if(\pocketmine\DEBUG > 1){
|
||||
echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL;
|
||||
}
|
||||
kill(getmypid());
|
||||
}
|
||||
}while(false);
|
||||
|
||||
$logger->shutdown();
|
||||
$logger->join();
|
||||
|
||||
echo Terminal::$FORMAT_RESET . PHP_EOL;
|
||||
|
||||
if($erroredThreads > 0){
|
||||
if(\pocketmine\DEBUG > 1){
|
||||
echo "Some threads could not be stopped, performing a force-kill" . PHP_EOL . PHP_EOL;
|
||||
}
|
||||
kill(getmypid());
|
||||
}else{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
exit($exitCode);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
/**
|
||||
@ -41,6 +43,13 @@ abstract class Thread extends \Thread{
|
||||
$this->classLoader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the class loader for this thread.
|
||||
*
|
||||
* WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable.
|
||||
* If you do not do this, you will not be able to use new classes that were not loaded when the thread was started
|
||||
* (unless you are using a custom autoloader).
|
||||
*/
|
||||
public function registerClassLoader(){
|
||||
if(!interface_exists("ClassLoader", false)){
|
||||
require(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||
@ -81,7 +90,7 @@ abstract class Thread extends \Thread{
|
||||
ThreadManager::getInstance()->remove($this);
|
||||
}
|
||||
|
||||
public function getThreadName(){
|
||||
public function getThreadName() : string{
|
||||
return (new \ReflectionClass($this))->getShortName();
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
class ThreadManager extends \Volatile{
|
||||
@ -58,7 +60,7 @@ class ThreadManager extends \Volatile{
|
||||
/**
|
||||
* @return Worker[]|Thread[]
|
||||
*/
|
||||
public function getAll(){
|
||||
public function getAll() : array{
|
||||
$array = [];
|
||||
foreach($this as $key => $thread){
|
||||
$array[$key] = $thread;
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
/**
|
||||
@ -42,6 +44,13 @@ abstract class Worker extends \Worker{
|
||||
$this->classLoader = $loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the class loader for this thread.
|
||||
*
|
||||
* WARNING: This method MUST be called from any descendent threads' run() method to make autoloading usable.
|
||||
* If you do not do this, you will not be able to use new classes that were not loaded when the thread was started
|
||||
* (unless you are using a custom autoloader).
|
||||
*/
|
||||
public function registerClassLoader(){
|
||||
if(!interface_exists("ClassLoader", false)){
|
||||
require(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||
@ -86,7 +95,7 @@ abstract class Worker extends \Worker{
|
||||
ThreadManager::getInstance()->remove($this);
|
||||
}
|
||||
|
||||
public function getThreadName(){
|
||||
public function getThreadName() : string{
|
||||
return (new \ReflectionClass($this))->getShortName();
|
||||
}
|
||||
}
|
||||
|
@ -19,17 +19,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class ActivatorRail extends Rail{
|
||||
|
||||
protected $id = self::ACTIVATOR_RAIL;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Activator Rail";
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -32,35 +34,35 @@ class Air extends Transparent{
|
||||
protected $id = self::AIR;
|
||||
protected $meta = 0;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Air";
|
||||
}
|
||||
|
||||
public function canPassThrough(){
|
||||
public function canPassThrough() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeFlowedInto(){
|
||||
public function canBeFlowedInto() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBePlaced(){
|
||||
public function canBePlaced() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -68,11 +70,11 @@ class Air extends Transparent{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\inventory\AnvilInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Anvil extends Fallable{
|
||||
@ -34,27 +38,23 @@ class Anvil extends Fallable{
|
||||
|
||||
protected $id = self::ANVIL;
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 6000;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
self::TYPE_NORMAL => "Anvil",
|
||||
self::TYPE_SLIGHTLY_DAMAGED => "Slightly Damaged Anvil",
|
||||
@ -63,11 +63,11 @@ class Anvil extends Fallable{
|
||||
return $names[$this->meta & 0x0c] ?? "Anvil";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$player->addWindow(new AnvilInventory($this));
|
||||
}
|
||||
@ -75,19 +75,19 @@ class Anvil extends Fallable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$direction = ($player !== null ? $player->getDirection() : 0) & 0x03;
|
||||
$this->meta = ($this->meta & 0x0c) | $direction;
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[$this->id, $this->meta & 0x0c, 1],
|
||||
ItemFactory::get($this->getItemId(), $this->getDamage() & 0x0c, 1)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,32 +19,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Bed as TileBed;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
class Bed extends Transparent{
|
||||
const BITFLAG_OCCUPIED = 0x04;
|
||||
const BITFLAG_HEAD = 0x08;
|
||||
|
||||
protected $id = self::BED_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
protected $itemId = Item::BED;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.2;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Bed Block";
|
||||
}
|
||||
|
||||
@ -59,64 +69,135 @@ class Bed extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function isHeadPart() : bool{
|
||||
return ($this->meta & self::BITFLAG_HEAD) !== 0;
|
||||
}
|
||||
|
||||
$time = $this->getLevel()->getTime() % Level::TIME_FULL;
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isOccupied() : bool{
|
||||
return ($this->meta & self::BITFLAG_OCCUPIED) !== 0;
|
||||
}
|
||||
|
||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||
|
||||
if($player instanceof Player and !$isNight){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.noSleep"));
|
||||
return true;
|
||||
public function setOccupied(bool $occupied = true){
|
||||
if($occupied){
|
||||
$this->meta |= self::BITFLAG_OCCUPIED;
|
||||
}else{
|
||||
$this->meta &= ~self::BITFLAG_OCCUPIED;
|
||||
}
|
||||
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
$blockEast = $this->getSide(5);
|
||||
$blockWest = $this->getSide(4);
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
$b = $this;
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$b = $blockNorth;
|
||||
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$b = $blockSouth;
|
||||
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$b = $blockEast;
|
||||
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$b = $blockWest;
|
||||
}else{
|
||||
if($player instanceof Player){
|
||||
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||
}
|
||||
$this->getLevel()->setBlock($this, $this, false, false);
|
||||
|
||||
if(($other = $this->getOtherHalf()) !== null and !$other->isOccupied()){
|
||||
$other->setOccupied($occupied);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meta
|
||||
* @param bool $isHead
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getOtherHalfSide(int $meta, bool $isHead = false) : int{
|
||||
$rotation = $meta & 0x03;
|
||||
$side = -1;
|
||||
|
||||
switch($rotation){
|
||||
case 0x00: //South
|
||||
$side = Vector3::SIDE_SOUTH;
|
||||
break;
|
||||
case 0x01: //West
|
||||
$side = Vector3::SIDE_WEST;
|
||||
break;
|
||||
case 0x02: //North
|
||||
$side = Vector3::SIDE_NORTH;
|
||||
break;
|
||||
case 0x03: //East
|
||||
$side = Vector3::SIDE_EAST;
|
||||
break;
|
||||
}
|
||||
|
||||
if($isHead){
|
||||
$side = Vector3::getOppositeSide($side);
|
||||
}
|
||||
|
||||
return $side;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Bed|null
|
||||
*/
|
||||
public function getOtherHalf(){
|
||||
$other = $this->getSide(self::getOtherHalfSide($this->meta, $this->isHeadPart()));
|
||||
if($other instanceof Bed and $other->getId() === $this->getId() and $other->isHeadPart() !== $this->isHeadPart() and (($other->getDamage() & 0x03) === ($this->getDamage() & 0x03))){
|
||||
return $other;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
$other = $this->getOtherHalf();
|
||||
if($other === null){
|
||||
$player->sendMessage(TextFormat::GRAY . "This bed is incomplete");
|
||||
|
||||
return true;
|
||||
}elseif($player->distanceSquared($this) > 4 and $player->distanceSquared($other) > 4){
|
||||
//MCPE doesn't have messages for bed too far away
|
||||
return true;
|
||||
}
|
||||
|
||||
$time = $this->getLevel()->getTime() % Level::TIME_FULL;
|
||||
|
||||
$isNight = ($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE);
|
||||
|
||||
if(!$isNight){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.noSleep"));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if($player instanceof Player and $player->sleepOn($b) === false){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.occupied"));
|
||||
$b = ($this->isHeadPart() ? $this : $other);
|
||||
|
||||
if($b->isOccupied()){
|
||||
$player->sendMessage(new TranslationContainer(TextFormat::GRAY . "%tile.bed.occupied"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->sleepOn($b);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->isTransparent() === false){
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
];
|
||||
$d = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$next = $this->getSide($faces[(($d + 3) % 4)]);
|
||||
$downNext = $this->getSide(0);
|
||||
if($next->canBeReplaced() === true and $downNext->isTransparent() === false){
|
||||
$meta = (($d + 3) % 4) & 0x03;
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | 0x08), true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if(!$down->isTransparent()){
|
||||
$meta = (($player instanceof Player ? $player->getDirection() : 0) - 1) & 0x03;
|
||||
$next = $this->getSide(self::getOtherHalfSide($meta));
|
||||
if($next->canBeReplaced() === true and !$next->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->setBlock($blockReplace, BlockFactory::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, BlockFactory::get($this->id, $meta | self::BITFLAG_HEAD), true, true);
|
||||
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::BED),
|
||||
new ByteTag("color", $item->getDamage() & 0x0f),
|
||||
new IntTag("x", $blockReplace->x),
|
||||
new IntTag("y", $blockReplace->y),
|
||||
new IntTag("z", $blockReplace->z)
|
||||
]);
|
||||
|
||||
$nbt2 = clone $nbt;
|
||||
$nbt2["x"] = $next->x;
|
||||
$nbt2["z"] = $next->z;
|
||||
|
||||
Tile::createTile(Tile::BED, $this->getLevel(), $nbt);
|
||||
Tile::createTile(Tile::BED, $this->getLevel(), $nbt2);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -125,42 +206,30 @@ class Bed extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$blockNorth = $this->getSide(2); //Gets the blocks around them
|
||||
$blockSouth = $this->getSide(3);
|
||||
$blockEast = $this->getSide(5);
|
||||
$blockWest = $this->getSide(4);
|
||||
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
if($blockNorth->getId() === $this->id and $blockNorth->meta !== 0x08){ //Checks if the block ID and meta are right
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getId() === $this->id and $blockSouth->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getId() === $this->id and $blockEast->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getId() === $this->id and $blockWest->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
if(($other = $this->getOtherHalf()) !== null){
|
||||
$this->getLevel()->useBreakOn($other, $item, $player, $player !== null); //make sure tiles get removed
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[Item::BED, 0, 1],
|
||||
];
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->isHeadPart()){
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if($tile instanceof TileBed){
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $tile->getColor(), 1)
|
||||
];
|
||||
}else{
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), 14, 1) //Red
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -27,23 +29,23 @@ class Bedrock extends Solid{
|
||||
|
||||
protected $id = self::BEDROCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Bedrock";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 18000000;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -19,31 +19,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
|
||||
class Beetroot extends Crops{
|
||||
|
||||
protected $id = self::BEETROOT_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Beetroot Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = [Item::BEETROOT, 0, 1];
|
||||
$drops[] = [Item::BEETROOT_SEEDS, 0, mt_rand(0, 3)];
|
||||
}else{
|
||||
$drops[] = [Item::BEETROOT_SEEDS, 0, 1];
|
||||
return [
|
||||
ItemFactory::get(Item::BEETROOT, 0, 1),
|
||||
ItemFactory::get(Item::BEETROOT_SEEDS, 0, mt_rand(0, 3))
|
||||
];
|
||||
}
|
||||
|
||||
return $drops;
|
||||
return [
|
||||
ItemFactory::get(Item::BEETROOT_SEEDS, 0, 1)
|
||||
];
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class BirchWoodStairs extends WoodStairs{
|
||||
|
||||
protected $id = self::BIRCH_WOOD_STAIRS;
|
||||
|
||||
public function getName(){
|
||||
return "Birch Wood Stairs";
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* All Block classes are in here
|
||||
*/
|
||||
@ -26,6 +28,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\MovingObjectPosition;
|
||||
@ -39,326 +42,137 @@ use pocketmine\plugin\Plugin;
|
||||
|
||||
class Block extends Position implements BlockIds, Metadatable{
|
||||
|
||||
/** @var \SplFixedArray */
|
||||
public static $list = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $fullList = null;
|
||||
|
||||
/** @var \SplFixedArray */
|
||||
public static $light = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $lightFilter = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $solid = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $hardness = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $transparent = null;
|
||||
/**
|
||||
* Returns a new Block instance with the specified ID, meta and position.
|
||||
*
|
||||
* This function redirects to {@link BlockFactory#get}.
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param Position|null $pos
|
||||
*
|
||||
* @return Block
|
||||
*/
|
||||
public static function get(int $id, int $meta = 0, Position $pos = null) : Block{
|
||||
return BlockFactory::get($id, $meta, $pos);
|
||||
}
|
||||
|
||||
/** @var int */
|
||||
protected $id;
|
||||
/** @var int */
|
||||
protected $meta = 0;
|
||||
/** @var string */
|
||||
protected $fallbackName;
|
||||
/** @var int|null */
|
||||
protected $itemId;
|
||||
|
||||
/** @var AxisAlignedBB */
|
||||
public $boundingBox = null;
|
||||
|
||||
public static function init(){
|
||||
if(self::$list === null){
|
||||
self::$list = new \SplFixedArray(256);
|
||||
self::$fullList = new \SplFixedArray(4096);
|
||||
self::$light = new \SplFixedArray(256);
|
||||
self::$lightFilter = new \SplFixedArray(256);
|
||||
self::$solid = new \SplFixedArray(256);
|
||||
self::$hardness = new \SplFixedArray(256);
|
||||
self::$transparent = new \SplFixedArray(256);
|
||||
self::$list[self::AIR] = Air::class;
|
||||
self::$list[self::STONE] = Stone::class;
|
||||
self::$list[self::GRASS] = Grass::class;
|
||||
self::$list[self::DIRT] = Dirt::class;
|
||||
self::$list[self::COBBLESTONE] = Cobblestone::class;
|
||||
self::$list[self::PLANKS] = Planks::class;
|
||||
self::$list[self::SAPLING] = Sapling::class;
|
||||
self::$list[self::BEDROCK] = Bedrock::class;
|
||||
self::$list[self::WATER] = Water::class;
|
||||
self::$list[self::STILL_WATER] = StillWater::class;
|
||||
self::$list[self::LAVA] = Lava::class;
|
||||
self::$list[self::STILL_LAVA] = StillLava::class;
|
||||
self::$list[self::SAND] = Sand::class;
|
||||
self::$list[self::GRAVEL] = Gravel::class;
|
||||
self::$list[self::GOLD_ORE] = GoldOre::class;
|
||||
self::$list[self::IRON_ORE] = IronOre::class;
|
||||
self::$list[self::COAL_ORE] = CoalOre::class;
|
||||
self::$list[self::WOOD] = Wood::class;
|
||||
self::$list[self::LEAVES] = Leaves::class;
|
||||
self::$list[self::SPONGE] = Sponge::class;
|
||||
self::$list[self::GLASS] = Glass::class;
|
||||
self::$list[self::LAPIS_ORE] = LapisOre::class;
|
||||
self::$list[self::LAPIS_BLOCK] = Lapis::class;
|
||||
self::$list[self::ACTIVATOR_RAIL] = ActivatorRail::class;
|
||||
self::$list[self::COCOA_BLOCK] = CocoaBlock::class;
|
||||
self::$list[self::SANDSTONE] = Sandstone::class;
|
||||
self::$list[self::NOTE_BLOCK] = NoteBlock::class;
|
||||
self::$list[self::BED_BLOCK] = Bed::class;
|
||||
self::$list[self::POWERED_RAIL] = PoweredRail::class;
|
||||
self::$list[self::DETECTOR_RAIL] = DetectorRail::class;
|
||||
self::$list[self::COBWEB] = Cobweb::class;
|
||||
self::$list[self::TALL_GRASS] = TallGrass::class;
|
||||
self::$list[self::DEAD_BUSH] = DeadBush::class;
|
||||
self::$list[self::WOOL] = Wool::class;
|
||||
self::$list[self::DANDELION] = Dandelion::class;
|
||||
self::$list[self::RED_FLOWER] = Flower::class;
|
||||
self::$list[self::BROWN_MUSHROOM] = BrownMushroom::class;
|
||||
self::$list[self::RED_MUSHROOM] = RedMushroom::class;
|
||||
self::$list[self::GOLD_BLOCK] = Gold::class;
|
||||
self::$list[self::IRON_BLOCK] = Iron::class;
|
||||
self::$list[self::DOUBLE_SLAB] = DoubleSlab::class;
|
||||
self::$list[self::SLAB] = Slab::class;
|
||||
self::$list[self::BRICKS_BLOCK] = Bricks::class;
|
||||
self::$list[self::TNT] = TNT::class;
|
||||
self::$list[self::BOOKSHELF] = Bookshelf::class;
|
||||
self::$list[self::MOSS_STONE] = MossStone::class;
|
||||
self::$list[self::OBSIDIAN] = Obsidian::class;
|
||||
self::$list[self::TORCH] = Torch::class;
|
||||
self::$list[self::FIRE] = Fire::class;
|
||||
self::$list[self::MONSTER_SPAWNER] = MonsterSpawner::class;
|
||||
self::$list[self::WOOD_STAIRS] = WoodStairs::class;
|
||||
self::$list[self::CHEST] = Chest::class;
|
||||
|
||||
self::$list[self::DIAMOND_ORE] = DiamondOre::class;
|
||||
self::$list[self::DIAMOND_BLOCK] = Diamond::class;
|
||||
self::$list[self::WORKBENCH] = Workbench::class;
|
||||
self::$list[self::WHEAT_BLOCK] = Wheat::class;
|
||||
self::$list[self::FARMLAND] = Farmland::class;
|
||||
self::$list[self::FURNACE] = Furnace::class;
|
||||
self::$list[self::BURNING_FURNACE] = BurningFurnace::class;
|
||||
self::$list[self::SIGN_POST] = SignPost::class;
|
||||
self::$list[self::WOOD_DOOR_BLOCK] = WoodDoor::class;
|
||||
self::$list[self::LADDER] = Ladder::class;
|
||||
self::$list[self::RAIL] = Rail::class;
|
||||
|
||||
self::$list[self::COBBLESTONE_STAIRS] = CobblestoneStairs::class;
|
||||
self::$list[self::WALL_SIGN] = WallSign::class;
|
||||
self::$list[self::LEVER] = Lever::class;
|
||||
self::$list[self::STONE_PRESSURE_PLATE] = StonePressurePlate::class;
|
||||
self::$list[self::IRON_DOOR_BLOCK] = IronDoor::class;
|
||||
self::$list[self::WOODEN_PRESSURE_PLATE] = WoodenPressurePlate::class;
|
||||
self::$list[self::REDSTONE_ORE] = RedstoneOre::class;
|
||||
self::$list[self::GLOWING_REDSTONE_ORE] = GlowingRedstoneOre::class;
|
||||
|
||||
self::$list[self::REDSTONE_TORCH] = RedstoneTorch::class;
|
||||
self::$list[self::LIT_REDSTONE_TORCH] = LitRedstoneTorch::class;
|
||||
self::$list[self::STONE_BUTTON] = StoneButton::class;
|
||||
self::$list[self::SNOW_LAYER] = SnowLayer::class;
|
||||
self::$list[self::ICE] = Ice::class;
|
||||
self::$list[self::SNOW_BLOCK] = Snow::class;
|
||||
self::$list[self::CACTUS] = Cactus::class;
|
||||
self::$list[self::CLAY_BLOCK] = Clay::class;
|
||||
self::$list[self::SUGARCANE_BLOCK] = Sugarcane::class;
|
||||
|
||||
self::$list[self::FENCE] = Fence::class;
|
||||
self::$list[self::PUMPKIN] = Pumpkin::class;
|
||||
self::$list[self::NETHERRACK] = Netherrack::class;
|
||||
self::$list[self::SOUL_SAND] = SoulSand::class;
|
||||
self::$list[self::GLOWSTONE_BLOCK] = Glowstone::class;
|
||||
|
||||
self::$list[self::LIT_PUMPKIN] = LitPumpkin::class;
|
||||
self::$list[self::CAKE_BLOCK] = Cake::class;
|
||||
|
||||
self::$list[self::TRAPDOOR] = Trapdoor::class;
|
||||
|
||||
self::$list[self::STONE_BRICKS] = StoneBricks::class;
|
||||
|
||||
self::$list[self::IRON_BARS] = IronBars::class;
|
||||
self::$list[self::GLASS_PANE] = GlassPane::class;
|
||||
self::$list[self::MELON_BLOCK] = Melon::class;
|
||||
self::$list[self::PUMPKIN_STEM] = PumpkinStem::class;
|
||||
self::$list[self::MELON_STEM] = MelonStem::class;
|
||||
self::$list[self::VINE] = Vine::class;
|
||||
self::$list[self::FENCE_GATE] = FenceGate::class;
|
||||
self::$list[self::BRICK_STAIRS] = BrickStairs::class;
|
||||
self::$list[self::STONE_BRICK_STAIRS] = StoneBrickStairs::class;
|
||||
|
||||
self::$list[self::MYCELIUM] = Mycelium::class;
|
||||
self::$list[self::WATER_LILY] = WaterLily::class;
|
||||
self::$list[self::NETHER_BRICKS] = NetherBrick::class;
|
||||
self::$list[self::NETHER_BRICK_FENCE] = NetherBrickFence::class;
|
||||
self::$list[self::NETHER_BRICKS_STAIRS] = NetherBrickStairs::class;
|
||||
|
||||
self::$list[self::ENCHANTING_TABLE] = EnchantingTable::class;
|
||||
self::$list[self::BREWING_STAND_BLOCK] = BrewingStand::class;
|
||||
self::$list[self::END_PORTAL_FRAME] = EndPortalFrame::class;
|
||||
self::$list[self::END_STONE] = EndStone::class;
|
||||
self::$list[self::REDSTONE_LAMP] = RedstoneLamp::class;
|
||||
self::$list[self::LIT_REDSTONE_LAMP] = LitRedstoneLamp::class;
|
||||
self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class;
|
||||
self::$list[self::EMERALD_ORE] = EmeraldOre::class;
|
||||
self::$list[self::TRIPWIRE_HOOK] = TripwireHook::class;
|
||||
self::$list[self::TRIPWIRE] = Tripwire::class;
|
||||
self::$list[self::EMERALD_BLOCK] = Emerald::class;
|
||||
self::$list[self::SPRUCE_WOOD_STAIRS] = SpruceWoodStairs::class;
|
||||
self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class;
|
||||
self::$list[self::JUNGLE_WOOD_STAIRS] = JungleWoodStairs::class;
|
||||
self::$list[self::STONE_WALL] = StoneWall::class;
|
||||
self::$list[self::FLOWER_POT_BLOCK] = FlowerPot::class;
|
||||
self::$list[self::CARROT_BLOCK] = Carrot::class;
|
||||
self::$list[self::POTATO_BLOCK] = Potato::class;
|
||||
self::$list[self::WOODEN_BUTTON] = WoodenButton::class;
|
||||
self::$list[self::MOB_HEAD_BLOCK] = MobHead::class;
|
||||
self::$list[self::ANVIL] = Anvil::class;
|
||||
self::$list[self::TRAPPED_CHEST] = TrappedChest::class;
|
||||
self::$list[self::WEIGHTED_PRESSURE_PLATE_LIGHT] = WeightedPressurePlateLight::class;
|
||||
self::$list[self::WEIGHTED_PRESSURE_PLATE_HEAVY] = WeightedPressurePlateHeavy::class;
|
||||
|
||||
self::$list[self::DAYLIGHT_SENSOR] = DaylightSensor::class;
|
||||
self::$list[self::REDSTONE_BLOCK] = Redstone::class;
|
||||
|
||||
self::$list[self::QUARTZ_BLOCK] = Quartz::class;
|
||||
self::$list[self::QUARTZ_STAIRS] = QuartzStairs::class;
|
||||
self::$list[self::DOUBLE_WOOD_SLAB] = DoubleWoodSlab::class;
|
||||
self::$list[self::WOOD_SLAB] = WoodSlab::class;
|
||||
self::$list[self::STAINED_CLAY] = StainedClay::class;
|
||||
|
||||
self::$list[self::LEAVES2] = Leaves2::class;
|
||||
self::$list[self::WOOD2] = Wood2::class;
|
||||
self::$list[self::ACACIA_WOOD_STAIRS] = AcaciaWoodStairs::class;
|
||||
self::$list[self::DARK_OAK_WOOD_STAIRS] = DarkOakWoodStairs::class;
|
||||
self::$list[self::PRISMARINE] = Prismarine::class;
|
||||
self::$list[self::SEA_LANTERN] = SeaLantern::class;
|
||||
self::$list[self::IRON_TRAPDOOR] = IronTrapdoor::class;
|
||||
self::$list[self::HAY_BALE] = HayBale::class;
|
||||
self::$list[self::CARPET] = Carpet::class;
|
||||
self::$list[self::HARDENED_CLAY] = HardenedClay::class;
|
||||
self::$list[self::COAL_BLOCK] = Coal::class;
|
||||
self::$list[self::PACKED_ICE] = PackedIce::class;
|
||||
self::$list[self::DOUBLE_PLANT] = DoublePlant::class;
|
||||
|
||||
self::$list[self::FENCE_GATE_SPRUCE] = FenceGateSpruce::class;
|
||||
self::$list[self::FENCE_GATE_BIRCH] = FenceGateBirch::class;
|
||||
self::$list[self::FENCE_GATE_JUNGLE] = FenceGateJungle::class;
|
||||
self::$list[self::FENCE_GATE_DARK_OAK] = FenceGateDarkOak::class;
|
||||
self::$list[self::FENCE_GATE_ACACIA] = FenceGateAcacia::class;
|
||||
|
||||
self::$list[self::ITEM_FRAME_BLOCK] = ItemFrame::class;
|
||||
|
||||
self::$list[self::GRASS_PATH] = GrassPath::class;
|
||||
|
||||
self::$list[self::PODZOL] = Podzol::class;
|
||||
self::$list[self::BEETROOT_BLOCK] = Beetroot::class;
|
||||
self::$list[self::STONECUTTER] = Stonecutter::class;
|
||||
self::$list[self::GLOWING_OBSIDIAN] = GlowingObsidian::class;
|
||||
|
||||
foreach(self::$list as $id => $class){
|
||||
if($class !== null){
|
||||
/** @var Block $block */
|
||||
$block = new $class();
|
||||
|
||||
for($data = 0; $data < 16; ++$data){
|
||||
self::$fullList[($id << 4) | $data] = new $class($data);
|
||||
}
|
||||
|
||||
self::$solid[$id] = $block->isSolid();
|
||||
self::$transparent[$id] = $block->isTransparent();
|
||||
self::$hardness[$id] = $block->getHardness();
|
||||
self::$light[$id] = $block->getLightLevel();
|
||||
|
||||
if($block->isSolid()){
|
||||
if($block->isTransparent()){
|
||||
if($block instanceof Liquid or $block instanceof Ice){
|
||||
self::$lightFilter[$id] = 2;
|
||||
}else{
|
||||
self::$lightFilter[$id] = 1;
|
||||
}
|
||||
}else{
|
||||
self::$lightFilter[$id] = 15;
|
||||
}
|
||||
}else{
|
||||
self::$lightFilter[$id] = 1;
|
||||
}
|
||||
}else{
|
||||
self::$lightFilter[$id] = 1;
|
||||
for($data = 0; $data < 16; ++$data){
|
||||
self::$fullList[($id << 4) | $data] = new UnknownBlock($id, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param Position $pos
|
||||
*
|
||||
* @return Block
|
||||
* @param int $id The block type's ID, 0-255
|
||||
* @param int $meta Meta value of the block type
|
||||
* @param string $name English name of the block type (TODO: implement translations)
|
||||
* @param int $itemId The item ID of the block type, used for block picking and dropping items.
|
||||
*/
|
||||
public static function get($id, $meta = 0, Position $pos = null){
|
||||
try{
|
||||
$block = self::$list[$id];
|
||||
if($block !== null){
|
||||
$block = new $block($meta);
|
||||
}else{
|
||||
$block = new UnknownBlock($id, $meta);
|
||||
}
|
||||
}catch(\RuntimeException $e){
|
||||
$block = new UnknownBlock($id, $meta);
|
||||
}
|
||||
|
||||
if($pos !== null){
|
||||
$block->x = $pos->x;
|
||||
$block->y = $pos->y;
|
||||
$block->z = $pos->z;
|
||||
$block->level = $pos->level;
|
||||
}
|
||||
|
||||
return $block;
|
||||
public function __construct(int $id, int $meta = 0, string $name = "Unknown", int $itemId = null){
|
||||
$this->id = $id;
|
||||
$this->meta = $meta;
|
||||
$this->fallbackName = $name;
|
||||
$this->itemId = $itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() : string{
|
||||
return $this->fallbackName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getId() : int{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the item form of the block.
|
||||
* Used for drops for blocks (some blocks such as doors have a different item ID).
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getItemId() : int{
|
||||
return $this->itemId ?? $this->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getDamage() : int{
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
*/
|
||||
public function __construct($id, $meta = 0){
|
||||
$this->id = (int) $id;
|
||||
$this->meta = (int) $meta;
|
||||
final public function setDamage(int $meta){
|
||||
if($meta < 0 or $meta > 0xf){
|
||||
throw new \InvalidArgumentException("Block damage values must be 0-15, not $meta");
|
||||
}
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bitmask to use to remove superfluous information from block meta when getting its item form or name.
|
||||
* This defaults to -1 (don't remove any data). Used to remove rotation data and bitflags from block drops.
|
||||
*
|
||||
* If your block should not have any meta value when it's dropped as an item, override this to return 0 in
|
||||
* descendent classes.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getVariantBitmask() : int{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the Block, using block space and block target, and side. Returns if the block has been placed.
|
||||
*
|
||||
* @param Item $item
|
||||
* @param Block $block
|
||||
* @param Block $target
|
||||
* @param int $face
|
||||
* @param float $fx
|
||||
* @param float $fy
|
||||
* @param float $fz
|
||||
* @param Player $player = null
|
||||
* @param Item $item
|
||||
* @param Block $blockReplace
|
||||
* @param Block $blockClicked
|
||||
* @param int $face
|
||||
* @param Vector3 $facePos
|
||||
* @param Player|null $player
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, $this, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the item can be broken with an specific Item
|
||||
* Returns if the block can be broken with an specific Item
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the actions needed so the block is broken with the Item
|
||||
*
|
||||
* @param Item $item
|
||||
* @param Item $item
|
||||
* @param Player|null $player
|
||||
*
|
||||
* @return mixed
|
||||
* @return bool
|
||||
*/
|
||||
public function onBreak(Item $item){
|
||||
return $this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -366,144 +180,158 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
*
|
||||
* @param int $type
|
||||
*
|
||||
* @return int|bool
|
||||
* @return bool|int
|
||||
*/
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do actions when activated by Item. Returns if it has done anything
|
||||
*
|
||||
* @param Item $item
|
||||
* @param Player $player
|
||||
* @param Item $item
|
||||
* @param Player|null $player
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* Returns a base value used to compute block break times.
|
||||
* @return float
|
||||
*/
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @deprecated
|
||||
* @return float
|
||||
*/
|
||||
public function getResistance(){
|
||||
public function getResistance() : float{
|
||||
return $this->getBlastResistance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block's resistance to explosions. Usually 5x hardness.
|
||||
* @return float
|
||||
*/
|
||||
public function getBlastResistance() : float{
|
||||
return $this->getHardness() * 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getFrictionFactor(){
|
||||
public function getFrictionFactor() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int 0-15
|
||||
*/
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isPlaceable
|
||||
* Returns the amount of light this block will filter out when light passes through this block.
|
||||
* This value is used in light spread calculation.
|
||||
*
|
||||
* @return int 0-15
|
||||
*/
|
||||
public function getLightFilter() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block will diffuse sky light passing through it vertically.
|
||||
* Diffusion means that full-strength sky light passing through this block will not be reduced, but will start being filtered below the block.
|
||||
* Examples of this behaviour include leaves and cobwebs.
|
||||
*
|
||||
* Light-diffusing blocks are included by the heightmap.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBePlaced(){
|
||||
public function diffusesSkyLight() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether random block updates will be done on this block.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ticksRandomly() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isPlaceable
|
||||
* @return bool
|
||||
*/
|
||||
public function canBePlaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Block|null $with
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeReplaced(){
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTransparent(){
|
||||
public function isTransparent() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isFlowable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeFlowedInto(){
|
||||
public function canBeFlowedInto() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasEntityCollision() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canPassThrough() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isActivable
|
||||
*
|
||||
* Returns whether entities can climb up this block.
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeActivated(){
|
||||
public function canClimb() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canPassThrough(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(){
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function addVelocityToEntity(Entity $entity, Vector3 $vector){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getDamage(){
|
||||
return $this->meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meta
|
||||
*/
|
||||
final public function setDamage($meta){
|
||||
$this->meta = $meta & 0x0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the block position to a new Position object
|
||||
*
|
||||
@ -522,16 +350,12 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return array
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getDrops(Item $item){
|
||||
if(!isset(self::$list[$this->getId()])){ //Unknown blocks
|
||||
return [];
|
||||
}else{
|
||||
return [
|
||||
[$this->getId(), $this->getDamage(), 1],
|
||||
];
|
||||
}
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $this->getDamage() & $this->getVariantBitmask(), 1)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -541,7 +365,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getBreakTime(Item $item){
|
||||
public function getBreakTime(Item $item) : float{
|
||||
$base = $this->getHardness() * 1.5;
|
||||
if($this->canBeBrokenWith($item)){
|
||||
if($this->getToolType() === Tool::TYPE_SHEARS and $item->isShears()){
|
||||
@ -580,10 +404,18 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return $base;
|
||||
}
|
||||
|
||||
public function canBeBrokenWith(Item $item){
|
||||
public function canBeBrokenWith(Item $item) : bool{
|
||||
return $this->getHardness() !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time in ticks which the block will fuel a furnace for.
|
||||
* @return int
|
||||
*/
|
||||
public function getFuelTime() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Block on the side $side, works like Vector3::side()
|
||||
*
|
||||
@ -597,7 +429,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return $this->getLevel()->getBlock(Vector3::getSide($side, $step));
|
||||
}
|
||||
|
||||
return Block::get(Item::AIR, 0, Position::fromObject(Vector3::getSide($side, $step)));
|
||||
return BlockFactory::get(Block::AIR, 0, Position::fromObject(Vector3::getSide($side, $step)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -614,7 +446,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function collidesWithBB(AxisAlignedBB $bb){
|
||||
public function collidesWithBB(AxisAlignedBB $bb) : bool{
|
||||
$bb2 = $this->getBoundingBox();
|
||||
|
||||
return $bb2 !== null and $bb->intersectsWith($bb2);
|
||||
@ -628,7 +460,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB
|
||||
* @return AxisAlignedBB|null
|
||||
*/
|
||||
public function getBoundingBox(){
|
||||
if($this->boundingBox === null){
|
||||
@ -638,7 +470,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB
|
||||
* @return AxisAlignedBB|null
|
||||
*/
|
||||
protected function recalculateBoundingBox(){
|
||||
return new AxisAlignedBB(
|
||||
@ -655,7 +487,7 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* @param Vector3 $pos1
|
||||
* @param Vector3 $pos2
|
||||
*
|
||||
* @return MovingObjectPosition
|
||||
* @return MovingObjectPosition|null
|
||||
*/
|
||||
public function calculateIntercept(Vector3 $pos1, Vector3 $pos2){
|
||||
$bb = $this->getBoundingBox();
|
||||
@ -739,13 +571,13 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return MovingObjectPosition::fromBlock($this->x, $this->y, $this->z, $f, $vector->add($this->x, $this->y, $this->z));
|
||||
}
|
||||
|
||||
public function setMetadata($metadataKey, MetadataValue $metadataValue){
|
||||
public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->setMetadata($this, $metadataKey, $metadataValue);
|
||||
$this->getLevel()->getBlockMetadata()->setMetadata($this, $metadataKey, $newMetadataValue);
|
||||
}
|
||||
}
|
||||
|
||||
public function getMetadata($metadataKey){
|
||||
public function getMetadata(string $metadataKey){
|
||||
if($this->getLevel() instanceof Level){
|
||||
return $this->getLevel()->getBlockMetadata()->getMetadata($this, $metadataKey);
|
||||
}
|
||||
@ -753,15 +585,17 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function hasMetadata($metadataKey){
|
||||
public function hasMetadata(string $metadataKey) : bool{
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->hasMetadata($this, $metadataKey);
|
||||
return $this->getLevel()->getBlockMetadata()->hasMetadata($this, $metadataKey);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function removeMetadata($metadataKey, Plugin $plugin){
|
||||
public function removeMetadata(string $metadataKey, Plugin $owningPlugin){
|
||||
if($this->getLevel() instanceof Level){
|
||||
$this->getLevel()->getBlockMetadata()->removeMetadata($this, $metadataKey, $plugin);
|
||||
$this->getLevel()->getBlockMetadata()->removeMetadata($this, $metadataKey, $owningPlugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
406
src/pocketmine/block/BlockFactory.php
Normal file
406
src/pocketmine/block/BlockFactory.php
Normal file
@ -0,0 +1,406 @@
|
||||
<?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\level\Position;
|
||||
|
||||
/**
|
||||
* Manages block registration and instance creation
|
||||
*/
|
||||
class BlockFactory{
|
||||
/** @var \SplFixedArray<Block> */
|
||||
private static $list = null;
|
||||
/** @var \SplFixedArray<Block> */
|
||||
private static $fullList = null;
|
||||
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $solid = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $transparent = null;
|
||||
/** @var \SplFixedArray<float> */
|
||||
public static $hardness = null;
|
||||
/** @var \SplFixedArray<int> */
|
||||
public static $light = null;
|
||||
/** @var \SplFixedArray<int> */
|
||||
public static $lightFilter = null;
|
||||
/** @var \SplFixedArray<bool> */
|
||||
public static $diffusesSkyLight = null;
|
||||
/** @var \SplFixedArray<float> */
|
||||
public static $blastResistance = null;
|
||||
|
||||
/**
|
||||
* Initializes the block factory. By default this is called only once on server start, however you may wish to use
|
||||
* this if you need to reset the block factory back to its original defaults for whatever reason.
|
||||
*
|
||||
* @param bool $force
|
||||
*/
|
||||
public static function init(bool $force = false){
|
||||
if(self::$list === null or $force){
|
||||
self::$list = new \SplFixedArray(256);
|
||||
self::$fullList = new \SplFixedArray(4096);
|
||||
|
||||
self::$light = new \SplFixedArray(256);
|
||||
self::$lightFilter = new \SplFixedArray(256);
|
||||
self::$solid = new \SplFixedArray(256);
|
||||
self::$hardness = new \SplFixedArray(256);
|
||||
self::$transparent = new \SplFixedArray(256);
|
||||
self::$diffusesSkyLight = new \SplFixedArray(256);
|
||||
self::$blastResistance = new \SplFixedArray(256);
|
||||
|
||||
self::registerBlock(new Air());
|
||||
self::registerBlock(new Stone());
|
||||
self::registerBlock(new Grass());
|
||||
self::registerBlock(new Dirt());
|
||||
self::registerBlock(new Cobblestone());
|
||||
self::registerBlock(new Planks());
|
||||
self::registerBlock(new Sapling());
|
||||
self::registerBlock(new Bedrock());
|
||||
self::registerBlock(new Water());
|
||||
self::registerBlock(new StillWater());
|
||||
self::registerBlock(new Lava());
|
||||
self::registerBlock(new StillLava());
|
||||
self::registerBlock(new Sand());
|
||||
self::registerBlock(new Gravel());
|
||||
self::registerBlock(new GoldOre());
|
||||
self::registerBlock(new IronOre());
|
||||
self::registerBlock(new CoalOre());
|
||||
self::registerBlock(new Wood());
|
||||
self::registerBlock(new Leaves());
|
||||
self::registerBlock(new Sponge());
|
||||
self::registerBlock(new Glass());
|
||||
self::registerBlock(new LapisOre());
|
||||
self::registerBlock(new Lapis());
|
||||
//TODO: DISPENSER
|
||||
self::registerBlock(new Sandstone());
|
||||
self::registerBlock(new NoteBlock());
|
||||
self::registerBlock(new Bed());
|
||||
self::registerBlock(new PoweredRail());
|
||||
self::registerBlock(new DetectorRail());
|
||||
//TODO: STICKY_PISTON
|
||||
self::registerBlock(new Cobweb());
|
||||
self::registerBlock(new TallGrass());
|
||||
self::registerBlock(new DeadBush());
|
||||
//TODO: PISTON
|
||||
//TODO: PISTONARMCOLLISION
|
||||
self::registerBlock(new Wool());
|
||||
|
||||
self::registerBlock(new Dandelion());
|
||||
self::registerBlock(new Flower());
|
||||
self::registerBlock(new BrownMushroom());
|
||||
self::registerBlock(new RedMushroom());
|
||||
self::registerBlock(new Gold());
|
||||
self::registerBlock(new Iron());
|
||||
self::registerBlock(new DoubleStoneSlab());
|
||||
self::registerBlock(new StoneSlab());
|
||||
self::registerBlock(new Bricks());
|
||||
self::registerBlock(new TNT());
|
||||
self::registerBlock(new Bookshelf());
|
||||
self::registerBlock(new MossyCobblestone());
|
||||
self::registerBlock(new Obsidian());
|
||||
self::registerBlock(new Torch());
|
||||
self::registerBlock(new Fire());
|
||||
self::registerBlock(new MonsterSpawner());
|
||||
self::registerBlock(new WoodenStairs(Block::OAK_STAIRS, 0, "Oak Stairs"));
|
||||
self::registerBlock(new Chest());
|
||||
//TODO: REDSTONE_WIRE
|
||||
self::registerBlock(new DiamondOre());
|
||||
self::registerBlock(new Diamond());
|
||||
self::registerBlock(new CraftingTable());
|
||||
self::registerBlock(new Wheat());
|
||||
self::registerBlock(new Farmland());
|
||||
self::registerBlock(new Furnace());
|
||||
self::registerBlock(new BurningFurnace());
|
||||
self::registerBlock(new SignPost());
|
||||
self::registerBlock(new WoodenDoor(Block::OAK_DOOR_BLOCK, 0, "Oak Door Block", Item::OAK_DOOR));
|
||||
self::registerBlock(new Ladder());
|
||||
self::registerBlock(new Rail());
|
||||
self::registerBlock(new CobblestoneStairs());
|
||||
self::registerBlock(new WallSign());
|
||||
self::registerBlock(new Lever());
|
||||
self::registerBlock(new StonePressurePlate());
|
||||
self::registerBlock(new IronDoor());
|
||||
self::registerBlock(new WoodenPressurePlate());
|
||||
self::registerBlock(new RedstoneOre());
|
||||
self::registerBlock(new GlowingRedstoneOre());
|
||||
self::registerBlock(new RedstoneTorchUnlit());
|
||||
self::registerBlock(new RedstoneTorch());
|
||||
self::registerBlock(new StoneButton());
|
||||
self::registerBlock(new SnowLayer());
|
||||
self::registerBlock(new Ice());
|
||||
self::registerBlock(new Snow());
|
||||
self::registerBlock(new Cactus());
|
||||
self::registerBlock(new Clay());
|
||||
self::registerBlock(new Sugarcane());
|
||||
|
||||
self::registerBlock(new Fence());
|
||||
self::registerBlock(new Pumpkin());
|
||||
self::registerBlock(new Netherrack());
|
||||
self::registerBlock(new SoulSand());
|
||||
self::registerBlock(new Glowstone());
|
||||
//TODO: PORTAL
|
||||
self::registerBlock(new LitPumpkin());
|
||||
self::registerBlock(new Cake());
|
||||
//TODO: REPEATER_BLOCK
|
||||
//TODO: POWERED_REPEATER
|
||||
//TODO: INVISIBLEBEDROCK
|
||||
self::registerBlock(new Trapdoor());
|
||||
//TODO: MONSTER_EGG
|
||||
self::registerBlock(new StoneBricks());
|
||||
//TODO: BROWN_MUSHROOM_BLOCK
|
||||
//TODO: RED_MUSHROOM_BLOCK
|
||||
self::registerBlock(new IronBars());
|
||||
self::registerBlock(new GlassPane());
|
||||
self::registerBlock(new Melon());
|
||||
self::registerBlock(new PumpkinStem());
|
||||
self::registerBlock(new MelonStem());
|
||||
self::registerBlock(new Vine());
|
||||
self::registerBlock(new FenceGate(Block::OAK_FENCE_GATE, 0, "Oak Fence Gate"));
|
||||
self::registerBlock(new BrickStairs());
|
||||
self::registerBlock(new StoneBrickStairs());
|
||||
self::registerBlock(new Mycelium());
|
||||
self::registerBlock(new WaterLily());
|
||||
self::registerBlock(new NetherBrick(Block::NETHER_BRICK_BLOCK, 0, "Nether Bricks"));
|
||||
self::registerBlock(new NetherBrickFence());
|
||||
self::registerBlock(new NetherBrickStairs());
|
||||
self::registerBlock(new NetherWartPlant());
|
||||
self::registerBlock(new EnchantingTable());
|
||||
self::registerBlock(new BrewingStand());
|
||||
//TODO: CAULDRON_BLOCK
|
||||
//TODO: END_PORTAL
|
||||
self::registerBlock(new EndPortalFrame());
|
||||
self::registerBlock(new EndStone());
|
||||
//TODO: DRAGON_EGG
|
||||
self::registerBlock(new RedstoneLamp());
|
||||
self::registerBlock(new LitRedstoneLamp());
|
||||
//TODO: DROPPER
|
||||
self::registerBlock(new ActivatorRail());
|
||||
self::registerBlock(new CocoaBlock());
|
||||
self::registerBlock(new SandstoneStairs());
|
||||
self::registerBlock(new EmeraldOre());
|
||||
//TODO: ENDER_CHEST
|
||||
self::registerBlock(new TripwireHook());
|
||||
self::registerBlock(new Tripwire());
|
||||
self::registerBlock(new Emerald());
|
||||
self::registerBlock(new WoodenStairs(Block::SPRUCE_STAIRS, 0, "Spruce Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::BIRCH_STAIRS, 0, "Birch Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::JUNGLE_STAIRS, 0, "Jungle Stairs"));
|
||||
//TODO: COMMAND_BLOCK
|
||||
//TODO: BEACON
|
||||
self::registerBlock(new CobblestoneWall());
|
||||
self::registerBlock(new FlowerPot());
|
||||
self::registerBlock(new Carrot());
|
||||
self::registerBlock(new Potato());
|
||||
self::registerBlock(new WoodenButton());
|
||||
self::registerBlock(new Skull());
|
||||
self::registerBlock(new Anvil());
|
||||
self::registerBlock(new TrappedChest());
|
||||
self::registerBlock(new WeightedPressurePlateLight());
|
||||
self::registerBlock(new WeightedPressurePlateHeavy());
|
||||
//TODO: COMPARATOR_BLOCK
|
||||
//TODO: POWERED_COMPARATOR
|
||||
self::registerBlock(new DaylightSensor());
|
||||
self::registerBlock(new Redstone());
|
||||
self::registerBlock(new NetherQuartzOre());
|
||||
//TODO: HOPPER_BLOCK
|
||||
self::registerBlock(new Quartz());
|
||||
self::registerBlock(new QuartzStairs());
|
||||
self::registerBlock(new DoubleWoodenSlab());
|
||||
self::registerBlock(new WoodenSlab());
|
||||
self::registerBlock(new StainedClay());
|
||||
self::registerBlock(new StainedGlassPane());
|
||||
self::registerBlock(new Leaves2());
|
||||
self::registerBlock(new Wood2());
|
||||
self::registerBlock(new WoodenStairs(Block::ACACIA_STAIRS, 0, "Acacia Stairs"));
|
||||
self::registerBlock(new WoodenStairs(Block::DARK_OAK_STAIRS, 0, "Dark Oak Stairs"));
|
||||
//TODO: SLIME
|
||||
|
||||
self::registerBlock(new IronTrapdoor());
|
||||
self::registerBlock(new Prismarine());
|
||||
self::registerBlock(new SeaLantern());
|
||||
self::registerBlock(new HayBale());
|
||||
self::registerBlock(new Carpet());
|
||||
self::registerBlock(new HardenedClay());
|
||||
self::registerBlock(new Coal());
|
||||
self::registerBlock(new PackedIce());
|
||||
self::registerBlock(new DoublePlant());
|
||||
|
||||
//TODO: DAYLIGHT_DETECTOR_INVERTED
|
||||
//TODO: RED_SANDSTONE
|
||||
//TODO: RED_SANDSTONE_STAIRS
|
||||
//TODO: DOUBLE_STONE_SLAB2
|
||||
//TODO: STONE_SLAB2
|
||||
self::registerBlock(new FenceGate(Block::SPRUCE_FENCE_GATE, 0, "Spruce Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::BIRCH_FENCE_GATE, 0, "Birch Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::JUNGLE_FENCE_GATE, 0, "Jungle Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::DARK_OAK_FENCE_GATE, 0, "Dark Oak Fence Gate"));
|
||||
self::registerBlock(new FenceGate(Block::ACACIA_FENCE_GATE, 0, "Acacia Fence Gate"));
|
||||
//TODO: REPEATING_COMMAND_BLOCK
|
||||
//TODO: CHAIN_COMMAND_BLOCK
|
||||
|
||||
self::registerBlock(new WoodenDoor(Block::SPRUCE_DOOR_BLOCK, 0, "Spruce Door Block", Item::SPRUCE_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::BIRCH_DOOR_BLOCK, 0, "Birch Door Block", Item::BIRCH_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::JUNGLE_DOOR_BLOCK, 0, "Jungle Door Block", Item::JUNGLE_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::ACACIA_DOOR_BLOCK, 0, "Acacia Door Block", Item::ACACIA_DOOR));
|
||||
self::registerBlock(new WoodenDoor(Block::DARK_OAK_DOOR_BLOCK, 0, "Dark Oak Door Block", Item::DARK_OAK_DOOR));
|
||||
self::registerBlock(new GrassPath());
|
||||
self::registerBlock(new ItemFrame());
|
||||
//TODO: CHORUS_FLOWER
|
||||
//TODO: PURPUR_BLOCK
|
||||
|
||||
//TODO: PURPUR_STAIRS
|
||||
|
||||
//TODO: END_BRICKS
|
||||
//TODO: FROSTED_ICE
|
||||
self::registerBlock(new EndRod());
|
||||
//TODO: END_GATEWAY
|
||||
|
||||
self::registerBlock(new Magma());
|
||||
self::registerBlock(new NetherWartBlock());
|
||||
self::registerBlock(new NetherBrick(Block::RED_NETHER_BRICK, 0, "Red Nether Bricks"));
|
||||
self::registerBlock(new BoneBlock());
|
||||
|
||||
//TODO: SHULKER_BOX
|
||||
self::registerBlock(new GlazedTerracotta(Block::PURPLE_GLAZED_TERRACOTTA, 0, "Purple Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::WHITE_GLAZED_TERRACOTTA, 0, "White Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::ORANGE_GLAZED_TERRACOTTA, 0, "Orange Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::MAGENTA_GLAZED_TERRACOTTA, 0, "Magenta Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::LIGHT_BLUE_GLAZED_TERRACOTTA, 0, "Light Blue Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::YELLOW_GLAZED_TERRACOTTA, 0, "Yellow Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::LIME_GLAZED_TERRACOTTA, 0, "Lime Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::PINK_GLAZED_TERRACOTTA, 0, "Pink Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::GRAY_GLAZED_TERRACOTTA, 0, "Grey Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::SILVER_GLAZED_TERRACOTTA, 0, "Light Grey Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::CYAN_GLAZED_TERRACOTTA, 0, "Cyan Glazed Terracotta"));
|
||||
|
||||
self::registerBlock(new GlazedTerracotta(Block::BLUE_GLAZED_TERRACOTTA, 0, "Blue Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::BROWN_GLAZED_TERRACOTTA, 0, "Brown Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::GREEN_GLAZED_TERRACOTTA, 0, "Green Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::RED_GLAZED_TERRACOTTA, 0, "Red Glazed Terracotta"));
|
||||
self::registerBlock(new GlazedTerracotta(Block::BLACK_GLAZED_TERRACOTTA, 0, "Black Glazed Terracotta"));
|
||||
self::registerBlock(new Concrete());
|
||||
//TODO: CONCRETEPOWDER
|
||||
|
||||
//TODO: CHORUS_PLANT
|
||||
self::registerBlock(new StainedGlass());
|
||||
|
||||
self::registerBlock(new Podzol());
|
||||
self::registerBlock(new Beetroot());
|
||||
self::registerBlock(new Stonecutter());
|
||||
self::registerBlock(new GlowingObsidian());
|
||||
self::registerBlock(new NetherReactor());
|
||||
//TODO: INFO_UPDATE
|
||||
//TODO: INFO_UPDATE2
|
||||
//TODO: MOVINGBLOCK
|
||||
//TODO: OBSERVER
|
||||
|
||||
//TODO: RESERVED6
|
||||
|
||||
foreach(self::$list as $id => $block){
|
||||
if($block === null){
|
||||
self::registerBlock(new UnknownBlock($id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a block type into the index. Plugins may use this method to register new block types or override
|
||||
* existing ones.
|
||||
*
|
||||
* NOTE: If you are registering a new block type, you will need to add it to the creative inventory yourself - it
|
||||
* will not automatically appear there.
|
||||
*
|
||||
* @param Block $block
|
||||
* @param bool $override Whether to override existing registrations
|
||||
*
|
||||
* @throws \RuntimeException if something attempted to override an already-registered block without specifying the
|
||||
* $override parameter.
|
||||
*/
|
||||
public static function registerBlock(Block $block, bool $override = false){
|
||||
$id = $block->getId();
|
||||
|
||||
if(self::$list[$id] !== null and !(self::$list[$id] instanceof UnknownBlock) and !$override){
|
||||
throw new \RuntimeException("Trying to overwrite an already registered block");
|
||||
}
|
||||
|
||||
self::$list[$id] = clone $block;
|
||||
|
||||
for($meta = 0; $meta < 16; ++$meta){
|
||||
$variant = clone $block;
|
||||
$variant->setDamage($meta);
|
||||
self::$fullList[($id << 4) | $meta] = $variant;
|
||||
}
|
||||
|
||||
self::$solid[$id] = $block->isSolid();
|
||||
self::$transparent[$id] = $block->isTransparent();
|
||||
self::$hardness[$id] = $block->getHardness();
|
||||
self::$light[$id] = $block->getLightLevel();
|
||||
self::$lightFilter[$id] = $block->getLightFilter() + 1; //opacity plus 1 standard light filter
|
||||
self::$diffusesSkyLight[$id] = $block->diffusesSkyLight();
|
||||
self::$blastResistance[$id] = $block->getBlastResistance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Block instance with the specified ID, meta and position.
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param Position $pos
|
||||
*
|
||||
* @return Block
|
||||
*/
|
||||
public static function get(int $id, int $meta = 0, Position $pos = null) : Block{
|
||||
if($meta < 0 or $meta > 0xf){
|
||||
throw new \InvalidArgumentException("Block meta value $meta is out of bounds");
|
||||
}
|
||||
|
||||
try{
|
||||
if(self::$fullList !== null){
|
||||
$block = clone self::$fullList[($id << 4) | $meta];
|
||||
}else{
|
||||
$block = new UnknownBlock($id, $meta);
|
||||
}
|
||||
}catch(\RuntimeException $e){
|
||||
throw new \InvalidArgumentException("Block ID $id is out of bounds");
|
||||
}
|
||||
|
||||
if($pos !== null){
|
||||
$block->x = $pos->x;
|
||||
$block->y = $pos->y;
|
||||
$block->z = $pos->z;
|
||||
$block->level = $pos->level;
|
||||
}
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return \SplFixedArray
|
||||
*/
|
||||
public static function getBlockStatesArray() : \SplFixedArray{
|
||||
return self::$fullList;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
interface BlockIds{
|
||||
@ -27,20 +29,20 @@ interface BlockIds{
|
||||
const STONE = 1;
|
||||
const GRASS = 2;
|
||||
const DIRT = 3;
|
||||
const COBBLESTONE = 4, COBBLE = 4;
|
||||
const PLANK = 5, PLANKS = 5, WOODEN_PLANK = 5, WOODEN_PLANKS = 5;
|
||||
const SAPLING = 6, SAPLINGS = 6;
|
||||
const COBBLESTONE = 4;
|
||||
const PLANKS = 5, WOODEN_PLANKS = 5;
|
||||
const SAPLING = 6;
|
||||
const BEDROCK = 7;
|
||||
const WATER = 8;
|
||||
const STILL_WATER = 9;
|
||||
const LAVA = 10;
|
||||
const STILL_LAVA = 11;
|
||||
const FLOWING_WATER = 8;
|
||||
const STILL_WATER = 9, WATER = 9;
|
||||
const FLOWING_LAVA = 10;
|
||||
const LAVA = 11, STILL_LAVA = 11;
|
||||
const SAND = 12;
|
||||
const GRAVEL = 13;
|
||||
const GOLD_ORE = 14;
|
||||
const IRON_ORE = 15;
|
||||
const COAL_ORE = 16;
|
||||
const LOG = 17, WOOD = 17, TRUNK = 17;
|
||||
const LOG = 17, WOOD = 17;
|
||||
const LEAVES = 18;
|
||||
const SPONGE = 19;
|
||||
const GLASS = 20;
|
||||
@ -48,35 +50,35 @@ interface BlockIds{
|
||||
const LAPIS_BLOCK = 22;
|
||||
const DISPENSER = 23;
|
||||
const SANDSTONE = 24;
|
||||
const NOTE_BLOCK = 25, NOTEBLOCK = 25;
|
||||
const NOTEBLOCK = 25, NOTE_BLOCK = 25;
|
||||
const BED_BLOCK = 26;
|
||||
const POWERED_RAIL = 27;
|
||||
const GOLDEN_RAIL = 27, POWERED_RAIL = 27;
|
||||
const DETECTOR_RAIL = 28;
|
||||
const STICKY_PISTON = 29;
|
||||
const COBWEB = 30;
|
||||
const TALL_GRASS = 31;
|
||||
const BUSH = 32, DEAD_BUSH = 32;
|
||||
const COBWEB = 30, WEB = 30;
|
||||
const TALLGRASS = 31, TALL_GRASS = 31;
|
||||
const DEADBUSH = 32, DEAD_BUSH = 32;
|
||||
const PISTON = 33;
|
||||
const PISTON_HEAD = 34;
|
||||
const PISTONARMCOLLISION = 34, PISTON_ARM_COLLISION = 34;
|
||||
const WOOL = 35;
|
||||
|
||||
const DANDELION = 37;
|
||||
const POPPY = 38, ROSE = 38, RED_FLOWER = 38;
|
||||
const DANDELION = 37, YELLOW_FLOWER = 37;
|
||||
const POPPY = 38, RED_FLOWER = 38;
|
||||
const BROWN_MUSHROOM = 39;
|
||||
const RED_MUSHROOM = 40;
|
||||
const GOLD_BLOCK = 41;
|
||||
const IRON_BLOCK = 42;
|
||||
const DOUBLE_SLAB = 43, DOUBLE_SLABS = 43;
|
||||
const SLAB = 44, SLABS = 44, STONE_SLAB = 44;
|
||||
const BRICKS = 45, BRICKS_BLOCK = 45;
|
||||
const DOUBLE_STONE_SLAB = 43;
|
||||
const STONE_SLAB = 44;
|
||||
const BRICK_BLOCK = 45;
|
||||
const TNT = 46;
|
||||
const BOOKSHELF = 47;
|
||||
const MOSS_STONE = 48, MOSSY_STONE = 48;
|
||||
const MOSSY_COBBLESTONE = 48, MOSS_STONE = 48;
|
||||
const OBSIDIAN = 49;
|
||||
const TORCH = 50;
|
||||
const FIRE = 51;
|
||||
const MONSTER_SPAWNER = 52;
|
||||
const WOOD_STAIRS = 53, WOODEN_STAIRS = 53, OAK_WOOD_STAIRS = 53, OAK_WOODEN_STAIRS = 53;
|
||||
const MOB_SPAWNER = 52, MONSTER_SPAWNER = 52;
|
||||
const OAK_STAIRS = 53, WOODEN_STAIRS = 53;
|
||||
const CHEST = 54;
|
||||
const REDSTONE_WIRE = 55;
|
||||
const DIAMOND_ORE = 56;
|
||||
@ -86,11 +88,11 @@ interface BlockIds{
|
||||
const FARMLAND = 60;
|
||||
const FURNACE = 61;
|
||||
const BURNING_FURNACE = 62, LIT_FURNACE = 62;
|
||||
const SIGN_POST = 63;
|
||||
const DOOR_BLOCK = 64, WOODEN_DOOR_BLOCK = 64, WOOD_DOOR_BLOCK = 64;
|
||||
const SIGN_POST = 63, STANDING_SIGN = 63;
|
||||
const OAK_DOOR_BLOCK = 64, WOODEN_DOOR_BLOCK = 64;
|
||||
const LADDER = 65;
|
||||
const RAIL = 66;
|
||||
const COBBLESTONE_STAIRS = 67, COBBLE_STAIRS = 67;
|
||||
const COBBLESTONE_STAIRS = 67, STONE_STAIRS = 67;
|
||||
const WALL_SIGN = 68;
|
||||
const LEVER = 69;
|
||||
const STONE_PRESSURE_PLATE = 70;
|
||||
@ -99,117 +101,119 @@ interface BlockIds{
|
||||
const REDSTONE_ORE = 73;
|
||||
const GLOWING_REDSTONE_ORE = 74, LIT_REDSTONE_ORE = 74;
|
||||
const UNLIT_REDSTONE_TORCH = 75;
|
||||
const REDSTONE_TORCH = 76, LIT_REDSTONE_TORCH = 76;
|
||||
const LIT_REDSTONE_TORCH = 76, REDSTONE_TORCH = 76;
|
||||
const STONE_BUTTON = 77;
|
||||
const SNOW = 78, SNOW_LAYER = 78;
|
||||
const SNOW_LAYER = 78;
|
||||
const ICE = 79;
|
||||
const SNOW_BLOCK = 80;
|
||||
const SNOW = 80, SNOW_BLOCK = 80;
|
||||
const CACTUS = 81;
|
||||
const CLAY_BLOCK = 82;
|
||||
const REEDS = 83, SUGARCANE_BLOCK = 83;
|
||||
const REEDS_BLOCK = 83, SUGARCANE_BLOCK = 83;
|
||||
|
||||
const FENCE = 85;
|
||||
const PUMPKIN = 86;
|
||||
const NETHERRACK = 87;
|
||||
const SOUL_SAND = 88;
|
||||
const GLOWSTONE = 89, GLOWSTONE_BLOCK = 89;
|
||||
const PORTAL_BLOCK = 90, PORTAL = 90;
|
||||
const GLOWSTONE = 89;
|
||||
const PORTAL = 90;
|
||||
const JACK_O_LANTERN = 91, LIT_PUMPKIN = 91;
|
||||
const CAKE_BLOCK = 92;
|
||||
const REPEATER_BLOCK = 93, UNPOWERED_REPEATER_BLOCK = 93;
|
||||
const POWERED_REPEATER_BLOCK = 94;
|
||||
const INVISIBLE_BEDROCK = 95;
|
||||
const REPEATER_BLOCK = 93, UNPOWERED_REPEATER = 93;
|
||||
const POWERED_REPEATER = 94;
|
||||
const INVISIBLEBEDROCK = 95, INVISIBLE_BEDROCK = 95;
|
||||
const TRAPDOOR = 96, WOODEN_TRAPDOOR = 96;
|
||||
const MONSTER_EGG_BLOCK = 97;
|
||||
const STONE_BRICKS = 98, STONE_BRICK = 98;
|
||||
const MONSTER_EGG = 97;
|
||||
const STONEBRICK = 98, STONE_BRICK = 98, STONE_BRICKS = 98;
|
||||
const BROWN_MUSHROOM_BLOCK = 99;
|
||||
const RED_MUSHROOM_BLOCK = 100;
|
||||
const IRON_BARS = 101, IRON_BAR = 101;
|
||||
const GLASS_PANE = 102, GLASS_PANEL = 102;
|
||||
const IRON_BARS = 101;
|
||||
const GLASS_PANE = 102;
|
||||
const MELON_BLOCK = 103;
|
||||
const PUMPKIN_STEM = 104;
|
||||
const MELON_STEM = 105;
|
||||
const VINES = 106, VINE = 106;
|
||||
const VINE = 106, VINES = 106;
|
||||
const FENCE_GATE = 107, OAK_FENCE_GATE = 107;
|
||||
const BRICK_STAIRS = 108;
|
||||
const STONE_BRICK_STAIRS = 109;
|
||||
const MYCELIUM = 110;
|
||||
const LILY_PAD = 111, WATER_LILY = 111;
|
||||
const NETHER_BRICKS = 112, NETHER_BRICK_BLOCK = 112;
|
||||
const LILY_PAD = 111, WATERLILY = 111, WATER_LILY = 111;
|
||||
const NETHER_BRICK_BLOCK = 112;
|
||||
const NETHER_BRICK_FENCE = 113;
|
||||
const NETHER_BRICK_STAIRS = 114, NETHER_BRICKS_STAIRS = 114;
|
||||
const NETHER_WART_BLOCK = 115;
|
||||
const ENCHANTING_TABLE = 116, ENCHANT_TABLE = 116, ENCHANTMENT_TABLE = 116;
|
||||
const NETHER_BRICK_STAIRS = 114;
|
||||
const NETHER_WART_PLANT = 115;
|
||||
const ENCHANTING_TABLE = 116, ENCHANTMENT_TABLE = 116;
|
||||
const BREWING_STAND_BLOCK = 117;
|
||||
const CAULDRON_BLOCK = 118;
|
||||
|
||||
const END_PORTAL_FRAME = 120, END_PORTAL = 120;
|
||||
const END_PORTAL = 119;
|
||||
const END_PORTAL_FRAME = 120;
|
||||
const END_STONE = 121;
|
||||
|
||||
const REDSTONE_LAMP = 123, INACTIVE_REDSTONE_LAMP = 123;
|
||||
const LIT_REDSTONE_LAMP = 124, ACTIVE_REDSTONE_LAMP = 124;
|
||||
const DRAGON_EGG = 122;
|
||||
const REDSTONE_LAMP = 123;
|
||||
const LIT_REDSTONE_LAMP = 124;
|
||||
const DROPPER = 125;
|
||||
const ACTIVATOR_RAIL = 126;
|
||||
const COCOA_BLOCK = 127, COCOA_PODS = 127;
|
||||
const COCOA = 127, COCOA_BLOCK = 127;
|
||||
const SANDSTONE_STAIRS = 128;
|
||||
const EMERALD_ORE = 129;
|
||||
|
||||
const ENDER_CHEST = 130;
|
||||
const TRIPWIRE_HOOK = 131;
|
||||
const TRIPWIRE = 132;
|
||||
const TRIPWIRE = 132, TRIP_WIRE = 132;
|
||||
const EMERALD_BLOCK = 133;
|
||||
const SPRUCE_WOOD_STAIRS = 134, SPRUCE_WOODEN_STAIRS = 134;
|
||||
const BIRCH_WOOD_STAIRS = 135, BIRCH_WOODEN_STAIRS = 135;
|
||||
const JUNGLE_WOOD_STAIRS = 136, JUNGLE_WOODEN_STAIRS = 136;
|
||||
|
||||
const SPRUCE_STAIRS = 134;
|
||||
const BIRCH_STAIRS = 135;
|
||||
const JUNGLE_STAIRS = 136;
|
||||
const COMMAND_BLOCK = 137;
|
||||
const BEACON = 138;
|
||||
const COBBLESTONE_WALL = 139, COBBLE_WALL = 139, STONE_WALL = 139;
|
||||
const COBBLESTONE_WALL = 139, STONE_WALL = 139;
|
||||
const FLOWER_POT_BLOCK = 140;
|
||||
const CARROT_BLOCK = 141;
|
||||
const POTATO_BLOCK = 142;
|
||||
const CARROTS = 141, CARROT_BLOCK = 141;
|
||||
const POTATOES = 142, POTATO_BLOCK = 142;
|
||||
const WOODEN_BUTTON = 143;
|
||||
const MOB_HEAD_BLOCK = 144, SKULL_BLOCK = 144;
|
||||
const ANVIL = 145;
|
||||
const TRAPPED_CHEST = 146;
|
||||
const WEIGHTED_PRESSURE_PLATE_LIGHT = 147, LIGHT_WEIGHTED_PRESSURE_PLATE = 147, GOLD_PRESSURE_PLATE = 147;
|
||||
const WEIGHTED_PRESSURE_PLATE_HEAVY = 148, HEAVY_WEIGHTED_PRESSURE_PLATE = 148, IRON_PRESSURE_PLATE = 148;
|
||||
const COMPARATOR_BLOCK = 149, UNPOWERED_COMPARATOR_BLOCK = 149;
|
||||
const POWERED_COMPARATOR_BLOCK = 150;
|
||||
const DAYLIGHT_SENSOR = 151;
|
||||
const LIGHT_WEIGHTED_PRESSURE_PLATE = 147;
|
||||
const HEAVY_WEIGHTED_PRESSURE_PLATE = 148;
|
||||
const COMPARATOR_BLOCK = 149, UNPOWERED_COMPARATOR = 149;
|
||||
const POWERED_COMPARATOR = 150;
|
||||
const DAYLIGHT_DETECTOR = 151, DAYLIGHT_SENSOR = 151;
|
||||
const REDSTONE_BLOCK = 152;
|
||||
const NETHER_QUARTZ_ORE = 153;
|
||||
const NETHER_QUARTZ_ORE = 153, QUARTZ_ORE = 153;
|
||||
const HOPPER_BLOCK = 154;
|
||||
const QUARTZ_BLOCK = 155;
|
||||
const QUARTZ_STAIRS = 156;
|
||||
const DOUBLE_WOOD_SLAB = 157, DOUBLE_WOODEN_SLAB = 157, DOUBLE_WOOD_SLABS = 157, DOUBLE_WOODEN_SLABS = 157;
|
||||
const WOOD_SLAB = 158, WOODEN_SLAB = 158, WOOD_SLABS = 158, WOODEN_SLABS = 158;
|
||||
const STAINED_CLAY = 159, STAINED_HARDENED_CLAY = 159;
|
||||
|
||||
const DOUBLE_WOODEN_SLAB = 157;
|
||||
const WOODEN_SLAB = 158;
|
||||
const STAINED_CLAY = 159, STAINED_HARDENED_CLAY = 159, TERRACOTTA = 159;
|
||||
const STAINED_GLASS_PANE = 160;
|
||||
const LEAVES2 = 161;
|
||||
const WOOD2 = 162, TRUNK2 = 162, LOG2 = 162;
|
||||
const ACACIA_WOOD_STAIRS = 163, ACACIA_WOODEN_STAIRS = 163;
|
||||
const DARK_OAK_WOOD_STAIRS = 164, DARK_OAK_WOODEN_STAIRS = 164;
|
||||
const SLIME_BLOCK = 165;
|
||||
const LOG2 = 162, WOOD2 = 162;
|
||||
const ACACIA_STAIRS = 163;
|
||||
const DARK_OAK_STAIRS = 164;
|
||||
const SLIME = 165, SLIME_BLOCK = 165;
|
||||
|
||||
const IRON_TRAPDOOR = 167;
|
||||
const PRISMARINE = 168;
|
||||
const SEA_LANTERN = 169;
|
||||
const HAY_BALE = 170;
|
||||
const SEALANTERN = 169, SEA_LANTERN = 169;
|
||||
const HAY_BALE = 170, HAY_BLOCK = 170;
|
||||
const CARPET = 171;
|
||||
const HARDENED_CLAY = 172;
|
||||
const COAL_BLOCK = 173;
|
||||
const PACKED_ICE = 174;
|
||||
const DOUBLE_PLANT = 175;
|
||||
|
||||
const INVERTED_DAYLIGHT_SENSOR = 178, DAYLIGHT_SENSOR_INVERTED = 178;
|
||||
const DAYLIGHT_DETECTOR_INVERTED = 178, DAYLIGHT_SENSOR_INVERTED = 178;
|
||||
const RED_SANDSTONE = 179;
|
||||
const RED_SANDSTONE_STAIRS = 180;
|
||||
const DOUBLE_RED_SANDSTONE_SLAB = 181;
|
||||
const RED_SANDSTONE_SLAB = 182;
|
||||
const SPRUCE_FENCE_GATE = 183, FENCE_GATE_SPRUCE = 183;
|
||||
const BIRCH_FENCE_GATE = 184, FENCE_GATE_BIRCH = 184;
|
||||
const JUNGLE_FENCE_GATE = 185, FENCE_GATE_JUNGLE = 185;
|
||||
const DARK_OAK_FENCE_GATE = 186, FENCE_GATE_DARK_OAK = 186;
|
||||
const ACACIA_FENCE_GATE = 187, FENCE_GATE_ACACIA = 187;
|
||||
const DOUBLE_STONE_SLAB2 = 181;
|
||||
const STONE_SLAB2 = 182;
|
||||
const SPRUCE_FENCE_GATE = 183;
|
||||
const BIRCH_FENCE_GATE = 184;
|
||||
const JUNGLE_FENCE_GATE = 185;
|
||||
const DARK_OAK_FENCE_GATE = 186;
|
||||
const ACACIA_FENCE_GATE = 187;
|
||||
const REPEATING_COMMAND_BLOCK = 188;
|
||||
const CHAIN_COMMAND_BLOCK = 189;
|
||||
|
||||
const SPRUCE_DOOR_BLOCK = 193;
|
||||
const BIRCH_DOOR_BLOCK = 194;
|
||||
@ -217,16 +221,56 @@ interface BlockIds{
|
||||
const ACACIA_DOOR_BLOCK = 196;
|
||||
const DARK_OAK_DOOR_BLOCK = 197;
|
||||
const GRASS_PATH = 198;
|
||||
const ITEM_FRAME_BLOCK = 199;
|
||||
const FRAME_BLOCK = 199, ITEM_FRAME_BLOCK = 199;
|
||||
const CHORUS_FLOWER = 200;
|
||||
const PURPUR_BLOCK = 201;
|
||||
|
||||
const PURPUR_STAIRS = 203;
|
||||
|
||||
const END_BRICKS = 206;
|
||||
const FROSTED_ICE = 207;
|
||||
const END_ROD = 208;
|
||||
const END_GATEWAY = 209;
|
||||
|
||||
const MAGMA = 213;
|
||||
const NETHER_WART_BLOCK = 214;
|
||||
const RED_NETHER_BRICK = 215;
|
||||
const BONE_BLOCK = 216;
|
||||
|
||||
const SHULKER_BOX = 218;
|
||||
const PURPLE_GLAZED_TERRACOTTA = 219;
|
||||
const WHITE_GLAZED_TERRACOTTA = 220;
|
||||
const ORANGE_GLAZED_TERRACOTTA = 221;
|
||||
const MAGENTA_GLAZED_TERRACOTTA = 222;
|
||||
const LIGHT_BLUE_GLAZED_TERRACOTTA = 223;
|
||||
const YELLOW_GLAZED_TERRACOTTA = 224;
|
||||
const LIME_GLAZED_TERRACOTTA = 225;
|
||||
const PINK_GLAZED_TERRACOTTA = 226;
|
||||
const GRAY_GLAZED_TERRACOTTA = 227;
|
||||
const SILVER_GLAZED_TERRACOTTA = 228;
|
||||
const CYAN_GLAZED_TERRACOTTA = 229;
|
||||
|
||||
const BLUE_GLAZED_TERRACOTTA = 231;
|
||||
const BROWN_GLAZED_TERRACOTTA = 232;
|
||||
const GREEN_GLAZED_TERRACOTTA = 233;
|
||||
const RED_GLAZED_TERRACOTTA = 234;
|
||||
const BLACK_GLAZED_TERRACOTTA = 235;
|
||||
const CONCRETE = 236;
|
||||
const CONCRETEPOWDER = 237, CONCRETE_POWDER = 237;
|
||||
|
||||
const CHORUS_PLANT = 240;
|
||||
const STAINED_GLASS = 241;
|
||||
|
||||
const PODZOL = 243;
|
||||
const BEETROOT_BLOCK = 244;
|
||||
const STONECUTTER = 245;
|
||||
const GLOWING_OBSIDIAN = 246;
|
||||
const NETHER_REACTOR = 247;
|
||||
const UPDATE_BLOCK = 248;
|
||||
const ATEUPD_BLOCK = 249;
|
||||
const BLOCK_MOVED_BY_PISTON = 250;
|
||||
const GLOWINGOBSIDIAN = 246, GLOWING_OBSIDIAN = 246;
|
||||
const NETHERREACTOR = 247, NETHER_REACTOR = 247;
|
||||
const INFO_UPDATE = 248;
|
||||
const INFO_UPDATE2 = 249;
|
||||
const MOVINGBLOCK = 250, MOVING_BLOCK = 250;
|
||||
const OBSERVER = 251;
|
||||
const INFO_RESERVED6 = 255;
|
||||
|
||||
const RESERVED6 = 255;
|
||||
|
||||
}
|
||||
|
69
src/pocketmine/block/BoneBlock.php
Normal file
69
src/pocketmine/block/BoneBlock.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\PillarRotationHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class BoneBlock extends Solid{
|
||||
|
||||
protected $id = Block::BONE_BLOCK;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Bone Block";
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->meta = PillarRotationHelper::getMetaFromFace($this->meta, $face);
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x03;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item); // TODO: Change the autogenerated stub
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,28 +19,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Bookshelf extends Solid{
|
||||
|
||||
protected $id = self::BOOKSHELF;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Bookshelf";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 1.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::BOOK, 0, 3)
|
||||
];
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
@ -27,19 +29,25 @@ class BrewingStand extends Transparent{
|
||||
|
||||
protected $id = self::BREWING_STAND_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Brewing Stand";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
@ -27,23 +29,23 @@ class BrickStairs extends Stair{
|
||||
|
||||
protected $id = self::BRICK_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Brick Stairs";
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -26,35 +28,33 @@ use pocketmine\item\Tool;
|
||||
|
||||
class Bricks extends Solid{
|
||||
|
||||
protected $id = self::BRICKS_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
protected $id = self::BRICK_BLOCK;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Bricks";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::BRICKS_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,53 +19,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class BrownMushroom extends Flowable{
|
||||
class BrownMushroom extends RedMushroom{
|
||||
|
||||
protected $id = self::BROWN_MUSHROOM;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Brown Mushroom";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->isTransparent() === false){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -19,10 +19,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
@ -36,39 +39,35 @@ class BurningFurnace extends Solid{
|
||||
|
||||
protected $id = self::BURNING_FURNACE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Burning Furnace";
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 13;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
3 => 3
|
||||
];
|
||||
$this->meta = $faces[$player instanceof Player ? $player->getDirection() : 0];
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$nbt = new CompoundTag("", [
|
||||
new ListTag("Items", []),
|
||||
new StringTag("id", Tile::FURNACE),
|
||||
@ -93,13 +92,7 @@ class BurningFurnace extends Solid{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$furnace = $this->getLevel()->getTile($this);
|
||||
if(!($furnace instanceof TileFurnace)){
|
||||
@ -126,12 +119,15 @@ class BurningFurnace extends Solid{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
$drops[] = [Item::FURNACE, 0, 1];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return $drops;
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
@ -36,19 +38,19 @@ class Cactus extends Transparent{
|
||||
|
||||
protected $id = self::CACTUS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.4;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cactus";
|
||||
}
|
||||
|
||||
@ -64,14 +66,18 @@ class Cactus extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
|
||||
$entity->attack($ev->getFinalDamage(), $ev);
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
|
||||
$entity->attack($ev);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}else{
|
||||
@ -83,12 +89,12 @@ class Cactus extends Transparent{
|
||||
}
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getId() !== self::CACTUS){
|
||||
if($this->meta == 0x0F){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::CACTUS){
|
||||
if($this->meta === 0x0f){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getId() === self::AIR){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Cactus()));
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, BlockFactory::get(Block::CACTUS)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||
}
|
||||
@ -106,13 +112,13 @@ class Cactus extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::SAND or $down->getId() === self::CACTUS){
|
||||
$block0 = $this->getSide(2);
|
||||
$block1 = $this->getSide(3);
|
||||
$block2 = $this->getSide(4);
|
||||
$block3 = $this->getSide(5);
|
||||
$block0 = $this->getSide(Vector3::SIDE_NORTH);
|
||||
$block1 = $this->getSide(Vector3::SIDE_SOUTH);
|
||||
$block2 = $this->getSide(Vector3::SIDE_WEST);
|
||||
$block3 = $this->getSide(Vector3::SIDE_EAST);
|
||||
if($block0->isTransparent() === true and $block1->isTransparent() === true and $block2->isTransparent() === true and $block3->isTransparent() === true){
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
@ -123,9 +129,7 @@ class Cactus extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Effect;
|
||||
@ -27,34 +29,31 @@ use pocketmine\item\FoodSource;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Cake extends Transparent implements FoodSource{
|
||||
|
||||
protected $id = self::CAKE_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cake Block";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
$f = (1 + $this->getDamage() * 2) / 16;
|
||||
$f = $this->getDamage() * 0.125; //1 slice width
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $f,
|
||||
$this->x + 0.0625 + $f,
|
||||
$this->y,
|
||||
$this->z + 0.0625,
|
||||
$this->x + 1 - 0.0625,
|
||||
@ -63,10 +62,10 @@ class Cake extends Transparent implements FoodSource{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -74,10 +73,10 @@ class Cake extends Transparent implements FoodSource{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -86,15 +85,22 @@ class Cake extends Transparent implements FoodSource{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($player instanceof Player and $player->getHealth() < $player->getMaxHealth()){
|
||||
$ev = new EntityEatBlockEvent($player, $this);
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
//TODO: refactor this into generic food handling
|
||||
if($player instanceof Player and $player->getFood() < $player->getMaxFood()){
|
||||
$player->getServer()->getPluginManager()->callEvent($ev = new EntityEatBlockEvent($player, $this));
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
$player->addFood($ev->getFoodRestore());
|
||||
$player->addSaturation($ev->getSaturationRestore());
|
||||
foreach($ev->getAdditionalEffects() as $effect){
|
||||
$player->addEffect($effect);
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($this, $ev->getResidue());
|
||||
return true;
|
||||
}
|
||||
@ -114,8 +120,8 @@ class Cake extends Transparent implements FoodSource{
|
||||
public function getResidue(){
|
||||
$clone = clone $this;
|
||||
$clone->meta++;
|
||||
if($clone->meta >= 0x06){
|
||||
$clone = new Air();
|
||||
if($clone->meta > 0x06){
|
||||
$clone = BlockFactory::get(Block::AIR);
|
||||
}
|
||||
return $clone;
|
||||
}
|
||||
|
@ -19,49 +19,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorBlockMetaHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Carpet extends Flowable{
|
||||
|
||||
protected $id = self::CARPET;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.1;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
0 => "White Carpet",
|
||||
1 => "Orange Carpet",
|
||||
2 => "Magenta Carpet",
|
||||
3 => "Light Blue Carpet",
|
||||
4 => "Yellow Carpet",
|
||||
5 => "Lime Carpet",
|
||||
6 => "Pink Carpet",
|
||||
7 => "Gray Carpet",
|
||||
8 => "Light Gray Carpet",
|
||||
9 => "Cyan Carpet",
|
||||
10 => "Purple Carpet",
|
||||
11 => "Blue Carpet",
|
||||
12 => "Brown Carpet",
|
||||
13 => "Green Carpet",
|
||||
14 => "Red Carpet",
|
||||
15 => "Black Carpet",
|
||||
];
|
||||
return $names[$this->meta & 0x0f];
|
||||
public function getName() : string{
|
||||
return ColorBlockMetaHelper::getColorFromMeta($this->meta) . " Carpet";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -76,10 +62,10 @@ class Carpet extends Flowable{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -87,9 +73,9 @@ class Carpet extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getId() === self::AIR){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -19,30 +19,28 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
|
||||
class Carrot extends Crops{
|
||||
|
||||
protected $id = self::CARROT_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Carrot Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$drops = [];
|
||||
if($this->meta >= 0x07){
|
||||
$drops[] = [Item::CARROT, 0, mt_rand(1, 4)];
|
||||
}else{
|
||||
$drops[] = [Item::CARROT, 0, 1];
|
||||
}
|
||||
|
||||
return $drops;
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::CARROT, 0, $this->meta >= 0x07 ? mt_rand(1, 4) : 1)
|
||||
];
|
||||
}
|
||||
}
|
@ -19,11 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
@ -37,23 +40,19 @@ class Chest extends Transparent{
|
||||
|
||||
protected $id = self::CHEST;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Chest";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
@ -68,12 +67,12 @@ class Chest extends Transparent{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 2,
|
||||
2 => 5,
|
||||
3 => 3,
|
||||
3 => 3
|
||||
];
|
||||
|
||||
$chest = null;
|
||||
@ -95,7 +94,7 @@ class Chest extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$nbt = new CompoundTag("", [
|
||||
new ListTag("Items", []),
|
||||
new StringTag("id", Tile::CHEST),
|
||||
@ -125,22 +124,18 @@ class Chest extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
if($t instanceof TileChest){
|
||||
$t->unpair();
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$top = $this->getSide(1);
|
||||
if($top->isTransparent() !== true){
|
||||
return true;
|
||||
}
|
||||
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
$chest = null;
|
||||
@ -158,10 +153,12 @@ class Chest extends Transparent{
|
||||
$chest = Tile::createTile("Chest", $this->getLevel(), $nbt);
|
||||
}
|
||||
|
||||
if(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof StringTag){
|
||||
if($chest->namedtag->Lock->getValue() !== $item->getCustomName()){
|
||||
return true;
|
||||
}
|
||||
if(
|
||||
!$this->getSide(Vector3::SIDE_UP)->isTransparent() or
|
||||
($chest->isPaired() and !$chest->getPair()->getBlock()->getSide(Vector3::SIDE_UP)->isTransparent()) or
|
||||
(isset($chest->namedtag->Lock) and $chest->namedtag->Lock instanceof StringTag and $chest->namedtag->Lock->getValue() !== $item->getCustomName())
|
||||
){
|
||||
return true;
|
||||
}
|
||||
|
||||
$player->addWindow($chest->getInventory());
|
||||
@ -170,9 +167,11 @@ class Chest extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
@ -19,34 +19,37 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Clay extends Solid{
|
||||
|
||||
protected $id = self::CLAY_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Clay Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::CLAY, 0, 4],
|
||||
ItemFactory::get(Item::CLAY_BALL, 0, 4)
|
||||
];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,31 @@ class Coal extends Solid{
|
||||
|
||||
protected $id = self::COAL_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Coal Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::COAL_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 16000;
|
||||
}
|
||||
}
|
@ -19,39 +19,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class CoalOre extends Solid{
|
||||
|
||||
protected $id = self::COAL_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Coal Ore";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::COAL, 0, 1],
|
||||
ItemFactory::get(Item::COAL, 0, 1)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Cobblestone extends Solid{
|
||||
|
||||
protected $id = self::COBBLESTONE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cobblestone";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::COBBLESTONE, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
@ -27,19 +29,19 @@ class CobblestoneStairs extends Stair{
|
||||
|
||||
protected $id = self::COBBLESTONE_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cobblestone Stairs";
|
||||
}
|
||||
|
||||
|
@ -19,35 +19,37 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
class StoneWall extends Transparent{
|
||||
class CobblestoneWall extends Transparent{
|
||||
const NONE_MOSSY_WALL = 0;
|
||||
const MOSSY_WALL = 1;
|
||||
|
||||
protected $id = self::STONE_WALL;
|
||||
protected $id = self::COBBLESTONE_WALL;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
if($this->meta === 0x01){
|
||||
return "Mossy Cobblestone Wall";
|
||||
}
|
||||
@ -86,7 +88,7 @@ class StoneWall extends Transparent{
|
||||
}
|
||||
|
||||
public function canConnect(Block $block){
|
||||
return ($block->getId() !== self::COBBLE_WALL and $block->getId() !== self::FENCE_GATE) ? $block->isSolid() and !$block->isTransparent() : true;
|
||||
return ($block->getId() !== self::COBBLESTONE_WALL and $block->getId() !== self::FENCE_GATE) ? $block->isSolid() and !$block->isTransparent() : true;
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
@ -29,23 +31,23 @@ class Cobweb extends Flowable{
|
||||
|
||||
protected $id = self::COBWEB;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cobweb";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 4;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SWORD;
|
||||
}
|
||||
|
||||
@ -53,8 +55,12 @@ class Cobweb extends Flowable{
|
||||
$entity->resetFallDistance();
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
//TODO: correct drops
|
||||
return [];
|
||||
}
|
||||
|
||||
public function diffusesSkyLight() : bool{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -19,17 +19,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class CocoaBlock extends Solid{
|
||||
|
||||
protected $id = self::COCOA_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Cocoa Block";
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -19,38 +19,40 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorBlockMetaHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class WoodDoor extends Door{
|
||||
class Concrete extends Solid{
|
||||
|
||||
protected $id = self::WOOD_DOOR_BLOCK;
|
||||
protected $id = Block::CONCRETE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Wood Door Block";
|
||||
public function getName() : string{
|
||||
return ColorBlockMetaHelper::getColorFromMeta($this->meta) . " Concrete";
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
public function getHardness() : float{
|
||||
return 1.8;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 3;
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
return Tool::TYPE_AXE;
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[Item::WOODEN_DOOR, 0, 1],
|
||||
];
|
||||
}
|
||||
}
|
@ -19,38 +19,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\Player;
|
||||
|
||||
//TODO: check orientation
|
||||
class Workbench extends Solid{
|
||||
class CraftingTable extends Solid{
|
||||
|
||||
protected $id = self::WORKBENCH;
|
||||
protected $id = self::CRAFTING_TABLE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Crafting Table";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
$player->craftingType = 1;
|
||||
}
|
||||
@ -58,9 +55,7 @@ class Workbench extends Solid{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
@ -19,24 +19,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
abstract class Crops extends Flowable{
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getId() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($blockReplace->getSide(Vector3::SIDE_DOWN)->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -45,7 +43,7 @@ abstract class Crops extends Flowable{
|
||||
}
|
||||
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$block = clone $this;
|
||||
$block->meta += mt_rand(2, 5);
|
||||
@ -67,14 +65,18 @@ abstract class Crops extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== Block::FARMLAND){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if(mt_rand(0, 2) == 1){
|
||||
if(mt_rand(0, 2) === 1){
|
||||
if($this->meta < 0x07){
|
||||
$block = clone $this;
|
||||
++$block->meta;
|
||||
|
@ -19,29 +19,32 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Dandelion extends Flowable{
|
||||
|
||||
protected $id = self::DANDELION;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Dandelion";
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getId() === 2 or $down->getId() === 3 or $down->getId() === 60){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -49,9 +52,9 @@ class Dandelion extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class DarkOakWoodStairs extends WoodStairs{
|
||||
|
||||
protected $id = self::DARK_OAK_WOOD_STAIRS;
|
||||
|
||||
public function getName(){
|
||||
return "Dark Oak Wood Stairs";
|
||||
}
|
||||
}
|
@ -19,21 +19,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class DaylightSensor extends Transparent{
|
||||
|
||||
protected $id = self::DAYLIGHT_SENSOR;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Daylight Sensor";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.2;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -19,26 +19,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
class DeadBush extends Flowable{
|
||||
|
||||
protected $id = self::DEAD_BUSH;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Dead Bush";
|
||||
}
|
||||
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -19,17 +19,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class DetectorRail extends Rail{
|
||||
|
||||
protected $id = self::DETECTOR_RAIL;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Detector Rail";
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Diamond extends Solid{
|
||||
|
||||
protected $id = self::DIAMOND_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Diamond Block";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::DIAMOND_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,38 +19,41 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class DiamondOre extends Solid{
|
||||
|
||||
protected $id = self::DIAMOND_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Diamond Ore";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::DIAMOND, 0, 1],
|
||||
ItemFactory::get(Item::DIAMOND, 0, 1)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -29,30 +31,26 @@ class Dirt extends Solid{
|
||||
|
||||
protected $id = self::DIRT;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Dirt";
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::FARMLAND, 0), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND, 0), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -31,11 +33,7 @@ use pocketmine\Player;
|
||||
|
||||
abstract class Door extends Transparent{
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -203,12 +201,12 @@ abstract class Door extends Transparent{
|
||||
return $bb;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), false);
|
||||
if($this->getSide(1) instanceof Door){
|
||||
$this->getLevel()->setBlock($this->getSide(1), new Air(), false);
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), false);
|
||||
if($this->getSide(Vector3::SIDE_UP) instanceof Door){
|
||||
$this->getLevel()->setBlock($this->getSide(Vector3::SIDE_UP), BlockFactory::get(Block::AIR), false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
@ -218,64 +216,59 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
if($face === 1){
|
||||
$blockUp = $this->getSide(1);
|
||||
$blockDown = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_UP){
|
||||
$blockUp = $this->getSide(Vector3::SIDE_UP);
|
||||
$blockDown = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($blockUp->canBeReplaced() === false or $blockDown->isTransparent() === true){
|
||||
return false;
|
||||
}
|
||||
$direction = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$face = [
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
3 => 5
|
||||
];
|
||||
$next = $this->getSide($face[(($direction + 2) % 4)]);
|
||||
$next2 = $this->getSide($face[$direction]);
|
||||
$next = $this->getSide($faces[($direction + 2) % 4]);
|
||||
$next2 = $this->getSide($faces[$direction]);
|
||||
$metaUp = 0x08;
|
||||
if($next->getId() === $this->getId() or ($next2->isTransparent() === false and $next->isTransparent() === true)){ //Door hinge
|
||||
$metaUp |= 0x01;
|
||||
}
|
||||
|
||||
$this->setDamage($player->getDirection() & 0x03);
|
||||
$this->getLevel()->setBlock($block, $this, true, true); //Bottom
|
||||
$this->getLevel()->setBlock($blockUp, $b = Block::get($this->getId(), $metaUp), true); //Top
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true); //Bottom
|
||||
$this->getLevel()->setBlock($blockUp, $b = BlockFactory::get($this->getId(), $metaUp), true); //Top
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
if(($this->getDamage() & 0x08) === 0x08){
|
||||
$down = $this->getSide(0);
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === $this->getId()){
|
||||
$this->getLevel()->setBlock($down, new Air(), true);
|
||||
$this->getLevel()->setBlock($down, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}else{
|
||||
$up = $this->getSide(1);
|
||||
$up = $this->getSide(Vector3::SIDE_UP);
|
||||
if($up->getId() === $this->getId()){
|
||||
$this->getLevel()->setBlock($up, new Air(), true);
|
||||
$this->getLevel()->setBlock($up, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if(($this->getDamage() & 0x08) === 0x08){ //Top
|
||||
$down = $this->getSide(0);
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === $this->getId()){
|
||||
$meta = $down->getDamage() ^ 0x04;
|
||||
$this->getLevel()->setBlock($down, Block::get($this->getId(), $meta), true);
|
||||
$players = $this->getLevel()->getChunkPlayers($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->getLoaderId()]);
|
||||
}
|
||||
|
||||
$this->level->setBlock($down, BlockFactory::get($this->getId(), $meta), true);
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
return true;
|
||||
}
|
||||
@ -283,14 +276,14 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}else{
|
||||
$this->meta ^= 0x04;
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$players = $this->getLevel()->getChunkPlayers($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->getLoaderId()]);
|
||||
}
|
||||
$this->level->setBlock($this, $this, true);
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -19,24 +19,30 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class DoublePlant extends Flowable{
|
||||
const BITFLAG_TOP = 0x08;
|
||||
|
||||
protected $id = self::DOUBLE_PLANT;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
return true;
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return $this->meta === 2 or $this->meta === 3; //grass or fern
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
0 => "Sunflower",
|
||||
1 => "Lilac",
|
||||
@ -45,14 +51,44 @@ class DoublePlant extends Flowable{
|
||||
4 => "Rose Bush",
|
||||
5 => "Peony"
|
||||
];
|
||||
return $names[$this->meta & 0x07];
|
||||
return $names[$this->meta & 0x07] ?? "";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$id = $blockReplace->getSide(Vector3::SIDE_DOWN)->getId();
|
||||
if(($id === Block::GRASS or $id === Block::DIRT) and $blockReplace->getSide(Vector3::SIDE_UP)->canBeReplaced()){
|
||||
$this->getLevel()->setBlock($blockReplace, $this, false, false);
|
||||
$this->getLevel()->setBlock($blockReplace->getSide(Vector3::SIDE_UP), BlockFactory::get($this->id, $this->meta | self::BITFLAG_TOP), false, false);
|
||||
|
||||
public function onUpdate($type){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this double-plant has a corresponding other half.
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidHalfPlant() : bool{
|
||||
if($this->meta & self::BITFLAG_TOP){
|
||||
$other = $this->getSide(Vector3::SIDE_DOWN);
|
||||
}else{
|
||||
$other = $this->getSide(Vector3::SIDE_UP);
|
||||
}
|
||||
|
||||
return (
|
||||
$other->getId() === $this->getId() and
|
||||
($other->getDamage() & 0x07) === ($this->getDamage() & 0x07) and
|
||||
($other->getDamage() & self::BITFLAG_TOP) !== ($this->getDamage() & self::BITFLAG_TOP)
|
||||
);
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true);
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if(!$this->isValidHalfPlant() or (($this->meta & self::BITFLAG_TOP) === 0 and $down->isTransparent())){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -61,10 +97,33 @@ class DoublePlant extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
//TODO
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
if(parent::onBreak($item, $player) and $this->isValidHalfPlant()){
|
||||
$this->getLevel()->useBreakOn($this->getSide(($this->meta & self::BITFLAG_TOP) !== 0 ? Vector3::SIDE_DOWN : Vector3::SIDE_UP), $item, $player, $player !== null);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x07;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->meta & self::BITFLAG_TOP){
|
||||
if(!$item->isShears() and ($this->meta === 2 or $this->meta === 3)){ //grass or fern
|
||||
if(mt_rand(0, 24) === 0){
|
||||
return [
|
||||
ItemFactory::get(Item::SEEDS, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,28 +19,31 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class DoubleSlab extends Solid{
|
||||
class DoubleStoneSlab extends Solid{
|
||||
|
||||
protected $id = self::DOUBLE_SLAB;
|
||||
protected $id = self::DOUBLE_STONE_SLAB;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
0 => "Stone",
|
||||
1 => "Sandstone",
|
||||
@ -49,19 +52,19 @@ class DoubleSlab extends Solid{
|
||||
4 => "Brick",
|
||||
5 => "Stone Brick",
|
||||
6 => "Quartz",
|
||||
7 => "Nether Brick",
|
||||
7 => "Nether Brick"
|
||||
];
|
||||
return "Double " . $names[$this->meta & 0x07] . " Slab";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::SLAB, $this->meta & 0x07, 2],
|
||||
ItemFactory::get(Item::STONE_SLAB, $this->getDamage() & 0x07, 2)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -19,44 +19,45 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class DoubleWoodSlab extends Solid{
|
||||
class DoubleWoodenSlab extends Solid{
|
||||
|
||||
protected $id = self::DOUBLE_WOOD_SLAB;
|
||||
protected $id = self::DOUBLE_WOODEN_SLAB;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
0 => "Oak",
|
||||
1 => "Spruce",
|
||||
2 => "Birch",
|
||||
3 => "Jungle",
|
||||
4 => "Acacia",
|
||||
5 => "Dark Oak",
|
||||
6 => "",
|
||||
7 => ""
|
||||
5 => "Dark Oak"
|
||||
];
|
||||
return "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||
return "Double " . ($names[$this->meta & 0x07] ?? "") . " Wooden Slab";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::WOOD_SLAB, $this->meta & 0x07, 2],
|
||||
ItemFactory::get(Item::WOODEN_SLAB, $this->getDamage() & 0x07, 2)
|
||||
];
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Emerald extends Solid{
|
||||
|
||||
protected $id = self::EMERALD_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Emerald Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::EMERALD_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,38 +19,41 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class EmeraldOre extends Solid{
|
||||
|
||||
protected $id = self::EMERALD_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Emerald Ore";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::EMERALD, 0, 1],
|
||||
ItemFactory::get(Item::EMERALD, 0, 1)
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,11 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\inventory\EnchantInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
@ -34,12 +37,12 @@ class EnchantingTable extends Transparent{
|
||||
|
||||
protected $id = self::ENCHANTING_TABLE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::ENCHANT_TABLE),
|
||||
new IntTag("x", $this->x),
|
||||
@ -62,27 +65,23 @@ class EnchantingTable extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 6000;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Enchanting Table";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
//TODO lock
|
||||
|
||||
@ -92,13 +91,11 @@ class EnchantingTable extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,27 +30,27 @@ class EndPortalFrame extends Solid{
|
||||
|
||||
protected $id = self::END_PORTAL_FRAME;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "End Portal Frame";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 18000000;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
104
src/pocketmine/block/EndRod.php
Normal file
104
src/pocketmine/block/EndRod.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\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class EndRod extends Flowable{
|
||||
|
||||
protected $id = Block::END_ROD;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "End Rod";
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_UP or $face === Vector3::SIDE_DOWN){
|
||||
$this->meta = $face;
|
||||
}else{
|
||||
$this->meta = $face ^ 0x01;
|
||||
}
|
||||
if($blockClicked instanceof EndRod and $blockClicked->getDamage() === $this->meta){
|
||||
$this->meta ^= 0x01;
|
||||
}
|
||||
|
||||
return $this->level->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function isSolid() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 14;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
$m = $this->meta & ~0x01;
|
||||
$width = 0.375;
|
||||
|
||||
switch($m){
|
||||
case 0x00: //up/down
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $width,
|
||||
$this->y,
|
||||
$this->z + $width,
|
||||
$this->x + 1 - $width,
|
||||
$this->y + 1,
|
||||
$this->z + 1 - $width
|
||||
);
|
||||
case 0x02: //north/south
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y + $width,
|
||||
$this->z + $width,
|
||||
$this->x + 1,
|
||||
$this->y + 1 - $width,
|
||||
$this->z + 1 - $width
|
||||
);
|
||||
case 0x04: //east/west
|
||||
return new AxisAlignedBB(
|
||||
$this->x + $width,
|
||||
$this->y + $width,
|
||||
$this->z,
|
||||
$this->x + 1 - $width,
|
||||
$this->y + 1 - $width,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
@ -27,19 +29,19 @@ class EndStone extends Solid{
|
||||
|
||||
protected $id = self::END_STONE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "End Stone";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
@ -33,27 +35,28 @@ use pocketmine\nbt\tag\ListTag;
|
||||
|
||||
abstract class Fallable extends Solid{
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === self::AIR or ($down instanceof Liquid)){
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
$fall = Entity::createEntity("FallingSand", $this->getLevel(), new CompoundTag("", [
|
||||
"Pos" => new ListTag("Pos", [
|
||||
new ListTag("Pos", [
|
||||
new DoubleTag("", $this->x + 0.5),
|
||||
new DoubleTag("", $this->y),
|
||||
new DoubleTag("", $this->z + 0.5)
|
||||
]),
|
||||
"Motion" => new ListTag("Motion", [
|
||||
new ListTag("Motion", [
|
||||
new DoubleTag("", 0),
|
||||
new DoubleTag("", 0),
|
||||
new DoubleTag("", 0)
|
||||
]),
|
||||
"Rotation" => new ListTag("Rotation", [
|
||||
new ListTag("Rotation", [
|
||||
new FloatTag("", 0),
|
||||
new FloatTag("", 0)
|
||||
]),
|
||||
"TileID" => new IntTag("TileID", $this->getId()),
|
||||
"Data" => new ByteTag("Data", $this->getDamage()),
|
||||
new IntTag("TileID", $this->getId()),
|
||||
new ByteTag("Data", $this->getDamage())
|
||||
]));
|
||||
|
||||
$fall->spawnToAll();
|
||||
|
@ -19,46 +19,62 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
class Farmland extends Solid{
|
||||
class Farmland extends Transparent{
|
||||
|
||||
protected $id = self::FARMLAND;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Farmland";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 0.9375,
|
||||
$this->y + 1, //TODO: this should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109)
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
//TODO: hydration
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
@ -35,31 +37,29 @@ class Fence extends Transparent{
|
||||
|
||||
protected $id = self::FENCE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
self::FENCE_OAK => "Oak Fence",
|
||||
self::FENCE_SPRUCE => "Spruce Fence",
|
||||
self::FENCE_BIRCH => "Birch Fence",
|
||||
self::FENCE_JUNGLE => "Jungle Fence",
|
||||
self::FENCE_ACACIA => "Acacia Fence",
|
||||
self::FENCE_DARKOAK => "Dark Oak Fence",
|
||||
"",
|
||||
""
|
||||
self::FENCE_DARKOAK => "Dark Oak Fence"
|
||||
];
|
||||
return $names[$this->meta & 0x07];
|
||||
return $names[$this->meta & 0x07] ?? "Unknown";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -88,4 +88,8 @@ class Fence extends Transparent{
|
||||
return ($block instanceof Fence or $block instanceof FenceGate) ? true : $block->isSolid() and !$block->isTransparent();
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,35 +19,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\sound\DoorSound;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class FenceGate extends Transparent{
|
||||
|
||||
protected $id = self::FENCE_GATE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Oak Fence Gate";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
@ -80,20 +69,18 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$this->meta = ($player instanceof Player ? ($player->getDirection() - 1) & 0x03 : 0);
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$this->meta = (($this->meta ^ 0x04) & ~0x02);
|
||||
|
||||
if($player !== null){
|
||||
@ -104,4 +91,8 @@ class FenceGate extends Transparent{
|
||||
$this->level->addSound(new DoorSound($this));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateSpruce extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_SPRUCE;
|
||||
|
||||
public function getName(){
|
||||
return "Spruce Fence Gate";
|
||||
}
|
||||
}
|
@ -19,51 +19,55 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Arrow;
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\entity\EntityCombustByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageByBlockEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Fire extends Flowable{
|
||||
|
||||
protected $id = self::FIRE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Fire Block";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
public function isBreakable(Item $item) : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
public function canBeReplaced(Block $with = null) : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
if(!$entity->hasEffect(Effect::FIRE_RESISTANCE)){
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
|
||||
$entity->attack($ev->getFinalDamage(), $ev);
|
||||
}
|
||||
$ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1);
|
||||
$entity->attack($ev);
|
||||
|
||||
$ev = new EntityCombustByBlockEvent($this, $entity, 8);
|
||||
if($entity instanceof Arrow){
|
||||
@ -75,11 +79,11 @@ class Fire extends Flowable{
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
for($s = 0; $s <= 5; ++$s){
|
||||
$side = $this->getSide($s);
|
||||
@ -87,14 +91,14 @@ class Fire extends Flowable{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getId() !== self::NETHERRACK){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->getId() !== self::NETHERRACK){
|
||||
if(mt_rand(0, 2) === 0){
|
||||
if($this->meta === 0x0F){
|
||||
$this->level->setBlock($this, new Air());
|
||||
$this->level->setBlock($this, BlockFactory::get(Block::AIR));
|
||||
}else{
|
||||
$this->meta++;
|
||||
$this->level->setBlock($this, $this);
|
||||
@ -103,6 +107,8 @@ class Fire extends Flowable{
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: fire spread
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -19,23 +19,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
abstract class Flowable extends Transparent{
|
||||
|
||||
public function canBeFlowedInto(){
|
||||
public function canBeFlowedInto() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getResistance(){
|
||||
public function getBlastResistance() : float{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -39,11 +41,11 @@ class Flower extends Flowable{
|
||||
|
||||
protected $id = self::RED_FLOWER;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
static $names = [
|
||||
self::TYPE_POPPY => "Poppy",
|
||||
self::TYPE_BLUE_ORCHID => "Blue Orchid",
|
||||
@ -53,23 +55,15 @@ class Flower extends Flowable{
|
||||
self::TYPE_ORANGE_TULIP => "Orange Tulip",
|
||||
self::TYPE_WHITE_TULIP => "White Tulip",
|
||||
self::TYPE_PINK_TULIP => "Pink Tulip",
|
||||
self::TYPE_OXEYE_DAISY => "Oxeye Daisy",
|
||||
9 => "Unknown",
|
||||
10 => "Unknown",
|
||||
11 => "Unknown",
|
||||
12 => "Unknown",
|
||||
13 => "Unknown",
|
||||
14 => "Unknown",
|
||||
15 => "Unknown"
|
||||
self::TYPE_OXEYE_DAISY => "Oxeye Daisy"
|
||||
];
|
||||
return $names[$this->meta];
|
||||
return $names[$this->meta] ?? "Unknown";
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === Block::GRASS or $down->getId() === Block::DIRT or $down->getId() === Block::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -77,7 +71,7 @@ class Flower extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
@ -19,9 +19,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -39,19 +42,16 @@ class FlowerPot extends Flowable{
|
||||
const STATE_FULL = 1;
|
||||
|
||||
protected $id = self::FLOWER_POT_BLOCK;
|
||||
protected $itemId = Item::FLOWER_POT;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Flower Pot Block";
|
||||
}
|
||||
|
||||
public function canBeActivated(): bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
return new AxisAlignedBB(
|
||||
$this->x + 0.3125,
|
||||
@ -63,20 +63,20 @@ class FlowerPot extends Flowable{
|
||||
);
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent()){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::FLOWER_POT),
|
||||
new IntTag("x", $block->x),
|
||||
new IntTag("y", $block->y),
|
||||
new IntTag("z", $block->z),
|
||||
new IntTag("x", $blockReplace->x),
|
||||
new IntTag("y", $blockReplace->y),
|
||||
new IntTag("z", $blockReplace->z),
|
||||
new ShortTag("item", 0),
|
||||
new IntTag("mData", 0),
|
||||
new IntTag("mData", 0)
|
||||
]);
|
||||
|
||||
if($item->hasCustomBlockData()){
|
||||
@ -89,9 +89,9 @@ class FlowerPot extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
if($this->getSide(Vector3::SIDE_DOWN)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
@ -101,7 +101,7 @@ class FlowerPot extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$pot = $this->getLevel()->getTile($this);
|
||||
if(!($pot instanceof TileFlowerPot)){
|
||||
return false;
|
||||
@ -117,20 +117,23 @@ class FlowerPot extends Flowable{
|
||||
if($player instanceof Player){
|
||||
if($player->isSurvival()){
|
||||
$item->setCount($item->getCount() - 1);
|
||||
$player->getInventory()->setItemInHand($item->getCount() > 0 ? $item : Item::get(Item::AIR));
|
||||
$player->getInventory()->setItemInHand($item->getCount() > 0 ? $item : ItemFactory::get(Item::AIR));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
$items = [[Item::FLOWER_POT, 0, 1]];
|
||||
public function getDrops(Item $item) : array{
|
||||
$items = parent::getDrops($item);
|
||||
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if($tile instanceof TileFlowerPot){
|
||||
if(($item = $tile->getItem())->getId() !== Item::AIR){
|
||||
$items[] = [$item->getId(), $item->getDamage(), 1];
|
||||
$item = $tile->getItem();
|
||||
if($item->getId() !== Item::AIR){
|
||||
$items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
@ -26,11 +28,11 @@ class Furnace extends BurningFurnace{
|
||||
|
||||
protected $id = self::FURNACE;
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Furnace";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -27,19 +29,19 @@ class Glass extends Transparent{
|
||||
|
||||
protected $id = self::GLASS;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glass";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -27,19 +29,19 @@ class GlassPane extends Thin{
|
||||
|
||||
protected $id = self::GLASS_PANE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glass Pane";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
67
src/pocketmine/block/GlazedTerracotta.php
Normal file
67
src/pocketmine/block/GlazedTerracotta.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?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\Tool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class GlazedTerracotta extends Solid{
|
||||
|
||||
public function getHardness() : float{
|
||||
return 1.4;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($player !== null){
|
||||
$faces = [
|
||||
0 => 4,
|
||||
1 => 3,
|
||||
2 => 5,
|
||||
3 => 2
|
||||
];
|
||||
$this->meta = $faces[(~($player->getDirection() - 1)) & 0x03];
|
||||
}
|
||||
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
@ -26,16 +28,23 @@ class GlowingObsidian extends Solid{
|
||||
|
||||
protected $id = self::GLOWING_OBSIDIAN;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glowing Obsidian";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 12;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 10;
|
||||
}
|
||||
|
||||
public function getBlastResistance() : float{
|
||||
return 50;
|
||||
}
|
||||
}
|
@ -19,26 +19,27 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class GlowingRedstoneOre extends RedstoneOre{
|
||||
|
||||
protected $id = self::GLOWING_REDSTONE_ORE;
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glowing Redstone Ore";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 9;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_SCHEDULED or $type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::REDSTONE_ORE, $this->meta), false, false);
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::REDSTONE_ORE, $this->meta), false, false);
|
||||
|
||||
return Level::BLOCK_UPDATE_WEAK;
|
||||
}
|
||||
|
@ -19,38 +19,41 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Glowstone extends Transparent{
|
||||
|
||||
protected $id = self::GLOWSTONE_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
protected $id = self::GLOWSTONE;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Glowstone";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
public function getLightLevel() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::GLOWSTONE_DUST, 0, mt_rand(2, 4)],
|
||||
ItemFactory::get(Item::GLOWSTONE_DUST, 0, mt_rand(2, 4))
|
||||
];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Gold extends Solid{
|
||||
|
||||
protected $id = self::GOLD_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Gold Block";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::GOLD_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class GoldOre extends Solid{
|
||||
|
||||
protected $id = self::GOLD_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Gold Ore";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
[Item::GOLD_ORE, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,71 +19,90 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\generator\object\TallGrass as TallGrassObject;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
class Grass extends Solid{
|
||||
|
||||
protected $id = self::GRASS;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Grass";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$block = $this->getLevel()->getBlock(new Vector3($this->x, $this->y, $this->z));
|
||||
if($block->getSide(1)->getLightLevel() < 4){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Dirt()));
|
||||
}elseif($block->getSide(1)->getLightLevel() >= 9){
|
||||
for($l = 0; $l < 4; ++$l){
|
||||
$x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
if($block->getId() === Block::DIRT && $block->getDamage() === 0x0F && $block->getSide(1)->getLightLevel() >= 4 && $block->z <= 2){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass()));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($block, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
$lightAbove = $this->level->getFullLightAt($this->x, $this->y + 1, $this->z);
|
||||
if($lightAbove < 4 and BlockFactory::$lightFilter[$this->level->getBlockIdAt($this->x, $this->y + 1, $this->z)] >= 3){ //2 plus 1 standard filter amount
|
||||
//grass dies
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this, $this, BlockFactory::get(Block::DIRT)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->level->setBlock($this, $ev->getNewState(), false, false);
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}elseif($lightAbove >= 9){
|
||||
//try grass spread
|
||||
$vector = $this->asVector3();
|
||||
for($i = 0; $i < 4; ++$i){
|
||||
$vector->x = mt_rand($this->x - 1, $this->x + 1);
|
||||
$vector->y = mt_rand($this->y - 3, $this->y + 1);
|
||||
$vector->z = mt_rand($this->z - 1, $this->z + 1);
|
||||
if(
|
||||
$this->level->getBlockIdAt($vector->x, $vector->y, $vector->z) !== Block::DIRT or
|
||||
$this->level->getFullLightAt($vector->x, $vector->y + 1, $vector->z) < 4 or
|
||||
BlockFactory::$lightFilter[$this->level->getBlockIdAt($vector->x, $vector->y + 1, $vector->z)] >= 3
|
||||
){
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->level->getServer()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($this->level->getBlock($vector), $this, BlockFactory::get(Block::GRASS)));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->level->setBlock($vector, $ev->getNewState(), false, false);
|
||||
}
|
||||
}
|
||||
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
$item->count--;
|
||||
TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
|
||||
@ -91,12 +110,12 @@ class Grass extends Solid{
|
||||
return true;
|
||||
}elseif($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, new Farmland());
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::FARMLAND));
|
||||
|
||||
return true;
|
||||
}elseif($item->isShovel() and $this->getSide(1)->getId() === Block::AIR){
|
||||
}elseif($item->isShovel() and $this->getSide(Vector3::SIDE_UP)->getId() === Block::AIR){
|
||||
$item->useOn($this);
|
||||
$this->getLevel()->setBlock($this, new GrassPath());
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::GRASS_PATH));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -19,9 +19,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
@ -29,15 +32,15 @@ class GrassPath extends Transparent{
|
||||
|
||||
protected $id = self::GRASS_PATH;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Grass Path";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
@ -47,18 +50,18 @@ class GrassPath extends Transparent{
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 1,
|
||||
$this->y + 0.9375,
|
||||
$this->y + 1, //TODO: this should be 0.9375, but MCPE currently treats them as a full block (https://bugs.mojang.com/browse/MCPE-12109)
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
];
|
||||
}
|
||||
}
|
@ -19,41 +19,42 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Gravel extends Fallable{
|
||||
|
||||
protected $id = self::GRAVEL;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Gravel";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if(mt_rand(1, 10) === 1){
|
||||
return [
|
||||
[Item::FLINT, 0, 1],
|
||||
ItemFactory::get(Item::FLINT, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
[Item::GRAVEL, 0, 1],
|
||||
];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
@ -27,19 +29,19 @@ class HardenedClay extends Solid{
|
||||
|
||||
protected $id = self::HARDENED_CLAY;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Hardened Clay";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 1.25;
|
||||
}
|
||||
}
|
@ -19,47 +19,47 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class HayBale extends Solid{
|
||||
|
||||
protected $id = self::HAY_BALE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Hay Bale";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
$faces = [
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0b1000,
|
||||
3 => 0b1000,
|
||||
4 => 0b0100,
|
||||
5 => 0b0100,
|
||||
5 => 0b0100
|
||||
];
|
||||
|
||||
$this->meta = ($this->meta & 0x03) | $faces[$face];
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x03;
|
||||
}
|
||||
|
||||
}
|
@ -19,38 +19,63 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Ice extends Transparent{
|
||||
|
||||
protected $id = self::ICE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Ice";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getLightFilter() : int{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getFrictionFactor() : float{
|
||||
return 0.98;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
$this->getLevel()->setBlock($this, new Water(), true);
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true);
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->level->getHighestAdjacentBlockLight($this->x, $this->y, $this->z) >= 12){
|
||||
$this->level->useBreakOn($this);
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class Iron extends Solid{
|
||||
|
||||
protected $id = self::IRON_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Iron Block";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_STONE){
|
||||
return [
|
||||
[Item::IRON_BLOCK, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,30 +30,32 @@ class IronBars extends Thin{
|
||||
|
||||
protected $id = self::IRON_BARS;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Iron Bars";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::IRON_BARS, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,29 @@ class IronDoor extends Door{
|
||||
|
||||
protected $id = self::IRON_DOOR_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
protected $itemId = Item::IRON_DOOR;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Iron Door Block";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
[Item::IRON_DOOR, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
@ -28,29 +30,27 @@ class IronOre extends Solid{
|
||||
|
||||
protected $id = self::IRON_ORE;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Iron Ore";
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_STONE){
|
||||
return [
|
||||
[Item::IRON_ORE, 0, 1],
|
||||
];
|
||||
}else{
|
||||
return [];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
@ -27,15 +29,15 @@ class IronTrapdoor extends Trapdoor{
|
||||
|
||||
protected $id = self::IRON_TRAPDOOR;
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Iron Trapdoor";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* 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
|
||||
@ -19,10 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\{
|
||||
ByteTag, CompoundTag, FloatTag, IntTag, StringTag
|
||||
};
|
||||
@ -33,19 +37,17 @@ use pocketmine\tile\Tile;
|
||||
class ItemFrame extends Flowable{
|
||||
protected $id = Block::ITEM_FRAME_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
protected $itemId = Item::ITEM_FRAME;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Item Frame";
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
$tile = $this->level->getTile($this);
|
||||
if(!($tile instanceof TileItemFrame)){
|
||||
$nbt = new CompoundTag("", [
|
||||
@ -68,7 +70,7 @@ class ItemFrame extends Flowable{
|
||||
$item->setCount($item->getCount() - 1);
|
||||
$tile->setItem($frameItem);
|
||||
if($player instanceof Player and $player->isSurvival()){
|
||||
$player->getInventory()->setItemInHand($item->getCount() <= 0 ? Item::get(Item::AIR) : $item);
|
||||
$player->getInventory()->setItemInHand($item->getCount() <= 0 ? ItemFactory::get(Item::AIR) : $item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -76,7 +78,7 @@ class ItemFrame extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
$tile = $this->level->getTile($this);
|
||||
if($tile instanceof TileItemFrame){
|
||||
//TODO: add events
|
||||
@ -84,10 +86,10 @@ class ItemFrame extends Flowable{
|
||||
$this->level->dropItem($tile->getBlock(), $tile->getItem());
|
||||
}
|
||||
}
|
||||
return parent::onBreak($item);
|
||||
return parent::onBreak($item, $player);
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$sides = [
|
||||
0 => 4,
|
||||
@ -103,26 +105,26 @@ class ItemFrame extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
if($face === 0 or $face === 1){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($face === Vector3::SIDE_DOWN or $face === Vector3::SIDE_UP){
|
||||
return false;
|
||||
}
|
||||
|
||||
$faces = [
|
||||
2 => 3,
|
||||
3 => 2,
|
||||
4 => 1,
|
||||
5 => 0
|
||||
Vector3::SIDE_NORTH => 3,
|
||||
Vector3::SIDE_SOUTH => 2,
|
||||
Vector3::SIDE_WEST => 1,
|
||||
Vector3::SIDE_EAST => 0
|
||||
];
|
||||
|
||||
$this->meta = $faces[$face];
|
||||
$this->level->setBlock($block, $this, true, true);
|
||||
$this->level->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
$nbt = new CompoundTag("", [
|
||||
new StringTag("id", Tile::ITEM_FRAME),
|
||||
new IntTag("x", $block->x),
|
||||
new IntTag("y", $block->y),
|
||||
new IntTag("z", $block->z),
|
||||
new IntTag("x", $blockReplace->x),
|
||||
new IntTag("y", $blockReplace->y),
|
||||
new IntTag("z", $blockReplace->z),
|
||||
new FloatTag("ItemDropChance", 1.0),
|
||||
new ByteTag("ItemRotation", 0)
|
||||
]);
|
||||
@ -139,10 +141,7 @@ class ItemFrame extends Flowable{
|
||||
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[Item::ITEM_FRAME, 0, 1]
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class JungleWoodStairs extends WoodStairs{
|
||||
|
||||
protected $id = self::JUNGLE_WOOD_STAIRS;
|
||||
|
||||
public function getName(){
|
||||
return "Jungle Wood Stairs";
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
@ -26,32 +28,37 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Ladder extends Transparent{
|
||||
|
||||
protected $id = self::LADDER;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName() : string{
|
||||
return "Ladder";
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
public function getHardness() : float{
|
||||
return 0.4;
|
||||
}
|
||||
|
||||
public function canClimb() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
$entity->resetFallDistance();
|
||||
$entity->onGround = true;
|
||||
@ -103,17 +110,17 @@ class Ladder extends Transparent{
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
if($target->isTransparent() === false){
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $facePos, Player $player = null) : bool{
|
||||
if($blockClicked->isTransparent() === false){
|
||||
$faces = [
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 5,
|
||||
5 => 5
|
||||
];
|
||||
if(isset($faces[$face])){
|
||||
$this->meta = $faces[$face];
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
$this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -122,7 +129,7 @@ class Ladder extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
public function onUpdate(int $type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$sides = [
|
||||
2 => 3,
|
||||
@ -139,13 +146,11 @@ class Ladder extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getToolType(){
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[$this->id, 0, 1],
|
||||
];
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user