mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-11 03:58:06 +00:00
Compare commits
267 Commits
api/3.0.0-
...
api/3.0.0-
Author | SHA1 | Date | |
---|---|---|---|
07bf1c9e22 | |||
b659a3d39f | |||
68b30108be | |||
f223fb2876 | |||
8bb785b7af | |||
806a2005d7 | |||
c794ced0ad | |||
f993358c5f | |||
1c12be6bf2 | |||
a1d9b8486e | |||
9397356ce4 | |||
e56e363dcc | |||
18b287c3ea | |||
9014eb72e9 | |||
82948726ed | |||
c601816586 | |||
d2d1df0447 | |||
f9b1afe4cf | |||
033cb8bd63 | |||
0ed9fcb641 | |||
efac23d4af | |||
48dc1c38f7 | |||
ffb3e2b47a | |||
ef816c0a52 | |||
3e35bc38e2 | |||
de0741f727 | |||
6fd4b9f1e2 | |||
6c8a1a5b80 | |||
3842ee15cf | |||
6c71b443e8 | |||
4a4900e5e7 | |||
26d4169fea | |||
7d88a8b315 | |||
41592a04b7 | |||
1d4bafb6ff | |||
28996f561f | |||
0658c0851b | |||
0df2064802 | |||
6543d96910 | |||
0bf5ab76fb | |||
8e1394bf53 | |||
6ddbdc9dc1 | |||
2a8be527d7 | |||
aca1422fca | |||
b0d0932ed9 | |||
fd5557861b | |||
1de7c5b114 | |||
2fb580db26 | |||
e5ca22a9a6 | |||
69ddaacc28 | |||
897a31e608 | |||
4943ff9dfc | |||
e36b38939c | |||
ecb3f9aeac | |||
f0696f77ef | |||
6813838754 | |||
65fe19ca71 | |||
a4f5cab12d | |||
29e06e30b2 | |||
3939e2d9dd | |||
2579438b84 | |||
95d42b9907 | |||
2eb6e075ae | |||
8f928915d9 | |||
3af8cf48b2 | |||
21c03670b6 | |||
0c868b16b6 | |||
1e67360048 | |||
3520dafd29 | |||
857b63ba8f | |||
9551e5b8e5 | |||
c7f15a556d | |||
efca9f0450 | |||
d728154e87 | |||
2e1a167bed | |||
6f6e3aaa21 | |||
9c65a2b890 | |||
beb5bf6dda | |||
7a5e5773b7 | |||
f1b0a4f1de | |||
751345c736 | |||
e850f34d76 | |||
8d7c65585c | |||
96f6362117 | |||
66c768d453 | |||
6fe7763db9 | |||
fda97decaa | |||
b3f44562e9 | |||
51350be190 | |||
7f4b5d282e | |||
94feecd44b | |||
45b02d92d4 | |||
fe4b5498e6 | |||
98b36fd73e | |||
07c7048433 | |||
f09cf92197 | |||
98eba11da5 | |||
a6c1e02847 | |||
b04cee12ea | |||
c4966404bb | |||
579c508761 | |||
43959bccb1 | |||
e6bd12dc2f | |||
7daca754b1 | |||
cb90e30bcf | |||
71d11c73f0 | |||
24116ba846 | |||
a0683dbb0f | |||
b6811b643c | |||
4d2549b50a | |||
1fb3274f37 | |||
6772a69c55 | |||
266a253c03 | |||
c62e1abf2f | |||
55f405f5c2 | |||
8fbd0e58f0 | |||
418d099a2e | |||
9d2eb5e911 | |||
b6c1124d50 | |||
03fda936a8 | |||
684fd46d09 | |||
90fc649441 | |||
0410df77aa | |||
0f30467f62 | |||
a84910f04c | |||
3ee225caec | |||
f963dbd10d | |||
debfbf0d93 | |||
5c37d298a6 | |||
3ca162f23f | |||
5f48433c95 | |||
33352638a9 | |||
db52501462 | |||
3a0cbd1cd4 | |||
1bdb68b7da | |||
6ce728169e | |||
06a3c7c478 | |||
70982c145b | |||
417f2d8998 | |||
7339c4ac2f | |||
43a0ede9d2 | |||
c747c7d025 | |||
c9e2e8980f | |||
9a956692de | |||
d30a6b60b7 | |||
41873bb115 | |||
8064152777 | |||
872df446bd | |||
376a615634 | |||
c16c9efdf3 | |||
c3cc6f9880 | |||
1e139743b8 | |||
bde0ba1100 | |||
50f273c041 | |||
db095f9705 | |||
f580f27ec7 | |||
a46029c0f6 | |||
1a615591e2 | |||
d19683b7dd | |||
f17b3b2a3b | |||
a0a2ea01bc | |||
5132ab6cd9 | |||
256bdf2581 | |||
8a3f8b4706 | |||
7264ce43ae | |||
66e475cbb8 | |||
1e896efff9 | |||
4db7a7e57f | |||
54b23968e7 | |||
bcb080e2b9 | |||
e5c58f9b04 | |||
af7aef70db | |||
3ea72a0bf9 | |||
be02fbb352 | |||
a67f7e3930 | |||
965c19375f | |||
63edcb8934 | |||
e7a012d69a | |||
99c55ac889 | |||
f14adf5827 | |||
c64b9ad63a | |||
dda71b06ae | |||
3c4dca7fdb | |||
ddbc5cf960 | |||
1edf69892a | |||
f10c2a2df2 | |||
3bbdc5ab5b | |||
082e3404c3 | |||
547833ae23 | |||
6e1df36188 | |||
329fe7d844 | |||
b7aaf54a6f | |||
6332814a04 | |||
9d4818d360 | |||
36f3accf4b | |||
8d08840ea4 | |||
7f0d0c9d63 | |||
bf55f03a3e | |||
a5c3fbdd7a | |||
a8bf2191b9 | |||
0688a86f57 | |||
2e11e448dd | |||
8bf275cb8b | |||
1896576a24 | |||
8f811c29d7 | |||
3a4f79629c | |||
375243860e | |||
a842a5319f | |||
c2b0f6af22 | |||
6490d99ac2 | |||
e0b063ac85 | |||
12ac2f4ac7 | |||
cc1951c7ba | |||
0e538ee51d | |||
1b4b832c8c | |||
4f8e4f0522 | |||
0ee78d2416 | |||
4c46087ffc | |||
bb3e72ea4b | |||
914e4c9a72 | |||
9fd7312629 | |||
24387d1efe | |||
3853938ef3 | |||
4ec8416f9a | |||
8aff793a4f | |||
d93ded9047 | |||
fbd04b0fe7 | |||
953f45c50f | |||
1822abc862 | |||
92e966686e | |||
3f50f88e2c | |||
532600ab67 | |||
78f8fe602c | |||
e75fbd7fb4 | |||
06f605879a | |||
4c7038f941 | |||
4bd4d42b82 | |||
f5ebfc3418 | |||
4ae278686c | |||
740786c99e | |||
6abf880e44 | |||
853411fa4f | |||
6e30d23254 | |||
717b36a983 | |||
90eed14cd6 | |||
4452e6ac93 | |||
56f1a6ba37 | |||
8c47a338df | |||
7c6535283e | |||
c669819bbb | |||
50f3231629 | |||
015cde2169 | |||
b9b50dd5dc | |||
da3640357c | |||
0004e7429f | |||
e2e6b7516a | |||
b903161a5d | |||
99fe63b2a3 | |||
dbc180315e | |||
45983acc0d | |||
a02af1053f | |||
7de88b9040 | |||
58327d0514 | |||
db31d13f96 | |||
55d0684565 | |||
7e3cd24444 | |||
2088a43c56 |
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -33,4 +33,8 @@ Requires translations:
|
||||
-->
|
||||
|
||||
## Tests
|
||||
<!-- Attach scripts or actions to test this pull request, as well as the result -->
|
||||
<!--
|
||||
Details should be provided of tests done. Simply saying "tested" or equivalent is not acceptable.
|
||||
|
||||
Attach scripts or actions to test this pull request, as well as the result
|
||||
-->
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,8 +1,9 @@
|
||||
players/*
|
||||
worlds/*
|
||||
plugins/*
|
||||
bin/*
|
||||
bin*/*
|
||||
timings/*
|
||||
crashdumps/*
|
||||
*.log
|
||||
*.txt
|
||||
*.phar
|
||||
|
@ -8,7 +8,7 @@ before_script:
|
||||
- echo | pecl install channel://pecl.php.net/yaml-2.0.2
|
||||
- git clone https://github.com/krakjoe/pthreads.git
|
||||
- cd pthreads
|
||||
- git checkout 6c6b15138c923b69cfa46ee05fc2dd45da587287
|
||||
- git checkout d32079fb4a88e6e008104d36dbbf0c2dd7deb403
|
||||
- phpize
|
||||
- ./configure
|
||||
- make
|
||||
|
@ -5,58 +5,48 @@
|
||||
|
||||
## Creating an Issue
|
||||
- If you are reporting a bug:
|
||||
- **make sure that you are using the latest supported version** before opening an issue.
|
||||
- **test it on a clean test server, WITHOUT PLUGINS**, to see if the issue still occurs. If not then it may be a plugin issue. Please also indicate the result of such tests.
|
||||
|
||||
- [Search the issue tracker](https://github.com/pmmp/PocketMine-MP/issues?utf8=%E2%9C%93&q=is%3Aissue) to check if anyone has already reported it, to avoid needlessly creating duplicate issues. Make sure you also check closed issues, as an issue you think is valid may already have been resolved.
|
||||
|
||||
- If your issue is related to a plugin, **do not report here, contact the plugin's original author** instead.
|
||||
|
||||
- **make sure that you are using the latest supported version** before opening an issue.
|
||||
- **test it on a clean test server, WITHOUT PLUGINS**, to see if the issue still occurs. If not then it may be a plugin issue. Please also indicate the result of such tests.
|
||||
- **[Search the issue tracker](https://github.com/pmmp/PocketMine-MP/issues?utf8=%E2%9C%93&q=is%3Aissue)** to check if anyone has already reported it, to avoid needlessly creating duplicate issues. Make sure you also check closed issues, as an issue you think is valid may already have been resolved.
|
||||
- **Do not report plugin issues here.** If your issue is related to a plugin, contact the plugin's original author instead.
|
||||
- **Support requests are not bugs.** Issues such as "How do I do this" are not bugs and will be closed. If you need help, please see [here](README.md#discussion) and do not misuse our issue tracker.
|
||||
|
||||
- **No generic titles** such as "Question", "Help", "Crash Report" etc. A good issue report provides a quick summary in the title. If you just got a crash report but you don't understand it, please look for a line starting with `Message`. It summarizes the bug.
|
||||
|
||||
- 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**.
|
||||
<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.
|
||||
|
||||
- **Provide information in the issue body, not in the title.** No tags like `[BUG]` are allowed in the title, including `[SOLVED]` for solved issues.
|
||||
- **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>Valid issue reports must include instructions how to reproduce the issue or a crashdump/backtrace (unless the cause of the issue is obvious).
|
||||
<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>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.
|
||||
|
||||
- If your issue is related to the PocketMine-MP website, forums, etc., please [talk to a human directly](README.md#discussion).
|
||||
|
||||
|
||||
|
||||
## Contributing Code
|
||||
- To contribute code to the repository, [fork it on GitHub](https://github.com/pmmp/PocketMine-MP/fork), create a branch on your fork, and make your changes on your fork. You can then make a [pull request](https://github.com/pmmp/PocketMine-MP/pull/new) to the project to compare your branch to ours and propose your changes to our repository. We use the Pull Request system to allow members of the team to review changes before they are merged.
|
||||
## Contributing
|
||||
To contribute to the repository, [fork it on GitHub](https://github.com/pmmp/PocketMine-MP/fork), create a branch on your fork, and make your changes on your fork. You can then make a [pull request](https://github.com/pmmp/PocketMine-MP/pull/new) to the project to compare your branch to ours and propose your changes to our repository. We use the Pull Request system to allow members of the team to review changes before they are merged.
|
||||
|
||||
- By proposing a pull request to the project, you agree to your code being distributed within PocketMine-MP under the [LGPL license](LICENSE).
|
||||
### Licensing
|
||||
By proposing a pull request to the project, you agree to your code being distributed within PocketMine-MP under the [LGPL license](LICENSE).
|
||||
|
||||
- At PocketMine, **we enforce a very high standard for contributions**. This is because PocketMine-MP and its related projects are used very widely in production. While this might seem like we are being mean at times, **our priority is what is best for PocketMine-MP itself**. We try to ensure that our project's codebase is as clean as possible and ensure that only top-quality material makes it through to PocketMine-MP itself. **If a contribution does not live up to our standards, changes may be requested or the pull request may be closed.**
|
||||
|
||||
- **Your pull request will be checked and discussed in due time.** Since the team is scattered all around the world, your PR may not receive any attention for some time.
|
||||
|
||||
- **Avoid using GitHub Web Editor**. The web editor lacks most useful GIT features and **should only be used for very minor changes**. It is immediately clear if the web editor has been used, and if so the PR is more likely to be rejected. If you want to make serious contributions, **please learn how to use [GIT version control](https://git-scm.com/)**.
|
||||
|
||||
- **Do not copy-paste code**. There are potential license issues implicit with copy-pasting, and copy-paste usually indicates a lack of understanding of the actual code. Copy-pasted code is obvious a mile off and **any PR like this is likely to be closed**. If you want to use somebody else's code from a Git repository, **use [GIT's cherry-pick feature](https://git-scm.com/docs/git-cherry-pick)** to cherry-pick the commit. **Cherry-picking is the politer way to copy somebody's changes** and retains all the original accreditation, so there is no need for copy-pasted commits with descriptions like `Some code, thanks @exampleperson`.
|
||||
|
||||
- In addition to the above, **make sure you can explain your changes**. If you can't provide a good explanation of changes, your PR may be rejected.
|
||||
### Contribution standards
|
||||
- **We enforce a very high standard for contributions**. This is because PocketMine-MP and its related projects are used very widely in production. While this might seem like we are being mean at times, **our priority is what is best for PocketMine-MP itself**.
|
||||
We try to ensure that our project's codebase is as clean as possible and ensure that only top-quality material makes it through to PocketMine-MP itself.
|
||||
- **If a contribution does not meet our standards, changes may be requested or the pull request may be closed.**
|
||||
|
||||
### Pull requests
|
||||
- **Create a new branch for each pull request.** Do not create a pull request with commits that exist in another pull request.
|
||||
|
||||
- **Code should use the same style as in PocketMine-MP.** See [below](#code-syntax) for an example.
|
||||
|
||||
- **The code must be clear** and written in English, comments included.
|
||||
|
||||
- **Use descriptive commit titles.** You can see an example [here](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||
|
||||
- **Try to stick to one change per commit.** This ensures that if you create a PR with several changes, we can decide which ones we wish to include and which ones not to include.
|
||||
|
||||
- **It is inadvisable to create pull requests with large commits** unless this has been discussed with the team beforehand. Large pull requests are difficult to review, and such pull requests may end up being closed. The only exception is when all features in the pull request are related to each other, and share the same core changes.
|
||||
|
||||
- **Do not include multiple unrelated changes in one commit.** An atomic style for commits is preferred - this means that changes included in a commit should be part of a single distinct change set. See [this link](https://www.freshconsulting.com/atomic-commits/) for more information on atomic commits. See the [documentation on `git add`](https://git-scm.com/docs/git-add) for information on how to isolate local changes for committing.
|
||||
- **Your pull request will be checked and discussed in due time.** Since the team is scattered all around the world, your PR may not receive any attention for some time.
|
||||
- **It is inadvisable to create large pull requests with lots of changes** unless this has been discussed with the team beforehand. Large pull requests are difficult to review, and such pull requests may end up being closed. The only exception is when all features in the pull request are related to each other, and share the same core changes.
|
||||
- **You may be asked to rebase your pull request** if the branch becomes outdated and/or if possibly conflicting changes are made to the target branch. To see how to do this, read [this page](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request).
|
||||
- **Details should be provided of tests done.** Simply saying "Tested" or equivalent is not acceptable.
|
||||
|
||||
### Code contributions
|
||||
- **Avoid using GitHub Web Editor**. The web editor lacks most useful GIT features and **should only be used for very minor changes**. It is immediately clear if the web editor has been used, and if so the PR is more likely to be rejected. If you want to make serious contributions, **please learn how to use [GIT version control](https://git-scm.com/)**.
|
||||
- **Do not copy-paste code**. There are potential license issues implicit with copy-pasting, and copy-paste usually indicates a lack of understanding of the actual code. Copy-pasted code is obvious a mile off and **any PR like this is likely to be closed**. If you want to use somebody else's code from a Git repository, **use [GIT's cherry-pick feature](https://git-scm.com/docs/git-cherry-pick)** to cherry-pick the commit. **Cherry-picking is the politer way to copy somebody's changes** and retains all the original accreditation, so there is no need for copy-pasted commits with descriptions like `Some code, thanks @exampleperson`.
|
||||
- **Make sure you can explain your changes**. If you can't provide a good explanation of changes, your PR may be rejected.
|
||||
- **Code should use the same style as in PocketMine-MP.** See [below](#code-syntax) for an example.
|
||||
- **The code must be clear** and written in English, comments included.
|
||||
|
||||
|
||||
**Thanks for contributing to PocketMine-MP!**
|
||||
@ -78,17 +68,18 @@ It is mainly [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accept
|
||||
- Strings SHOULD use the double quote `"` except when the single quote is required.
|
||||
- All code SHOULD have parameter and type declarations where possible.
|
||||
- Strict types SHOULD be enabled on new files where it is sensible to do so.
|
||||
- All constant declarations SHOULD be preceded by a visibility modifier.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
declare(strict_types = 1);
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\example;
|
||||
|
||||
class ExampleClass{
|
||||
|
||||
const EXAMPLE_CLASS_CONSTANT = 1;
|
||||
public const EXAMPLE_CLASS_CONSTANT = 1;
|
||||
|
||||
public $examplePublicVariable = "defaultValue";
|
||||
private $examplePrivateVariable;
|
||||
@ -99,7 +90,7 @@ class ExampleClass{
|
||||
* @param string $firstArgument the first argument
|
||||
* @param string|null $secondArgument default null
|
||||
*/
|
||||
public function __construct(string $firstArgument, &$secondArgument = null){
|
||||
public function __construct(string $firstArgument, ?string &$secondArgument = null){
|
||||
if($firstArgument === "exampleValue"){ //Remember to use === instead of == when possible
|
||||
//do things
|
||||
}elseif($firstArgument === "otherValue"){
|
||||
@ -119,7 +110,6 @@ class ExampleClass{
|
||||
public function doStuff(string $stuff) : string{
|
||||
return $stuff;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@ -133,4 +123,4 @@ class ExampleClass{
|
||||
* After voting has been closed, no further votes will be counted.
|
||||
* An RFC will be rejected if less than 50% + 1 (simple majority) has voted Yes.
|
||||
* If the RFC is approved, Team Members have the final word on its implementation or rejection.
|
||||
* RFCs with complex voting options will specify the vote percentage or other details.
|
||||
* RFCs with complex voting options will specify the vote percentage or other details.
|
||||
|
@ -10,7 +10,6 @@ If you don't find what you're looking for there, [talk to a human](#discussion).
|
||||
|
||||
### Discussion
|
||||
- [Forums](https://forums.pmmp.io/)
|
||||
- [#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 [Poggit](https://poggit.pmmp.io), or just search GitHub.
|
||||
@ -23,7 +22,10 @@ There are a very wide range of already-written plugins available which you can u
|
||||
Yes you can! Contributions are welcomed provided that they comply with our [Contributing Guidelines](CONTRIBUTING.md). Please ensure you read the relevant sections of the guidelines carefully before making a Pull Request or opening an Issue.
|
||||
|
||||
### Where can I get the latest .phar?
|
||||
Head over to our [official Jenkins server](https://jenkins.pmmp.io/)
|
||||
- Latest release builds can be found in our [GitHub releases](https://github.com/pmmp/PocketMine-MP/releases).
|
||||
- Latest bleeding-edge development builds (and other builds in the build job channels) can be found on our [Jenkins server](https://jenkins.pmmp.io/).
|
||||
|
||||
**Note: Please avoid development builds unless there is no other alternative for what you need.** Development builds are subject to changes at any time without notice, and it is likely that your server or plugins might break without warning.
|
||||
|
||||
## Third-party Libraries/Protocols Used
|
||||
* __[PHP Sockets](http://php.net/manual/en/book.sockets.php)__
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "pmmp/pocketmine-mp",
|
||||
"name": "pocketmine/pocketmine-mp",
|
||||
"description": "A server software for Minecraft: Pocket Edition written in PHP",
|
||||
"type": "project",
|
||||
"homepage": "https://pmmp.io",
|
||||
@ -21,8 +21,10 @@
|
||||
"ext-yaml": ">=2.0.0",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": ">=1.2.11",
|
||||
"pmmp/raklib": "dev-master#29ab14d5d8640a8ee359ce315b083a129e72db4a",
|
||||
"pmmp/pocketmine-spl": "^0.1.0"
|
||||
"pocketmine/raklib": "dev-master#eaa85c2b23bbc1a85030a621d4644c0e33e05950",
|
||||
"pocketmine/pocketmine-spl": "^0.2.0",
|
||||
"pocketmine/pocketmine-binaryutils": "dev-master#a7cd5303a3b215d26bf9be76682ce9311f40e887",
|
||||
"pocketmine/pocketmine-nbt": "dev-master#f8934c0aed90d1f55452588f7ebef7c4519518a5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
@ -37,6 +39,14 @@
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/PocketMine-SPL"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/PocketMine-BinaryUtils"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/pmmp/PocketMine-NBT"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
100
composer.lock
generated
100
composer.lock
generated
@ -4,20 +4,87 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "169d2724a6847e704f3bb76030bebc87",
|
||||
"content-hash": "5997f272811ed1148e7699a33335a0d2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "pmmp/pocketmine-spl",
|
||||
"version": "0.1.0",
|
||||
"name": "pocketmine/pocketmine-binaryutils",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/PocketMine-SPL.git",
|
||||
"reference": "c56936e6aaad925bb60002b29b1c70f497af4679"
|
||||
"url": "https://github.com/pmmp/PocketMine-BinaryUtils.git",
|
||||
"reference": "a7cd5303a3b215d26bf9be76682ce9311f40e887"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/PocketMine-SPL/zipball/c56936e6aaad925bb60002b29b1c70f497af4679",
|
||||
"reference": "c56936e6aaad925bb60002b29b1c70f497af4679",
|
||||
"url": "https://api.github.com/repos/pmmp/PocketMine-BinaryUtils/zipball/a7cd5303a3b215d26bf9be76682ce9311f40e887",
|
||||
"reference": "a7cd5303a3b215d26bf9be76682ce9311f40e887",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"pocketmine\\utils\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "Classes and methods for conveniently handling binary data",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/PocketMine-BinaryUtils/tree/master",
|
||||
"issues": "https://github.com/pmmp/PocketMine-BinaryUtils/issues"
|
||||
},
|
||||
"time": "2018-01-14T18:53:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/pocketmine-nbt",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/PocketMine-NBT.git",
|
||||
"reference": "f8934c0aed90d1f55452588f7ebef7c4519518a5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/PocketMine-NBT/zipball/f8934c0aed90d1f55452588f7ebef7c4519518a5",
|
||||
"reference": "f8934c0aed90d1f55452588f7ebef7c4519518a5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.0",
|
||||
"pocketmine/pocketmine-binaryutils": "dev-master#8bb34e771fee69abcc5482d17d2fa0b4f0e15a5e"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"pocketmine\\nbt\\": "src/"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"LGPL-3.0"
|
||||
],
|
||||
"description": "PHP library for working with Named Binary Tags",
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/PocketMine-NBT/tree/master",
|
||||
"issues": "https://github.com/pmmp/PocketMine-NBT/issues"
|
||||
},
|
||||
"time": "2018-01-11T13:51:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/pocketmine-spl",
|
||||
"version": "0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/PocketMine-SPL.git",
|
||||
"reference": "70c591a44b6c5aa541a1a55585764bed2b23148c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/PocketMine-SPL/zipball/70c591a44b6c5aa541a1a55585764bed2b23148c",
|
||||
"reference": "70c591a44b6c5aa541a1a55585764bed2b23148c",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -36,20 +103,20 @@
|
||||
"support": {
|
||||
"source": "https://github.com/pmmp/PocketMine-SPL/tree/master"
|
||||
},
|
||||
"time": "2017-12-10T12:18:30+00:00"
|
||||
"time": "2018-01-11T13:03:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pmmp/raklib",
|
||||
"name": "pocketmine/raklib",
|
||||
"version": "dev-master",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/RakLib.git",
|
||||
"reference": "29ab14d5d8640a8ee359ce315b083a129e72db4a"
|
||||
"reference": "eaa85c2b23bbc1a85030a621d4644c0e33e05950"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/29ab14d5d8640a8ee359ce315b083a129e72db4a",
|
||||
"reference": "29ab14d5d8640a8ee359ce315b083a129e72db4a",
|
||||
"url": "https://api.github.com/repos/pmmp/RakLib/zipball/eaa85c2b23bbc1a85030a621d4644c0e33e05950",
|
||||
"reference": "eaa85c2b23bbc1a85030a621d4644c0e33e05950",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -57,7 +124,8 @@
|
||||
"ext-pthreads": ">=3.1.7dev",
|
||||
"ext-sockets": "*",
|
||||
"php": ">=7.2.0RC3",
|
||||
"pmmp/pocketmine-spl": "^0.1.0"
|
||||
"pocketmine/pocketmine-binaryutils": "dev-master#a7cd5303a3b215d26bf9be76682ce9311f40e887",
|
||||
"pocketmine/pocketmine-spl": "^0.2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -73,7 +141,7 @@
|
||||
"source": "https://github.com/pmmp/RakLib/tree/master",
|
||||
"issues": "https://github.com/pmmp/RakLib/issues"
|
||||
},
|
||||
"time": "2017-12-10T12:24:38+00:00"
|
||||
"time": "2018-01-27T15:38:43+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
@ -82,7 +150,9 @@
|
||||
"stability-flags": {
|
||||
"php": 5,
|
||||
"ext-pthreads": 20,
|
||||
"pmmp/raklib": 20
|
||||
"pocketmine/raklib": 20,
|
||||
"pocketmine/pocketmine-binaryutils": 20,
|
||||
"pocketmine/pocketmine-nbt": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
|
@ -186,7 +186,7 @@ class CrashDump{
|
||||
$this->addLine("Line: " . $error["line"]);
|
||||
$this->addLine("Type: " . $error["type"]);
|
||||
|
||||
if(strpos($error["file"], "src/pocketmine/") === false and strpos($error["file"], "src/raklib/") === false and file_exists($error["fullFile"])){
|
||||
if(strpos($error["file"], "src/pocketmine/") === false and strpos($error["file"], "vendor/pocketmine/") === false and file_exists($error["fullFile"])){
|
||||
$this->addLine();
|
||||
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
|
||||
$this->data["plugin"] = true;
|
||||
@ -257,4 +257,4 @@ class CrashDump{
|
||||
fwrite($this->fp, $str);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ class MemoryManager{
|
||||
*/
|
||||
public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){
|
||||
MainLogger::getLogger()->notice("[Dump] After the memory dump is done, the server might crash");
|
||||
self::dumpMemory($this->server, $this->server->getLoader(), $outputFolder, $maxNesting, $maxStringSize);
|
||||
self::dumpMemory($this->server, $outputFolder, $maxNesting, $maxStringSize);
|
||||
|
||||
if($this->dumpWorkers){
|
||||
$scheduler = $this->server->getScheduler();
|
||||
@ -278,13 +278,14 @@ class MemoryManager{
|
||||
/**
|
||||
* Static memory dumper accessible from any thread.
|
||||
*
|
||||
* @param mixed $startingObject
|
||||
* @param \ClassLoader $loader
|
||||
* @param string $outputFolder
|
||||
* @param int $maxNesting
|
||||
* @param int $maxStringSize
|
||||
* @param mixed $startingObject
|
||||
* @param string $outputFolder
|
||||
* @param int $maxNesting
|
||||
* @param int $maxStringSize
|
||||
*
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function dumpMemory($startingObject, \ClassLoader $loader, string $outputFolder, int $maxNesting, int $maxStringSize){
|
||||
public static function dumpMemory($startingObject, string $outputFolder, int $maxNesting, int $maxStringSize){
|
||||
$hardLimit = ini_get('memory_limit');
|
||||
ini_set('memory_limit', '-1');
|
||||
gc_disable();
|
||||
@ -306,7 +307,7 @@ class MemoryManager{
|
||||
$staticProperties = [];
|
||||
$staticCount = 0;
|
||||
|
||||
foreach($loader->getClasses() as $className){
|
||||
foreach(get_declared_classes() as $className){
|
||||
$reflection = new \ReflectionClass($className);
|
||||
$staticProperties[$className] = [];
|
||||
foreach($reflection->getProperties() as $property){
|
||||
@ -330,7 +331,7 @@ class MemoryManager{
|
||||
file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
|
||||
MainLogger::getLogger()->info("[Dump] Wrote $staticCount static properties");
|
||||
|
||||
if($GLOBALS !== null){ //This might be null if we're on a different thread
|
||||
if(isset($GLOBALS)){ //This might be null if we're on a different thread
|
||||
$globalVariables = [];
|
||||
$globalCount = 0;
|
||||
|
||||
|
@ -74,12 +74,11 @@ use pocketmine\inventory\BigCraftingGrid;
|
||||
use pocketmine\inventory\CraftingGrid;
|
||||
use pocketmine\inventory\Inventory;
|
||||
use pocketmine\inventory\PlayerCursorInventory;
|
||||
use pocketmine\inventory\PlayerInventory;
|
||||
use pocketmine\inventory\transaction\action\InventoryAction;
|
||||
use pocketmine\inventory\transaction\CraftingTransaction;
|
||||
use pocketmine\inventory\transaction\InventoryTransaction;
|
||||
use pocketmine\item\Consumable;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\WritableBook;
|
||||
use pocketmine\item\WrittenBook;
|
||||
use pocketmine\level\ChunkLoader;
|
||||
@ -89,10 +88,9 @@ use pocketmine\level\Location;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\level\WeakPosition;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector2;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\metadata\MetadataValue;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\NetworkLittleEndianNBTStream;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\DoubleTag;
|
||||
@ -202,15 +200,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
public $spawned = false;
|
||||
public $loggedIn = false;
|
||||
public $gamemode;
|
||||
public $lastBreak;
|
||||
/** @var bool */
|
||||
protected $authenticated = false;
|
||||
/** @var string */
|
||||
protected $xuid = "";
|
||||
|
||||
protected $windowCnt = 2;
|
||||
/** @var \SplObjectStorage<Inventory> */
|
||||
protected $windows;
|
||||
/** @var int[] */
|
||||
protected $windows = [];
|
||||
/** @var Inventory[] */
|
||||
protected $windowIndex = [];
|
||||
/** @var bool[] */
|
||||
@ -281,7 +278,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
protected $flying = false;
|
||||
|
||||
protected $allowMovementCheats = false;
|
||||
protected $allowInstaBreak = false;
|
||||
|
||||
private $needACK = [];
|
||||
|
||||
@ -440,14 +436,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->allowMovementCheats = $value;
|
||||
}
|
||||
|
||||
public function allowInstaBreak() : bool{
|
||||
return $this->allowInstaBreak;
|
||||
}
|
||||
|
||||
public function setAllowInstaBreak(bool $value = true){
|
||||
$this->allowInstaBreak = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
*/
|
||||
@ -526,6 +514,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeCollidedWith() : bool{
|
||||
return !$this->isSpectator();
|
||||
}
|
||||
|
||||
public function resetFallDistance(){
|
||||
parent::resetFallDistance();
|
||||
if($this->inAirTicks !== 0){
|
||||
@ -692,11 +684,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
*/
|
||||
public function __construct(SourceInterface $interface, $clientID, string $ip, int $port){
|
||||
$this->interface = $interface;
|
||||
$this->windows = new \SplObjectStorage();
|
||||
$this->perm = new PermissibleBase($this);
|
||||
$this->namedtag = new CompoundTag();
|
||||
$this->server = Server::getInstance();
|
||||
$this->lastBreak = PHP_INT_MAX;
|
||||
$this->ip = $ip;
|
||||
$this->port = $port;
|
||||
$this->clientID = $clientID;
|
||||
@ -707,13 +697,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->setLevel($this->server->getDefaultLevel());
|
||||
$this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||
|
||||
$this->uuid = null;
|
||||
$this->rawUUID = null;
|
||||
|
||||
$this->creationTime = microtime(true);
|
||||
|
||||
$this->allowMovementCheats = (bool) $this->server->getProperty("player.anti-cheat.allow-movement-cheats", false);
|
||||
$this->allowInstaBreak = (bool) $this->server->getProperty("player.anti-cheat.allow-instabreak", false);
|
||||
|
||||
$this->sessionAdapter = new PlayerNetworkSessionAdapter($this->server, $this);
|
||||
}
|
||||
@ -1166,6 +1152,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return false;
|
||||
}
|
||||
|
||||
$pos = $pos->floor();
|
||||
$b = $this->level->getBlock($pos);
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerBedEnterEvent($this, $b));
|
||||
@ -1179,12 +1166,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
$this->sleeping = clone $pos;
|
||||
|
||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [$pos->x, $pos->y, $pos->z]);
|
||||
$this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, $pos);
|
||||
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, true);
|
||||
|
||||
$this->setSpawn($pos);
|
||||
|
||||
$this->level->sleepTicks = 60;
|
||||
$this->level->setSleepTicks(60);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1198,10 +1185,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $b));
|
||||
|
||||
$this->sleeping = null;
|
||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [0, 0, 0]);
|
||||
$this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null);
|
||||
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false);
|
||||
|
||||
$this->level->sleepTicks = 0;
|
||||
$this->level->setSleepTicks(0);
|
||||
|
||||
$pk = new AnimatePacket();
|
||||
$pk->entityRuntimeId = $this->id;
|
||||
@ -1433,6 +1420,14 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getXpDropAmount() : int{
|
||||
if(!$this->isCreative()){
|
||||
return parent::getXpDropAmount();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function checkGroundState(float $movX, float $movY, float $movZ, float $dx, float $dy, float $dz){
|
||||
if(!$this->onGround or $movY != 0){
|
||||
$bb = clone $this->boundingBox;
|
||||
@ -1660,6 +1655,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
if($this->spawned){
|
||||
$this->processMovement($tickDiff);
|
||||
$this->motionX = $this->motionY = $this->motionZ = 0; //TODO: HACK! (Fixes player knockback being messed up)
|
||||
|
||||
Timings::$timerEntityBaseTick->startTiming();
|
||||
$this->entityBaseTick($tickDiff);
|
||||
@ -1679,7 +1675,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$expectedVelocity = (-$this->gravity) / $this->drag - ((-$this->gravity) / $this->drag) * exp(-$this->drag * ($this->inAirTicks - $this->startAirTicks));
|
||||
$diff = ($this->speed->y - $expectedVelocity) ** 2;
|
||||
|
||||
if(!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){
|
||||
if(!$this->hasEffect(Effect::JUMP) and !$this->hasEffect(Effect::LEVITATION) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()){
|
||||
if($this->inAirTicks < 100){
|
||||
$this->setMotion(new Vector3(0, $expectedVelocity, 0));
|
||||
}elseif($this->kick($this->server->getLanguage()->translateString("kick.reason.cheat", ["%ability.flight"]))){
|
||||
@ -1742,21 +1738,21 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
* Returns whether the player can interact with the specified position. This checks distance and direction.
|
||||
*
|
||||
* @param Vector3 $pos
|
||||
* @param $maxDistance
|
||||
* @param float $maxDiff
|
||||
* @param float $maxDistance
|
||||
* @param float $maxDiff defaults to half of the 3D diagonal width of a block
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canInteract(Vector3 $pos, $maxDistance, float $maxDiff = 0.5) : bool{
|
||||
public function canInteract(Vector3 $pos, float $maxDistance, float $maxDiff = M_SQRT3 / 2) : bool{
|
||||
$eyePos = $this->getPosition()->add(0, $this->getEyeHeight(), 0);
|
||||
if($eyePos->distanceSquared($pos) > $maxDistance ** 2){
|
||||
return false;
|
||||
}
|
||||
|
||||
$dV = $this->getDirectionPlane();
|
||||
$dot = $dV->dot(new Vector2($eyePos->x, $eyePos->z));
|
||||
$dot1 = $dV->dot(new Vector2($pos->x, $pos->z));
|
||||
return ($dot1 - $dot) >= -$maxDiff;
|
||||
$dV = $this->getDirectionVector();
|
||||
$eyeDot = $dV->dot($eyePos);
|
||||
$targetDot = $dV->dot($pos);
|
||||
return ($targetDot - $eyeDot) >= -$maxDiff;
|
||||
}
|
||||
|
||||
protected function initHumanData(){
|
||||
@ -1828,6 +1824,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
$this->setSkin($skin);
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerPreLoginEvent($this, "Plugin reason"));
|
||||
if($ev->isCancelled()){
|
||||
$this->close("", $ev->getKickMessage());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!$this->server->isWhitelisted($this->iusername) and $this->kick("Server is white-listed", false)){
|
||||
return true;
|
||||
}
|
||||
@ -1839,17 +1842,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerPreLoginEvent($this, "Plugin reason"));
|
||||
if($ev->isCancelled()){
|
||||
$this->close("", $ev->getKickMessage());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!$packet->skipVerification){
|
||||
$this->server->getScheduler()->scheduleAsyncTask(new VerifyLoginTask($this, $packet));
|
||||
}else{
|
||||
$this->onVerifyCompleted($packet, true, true);
|
||||
$this->onVerifyCompleted($packet, null, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1862,13 +1858,13 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->sendDataPacket($pk, false, $immediate);
|
||||
}
|
||||
|
||||
public function onVerifyCompleted(LoginPacket $packet, bool $isValid, bool $isAuthenticated) : void{
|
||||
public function onVerifyCompleted(LoginPacket $packet, ?string $error, bool $isAuthenticated) : void{
|
||||
if($this->closed){
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$isValid){
|
||||
$this->close("", "disconnect.loginFailedInfo.invalidSession");
|
||||
if($error !== null){
|
||||
$this->close("", $this->server->getLanguage()->translateString("pocketmine.disconnect.invalidSession", [$error]));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1924,7 +1920,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
if(($level = $this->server->getLevelByName($this->namedtag->getString("Level", "", true))) === null){
|
||||
$this->setLevel($this->server->getDefaultLevel());
|
||||
$this->namedtag->setString("Level", $this->level->getName());
|
||||
$this->namedtag->setString("Level", $this->level->getFolderName());
|
||||
$spawnLocation = $this->level->getSpawnLocation();
|
||||
$this->namedtag->setTag(new ListTag("Pos", [
|
||||
new DoubleTag("", $spawnLocation->x),
|
||||
@ -2078,7 +2074,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->sendData($this);
|
||||
|
||||
$this->inventory->sendContents($this);
|
||||
$this->inventory->sendArmorContents($this);
|
||||
$this->armorInventory->sendContents($this);
|
||||
$this->inventory->sendCreativeContents();
|
||||
$this->inventory->sendHeldItem($this);
|
||||
|
||||
@ -2148,8 +2144,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->isTeleporting = false;
|
||||
}
|
||||
|
||||
$packet->yaw %= 360;
|
||||
$packet->pitch %= 360;
|
||||
$packet->yaw = fmod($packet->yaw, 360);
|
||||
$packet->pitch = fmod($packet->pitch, 360);
|
||||
|
||||
if($packet->yaw < 0){
|
||||
$packet->yaw += 360;
|
||||
@ -2164,7 +2160,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool{
|
||||
//TODO: add events so plugins can change this
|
||||
$this->getLevel()->addChunkPacket($this->chunk->getX(), $this->chunk->getZ(), $packet);
|
||||
if($this->chunk !== null){
|
||||
$this->getLevel()->addChunkPacket($this->chunk->getX(), $this->chunk->getZ(), $packet);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2245,6 +2243,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
switch($packet->transactionType){
|
||||
case InventoryTransactionPacket::TYPE_NORMAL:
|
||||
$this->setUsingItem(false);
|
||||
$transaction = new InventoryTransaction($this, $actions);
|
||||
|
||||
if(!$transaction->execute()){
|
||||
@ -2260,6 +2259,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
if(count($packet->actions) > 0){
|
||||
$this->server->getLogger()->debug("Expected 0 actions for mismatch, got " . count($packet->actions) . ", " . json_encode($packet->actions));
|
||||
}
|
||||
$this->setUsingItem(false);
|
||||
$this->sendAllInventories();
|
||||
|
||||
return true;
|
||||
@ -2314,7 +2314,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$item = $this->inventory->getItemInHand();
|
||||
$oldItem = clone $item;
|
||||
|
||||
if($this->canInteract($blockVector->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 6) and $this->level->useBreakOn($blockVector, $item, $this, true)){
|
||||
if($this->canInteract($blockVector->add(0.5, 0.5, 0.5), $this->isCreative() ? 13 : 7) and $this->level->useBreakOn($blockVector, $item, $this, true)){
|
||||
if($this->isSurvival()){
|
||||
if(!$item->equalsExact($oldItem)){
|
||||
$this->inventory->setItemInHand($item);
|
||||
@ -2399,34 +2399,18 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
|
||||
$cancelled = false;
|
||||
if($target instanceof Player and $this->server->getConfigBool("pvp", true) === false){
|
||||
$cancelled = true;
|
||||
}
|
||||
|
||||
$heldItem = $this->inventory->getItemInHand();
|
||||
|
||||
$damage = [
|
||||
EntityDamageEvent::MODIFIER_BASE => $heldItem->getAttackPoints()
|
||||
];
|
||||
|
||||
if(!$this->canInteract($target, 8)){
|
||||
$cancelled = true;
|
||||
}elseif($target instanceof Player){
|
||||
if(($target->getGamemode() & 0x01) > 0){
|
||||
return true;
|
||||
}elseif($this->server->getConfigBool("pvp") !== true){
|
||||
if($this->server->getConfigBool("pvp") !== true){
|
||||
$cancelled = true;
|
||||
}
|
||||
|
||||
$points = 0;
|
||||
foreach($target->getInventory()->getArmorContents() as $armorItem){
|
||||
$points += $armorItem->getDefensePoints();
|
||||
}
|
||||
|
||||
$damage[EntityDamageEvent::MODIFIER_ARMOR] = -($damage[EntityDamageEvent::MODIFIER_BASE] * $points * 0.04);
|
||||
}
|
||||
|
||||
$ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $damage);
|
||||
$ev = new EntityDamageByEntityEvent($this, $target, EntityDamageEvent::CAUSE_ENTITY_ATTACK, $heldItem->getAttackPoints());
|
||||
if($cancelled){
|
||||
$ev->setCancelled();
|
||||
}
|
||||
@ -2465,52 +2449,40 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->inventory->setItemInHand($item);
|
||||
}
|
||||
}else{
|
||||
$this->inventory->sendContents($this);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
case InventoryTransactionPacket::RELEASE_ITEM_ACTION_CONSUME:
|
||||
$slot = $this->inventory->getItemInHand();
|
||||
|
||||
if($slot->canBeConsumed()){
|
||||
if($slot instanceof Consumable){
|
||||
$ev = new PlayerItemConsumeEvent($this, $slot);
|
||||
if(!$slot->canBeConsumedBy($this)){
|
||||
$ev->setCancelled();
|
||||
}
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
if(!$ev->isCancelled()){
|
||||
$slot->onConsume($this);
|
||||
}else{
|
||||
$this->inventory->sendContents($this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}elseif($slot->getId() === Item::BUCKET and $slot->getDamage() === 1){ //Milk!
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerItemConsumeEvent($this, $slot));
|
||||
if($ev->isCancelled()){
|
||||
if($ev->isCancelled() or !$this->consumeObject($slot)){
|
||||
$this->inventory->sendContents($this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if($this->isSurvival()){
|
||||
--$slot->count;
|
||||
$slot->pop();
|
||||
$this->inventory->setItemInHand($slot);
|
||||
$this->inventory->addItem(ItemFactory::get(Item::BUCKET, 0, 1));
|
||||
$this->inventory->addItem($slot->getResidue());
|
||||
}
|
||||
|
||||
$this->removeAllEffects();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}finally{
|
||||
$this->setUsingItem(false);
|
||||
}
|
||||
|
||||
$this->inventory->sendContents($this);
|
||||
break;
|
||||
default:
|
||||
$this->inventory->sendContents($this);
|
||||
@ -2606,7 +2578,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
switch($packet->action){
|
||||
case PlayerActionPacket::ACTION_START_BREAK:
|
||||
if($this->lastBreak !== PHP_INT_MAX or $pos->distanceSquared($this) > 10000){
|
||||
if($pos->distanceSquared($this) > 10000){
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2636,12 +2608,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_START_BREAK, (int) (65535 / $breakTime));
|
||||
}
|
||||
}
|
||||
$this->lastBreak = microtime(true);
|
||||
|
||||
break;
|
||||
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
case PlayerActionPacket::ACTION_ABORT_BREAK:
|
||||
$this->lastBreak = PHP_INT_MAX;
|
||||
case PlayerActionPacket::ACTION_STOP_BREAK:
|
||||
$this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_BLOCK_STOP_BREAK);
|
||||
break;
|
||||
@ -2661,8 +2631,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
break;
|
||||
}
|
||||
|
||||
$this->resetCraftingGridType();
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $this->getSpawn()));
|
||||
|
||||
$realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getLevel());
|
||||
@ -2698,7 +2666,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
$this->sendSettings();
|
||||
$this->inventory->sendContents($this);
|
||||
$this->inventory->sendArmorContents($this);
|
||||
$this->armorInventory->sendContents($this);
|
||||
|
||||
$this->spawnToAll();
|
||||
$this->scheduleUpdate();
|
||||
@ -2797,8 +2765,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
$this->level->dropItem($this->add(0, 1.3, 0), $item, $motion, 40);
|
||||
|
||||
$this->setUsingItem(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2866,8 +2832,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
|
||||
$t = $this->level->getTile($pos);
|
||||
if($t instanceof Spawnable){
|
||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
||||
$nbt->read($packet->namedtag, false, true);
|
||||
$nbt = new NetworkLittleEndianNBTStream();
|
||||
$nbt->read($packet->namedtag);
|
||||
$nbt = $nbt->getData();
|
||||
if(!$t->updateCompoundTag($nbt, $this)){
|
||||
$t->spawnTo($this);
|
||||
@ -3357,7 +3323,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
|
||||
$this->removeAllWindows(true);
|
||||
$this->windows = null;
|
||||
$this->windows = [];
|
||||
$this->windowIndex = [];
|
||||
$this->cursorInventory = null;
|
||||
$this->craftingGrid = null;
|
||||
@ -3568,6 +3534,10 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
break;
|
||||
}
|
||||
|
||||
//Crafting grid must always be evacuated even if keep-inventory is true. This dumps the contents into the
|
||||
//main inventory and drops the rest on the ground.
|
||||
$this->resetCraftingGridType();
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerDeathEvent($this, $this->getDrops(), new TranslationContainer($message, $params)));
|
||||
|
||||
if(!$ev->getKeepInventory()){
|
||||
@ -3579,6 +3549,9 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->inventory->setHeldItemIndex(0, false); //This is already handled when sending contents, don't send it twice
|
||||
$this->inventory->clearAll();
|
||||
}
|
||||
if($this->armorInventory !== null){
|
||||
$this->armorInventory->clearAll();
|
||||
}
|
||||
}
|
||||
|
||||
if($ev->getDeathMessage() != ""){
|
||||
@ -3594,6 +3567,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return false; //never flag players for despawn
|
||||
}
|
||||
|
||||
protected function applyPostDamageEffects(EntityDamageEvent $source) : void{
|
||||
parent::applyPostDamageEffects($source);
|
||||
|
||||
$this->exhaust(0.3, PlayerExhaustEvent::CAUSE_DAMAGE);
|
||||
}
|
||||
|
||||
public function attack(EntityDamageEvent $source){
|
||||
if(!$this->isAlive()){
|
||||
return;
|
||||
@ -3609,13 +3588,12 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
|
||||
parent::attack($source);
|
||||
}
|
||||
|
||||
if($source->isCancelled()){
|
||||
return;
|
||||
}elseif($this->getLastDamageCause() === $source and $this->spawned){
|
||||
protected function doHitAnimation() : void{
|
||||
parent::doHitAnimation();
|
||||
if($this->spawned){
|
||||
$this->broadcastEntityEvent(EntityEventPacket::HURT_ANIMATION, null, [$this]);
|
||||
|
||||
$this->exhaust(0.3, PlayerExhaustEvent::CAUSE_DAMAGE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3688,6 +3666,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
protected function addDefaultWindows(){
|
||||
$this->addWindow($this->getInventory(), ContainerIds::INVENTORY, true);
|
||||
|
||||
$this->addWindow($this->getArmorInventory(), ContainerIds::ARMOR, true);
|
||||
|
||||
$this->cursorInventory = new PlayerCursorInventory($this);
|
||||
$this->addWindow($this->cursorInventory, ContainerIds::CURSOR, true);
|
||||
|
||||
@ -3735,13 +3715,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
* @return int
|
||||
*/
|
||||
public function getWindowId(Inventory $inventory) : int{
|
||||
if($this->windows->contains($inventory)){
|
||||
/** @var int $id */
|
||||
$id = $this->windows[$inventory];
|
||||
return $id;
|
||||
}
|
||||
|
||||
return ContainerIds::NONE;
|
||||
return $this->windows[spl_object_hash($inventory)] ?? ContainerIds::NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3777,7 +3751,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$cnt = $forceId;
|
||||
}
|
||||
$this->windowIndex[$cnt] = $inventory;
|
||||
$this->windows->attach($inventory, $cnt);
|
||||
$this->windows[spl_object_hash($inventory)] = $cnt;
|
||||
if($inventory->open($this)){
|
||||
if($isPermanent){
|
||||
$this->permanentWindows[$cnt] = true;
|
||||
@ -3799,18 +3773,16 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
* @throws \BadMethodCallException if trying to remove a fixed inventory window without the `force` parameter as true
|
||||
*/
|
||||
public function removeWindow(Inventory $inventory, bool $force = false){
|
||||
if($this->windows->contains($inventory)){
|
||||
/** @var int $id */
|
||||
$id = $this->windows[$inventory];
|
||||
if(!$force and isset($this->permanentWindows[$id])){
|
||||
throw new \BadMethodCallException("Cannot remove fixed window $id (" . get_class($inventory) . ") from " . $this->getName());
|
||||
}
|
||||
$this->windows->detach($this->windowIndex[$id]);
|
||||
unset($this->windowIndex[$id]);
|
||||
unset($this->permanentWindows[$id]);
|
||||
$id = $this->windows[$hash = spl_object_hash($inventory)] ?? null;
|
||||
|
||||
if($id !== null and !$force and isset($this->permanentWindows[$id])){
|
||||
throw new \BadMethodCallException("Cannot remove fixed window $id (" . get_class($inventory) . ") from " . $this->getName());
|
||||
}
|
||||
|
||||
$inventory->close($this);
|
||||
if($id !== null){
|
||||
unset($this->windows[$hash], $this->windowIndex[$id], $this->permanentWindows[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3831,9 +3803,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
protected function sendAllInventories(){
|
||||
foreach($this->windowIndex as $id => $inventory){
|
||||
$inventory->sendContents($this);
|
||||
if($inventory instanceof PlayerInventory){
|
||||
$inventory->sendArmorContents($this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ namespace pocketmine {
|
||||
|
||||
const NAME = "PocketMine-MP";
|
||||
const VERSION = "1.7dev";
|
||||
const API_VERSION = "3.0.0-ALPHA10";
|
||||
const API_VERSION = "3.0.0-ALPHA11";
|
||||
const CODENAME = "[REDACTED]";
|
||||
|
||||
const MIN_PHP_VERSION = "7.2.0RC3";
|
||||
@ -157,8 +157,6 @@ namespace pocketmine {
|
||||
* We now use the Composer autoloader, but this autoloader is still for loading plugins.
|
||||
*/
|
||||
$autoloader = new \BaseClassLoader();
|
||||
$autoloader->addPath(\pocketmine\PATH . "src");
|
||||
$autoloader->addPath(\pocketmine\PATH . "src" . DIRECTORY_SEPARATOR . "spl");
|
||||
$autoloader->register(false);
|
||||
|
||||
set_time_limit(0); //Who set it to 30 seconds?!?!
|
||||
@ -175,8 +173,8 @@ namespace pocketmine {
|
||||
|
||||
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-profiler"]);
|
||||
|
||||
define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR);
|
||||
define('pocketmine\PLUGIN_PATH', isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : \getcwd() . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
||||
define('pocketmine\DATA', isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : \realpath(\getcwd()) . DIRECTORY_SEPARATOR);
|
||||
define('pocketmine\PLUGIN_PATH', isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : \realpath(\getcwd()) . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR);
|
||||
|
||||
Terminal::init();
|
||||
|
||||
@ -367,6 +365,10 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
function kill($pid){
|
||||
global $logger;
|
||||
if($logger instanceof MainLogger){
|
||||
$logger->syncFlushBuffer();
|
||||
}
|
||||
switch(Utils::getOS()){
|
||||
case "win":
|
||||
exec("taskkill.exe /F /PID " . ((int) $pid) . " > NUL");
|
||||
@ -493,8 +495,9 @@ namespace pocketmine {
|
||||
"curl" => "cURL",
|
||||
"json" => "JSON",
|
||||
"mbstring" => "Multibyte String",
|
||||
"yaml" => "YAML",
|
||||
"openssl" => "OpenSSL",
|
||||
"sockets" => "Sockets",
|
||||
"yaml" => "YAML",
|
||||
"zip" => "Zip",
|
||||
"zlib" => "Zlib"
|
||||
];
|
||||
@ -532,7 +535,6 @@ namespace pocketmine {
|
||||
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
|
||||
|
||||
|
@ -67,6 +67,7 @@ use pocketmine\level\LevelException;
|
||||
use pocketmine\metadata\EntityMetadataStore;
|
||||
use pocketmine\metadata\LevelMetadataStore;
|
||||
use pocketmine\metadata\PlayerMetadataStore;
|
||||
use pocketmine\nbt\BigEndianNBTStream;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
@ -749,7 +750,7 @@ class Server{
|
||||
if($this->shouldSavePlayerData()){
|
||||
if(file_exists($path . "$name.dat")){
|
||||
try{
|
||||
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||
$nbt = new BigEndianNBTStream();
|
||||
$nbt->readCompressed(file_get_contents($path . "$name.dat"));
|
||||
|
||||
return $nbt->getData();
|
||||
@ -772,8 +773,8 @@ class Server{
|
||||
new DoubleTag("", $spawn->y),
|
||||
new DoubleTag("", $spawn->z)
|
||||
], NBT::TAG_Double),
|
||||
new StringTag("Level", $this->getDefaultLevel()->getName()),
|
||||
//new StringTag("SpawnLevel", $this->getDefaultLevel()->getName()),
|
||||
new StringTag("Level", $this->getDefaultLevel()->getFolderName()),
|
||||
//new StringTag("SpawnLevel", $this->getDefaultLevel()->getFolderName()),
|
||||
//new IntTag("SpawnX", (int) $spawn->x),
|
||||
//new IntTag("SpawnY", (int) $spawn->y),
|
||||
//new IntTag("SpawnZ", (int) $spawn->z),
|
||||
@ -815,7 +816,7 @@ class Server{
|
||||
$this->pluginManager->callEvent($ev);
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||
$nbt = new BigEndianNBTStream();
|
||||
try{
|
||||
$nbt->setData($ev->getSaveData());
|
||||
|
||||
@ -1101,8 +1102,9 @@ class Server{
|
||||
|
||||
$this->getLogger()->notice($this->getLanguage()->translateString("pocketmine.level.backgroundGeneration", [$name]));
|
||||
|
||||
$centerX = $level->getSpawnLocation()->getX() >> 4;
|
||||
$centerZ = $level->getSpawnLocation()->getZ() >> 4;
|
||||
$spawnLocation = $level->getSpawnLocation();
|
||||
$centerX = $spawnLocation->x >> 4;
|
||||
$centerZ = $spawnLocation->z >> 4;
|
||||
|
||||
$order = [];
|
||||
|
||||
@ -1432,6 +1434,9 @@ class Server{
|
||||
* @param string $pluginPath
|
||||
*/
|
||||
public function __construct(\ClassLoader $autoloader, \ThreadedLogger $logger, string $dataPath, string $pluginPath){
|
||||
if(self::$instance !== null){
|
||||
throw new \InvalidStateException("Only one server instance can exist at once");
|
||||
}
|
||||
self::$instance = $this;
|
||||
self::$sleeper = new \Threaded;
|
||||
$this->autoloader = $autoloader;
|
||||
@ -1522,6 +1527,8 @@ class Server{
|
||||
if($processors > 0){
|
||||
$poolSize = max(1, $processors);
|
||||
}
|
||||
}else{
|
||||
$poolSize = (int) $poolSize;
|
||||
}
|
||||
|
||||
ServerScheduler::$WORKERS = $poolSize;
|
||||
@ -1635,7 +1642,7 @@ class Server{
|
||||
Attribute::init();
|
||||
$this->craftingManager = new CraftingManager();
|
||||
|
||||
$this->resourceManager = new ResourcePackManager($this, $this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR);
|
||||
$this->resourceManager = new ResourcePackManager($this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR);
|
||||
|
||||
$this->pluginManager = new PluginManager($this, $this->commandMap);
|
||||
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
|
||||
@ -2089,11 +2096,13 @@ class Server{
|
||||
if($this->network instanceof Network){
|
||||
$this->getLogger()->debug("Stopping network interfaces");
|
||||
foreach($this->network->getInterfaces() as $interface){
|
||||
$this->getLogger()->debug("Stopping network interface " . get_class($interface));
|
||||
$interface->shutdown();
|
||||
$this->network->unregisterInterface($interface);
|
||||
}
|
||||
}
|
||||
|
||||
$this->getLogger()->debug("Collecting cycles");
|
||||
gc_collect_cycles();
|
||||
}catch(\Throwable $e){
|
||||
$this->logger->logException($e);
|
||||
@ -2113,7 +2122,7 @@ class Server{
|
||||
/**
|
||||
* Starts the PocketMine-MP server and starts processing ticks and packets
|
||||
*/
|
||||
public function start(){
|
||||
private function start(){
|
||||
if($this->getConfigBool("enable-query", true) === true){
|
||||
$this->queryHandler = new QueryHandler();
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ abstract class Thread extends \Thread{
|
||||
|
||||
/** @var \ClassLoader */
|
||||
protected $classLoader;
|
||||
/** @var string|null */
|
||||
protected $composerAutoloaderPath;
|
||||
|
||||
protected $isKilled = false;
|
||||
|
||||
public function getClassLoader(){
|
||||
@ -37,6 +40,8 @@ abstract class Thread extends \Thread{
|
||||
}
|
||||
|
||||
public function setClassLoader(\ClassLoader $loader = null){
|
||||
$this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH;
|
||||
|
||||
if($loader === null){
|
||||
$loader = Server::getInstance()->getLoader();
|
||||
}
|
||||
@ -51,10 +56,8 @@ abstract class Thread extends \Thread{
|
||||
* (unless you are using a custom autoloader).
|
||||
*/
|
||||
public function registerClassLoader(){
|
||||
require(\pocketmine\PATH . "vendor/autoload.php");
|
||||
if(!interface_exists("ClassLoader", false)){
|
||||
require(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||
require(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||
if($this->composerAutoloaderPath !== null){
|
||||
require $this->composerAutoloaderPath;
|
||||
}
|
||||
if($this->classLoader !== null){
|
||||
$this->classLoader->register(false);
|
||||
|
@ -89,4 +89,4 @@ class ThreadManager extends \Volatile{
|
||||
|
||||
return $erroredThreads;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ abstract class Worker extends \Worker{
|
||||
|
||||
/** @var \ClassLoader */
|
||||
protected $classLoader;
|
||||
/** @var string|null */
|
||||
protected $composerAutoloaderPath;
|
||||
|
||||
protected $isKilled = false;
|
||||
|
||||
@ -38,6 +40,8 @@ abstract class Worker extends \Worker{
|
||||
}
|
||||
|
||||
public function setClassLoader(\ClassLoader $loader = null){
|
||||
$this->composerAutoloaderPath = \pocketmine\COMPOSER_AUTOLOADER_PATH;
|
||||
|
||||
if($loader === null){
|
||||
$loader = Server::getInstance()->getLoader();
|
||||
}
|
||||
@ -52,10 +56,8 @@ abstract class Worker extends \Worker{
|
||||
* (unless you are using a custom autoloader).
|
||||
*/
|
||||
public function registerClassLoader(){
|
||||
require(\pocketmine\PATH . "vendor/autoload.php");
|
||||
if(!interface_exists("ClassLoader", false)){
|
||||
require(\pocketmine\PATH . "src/spl/ClassLoader.php");
|
||||
require(\pocketmine\PATH . "src/spl/BaseClassLoader.php");
|
||||
if($this->composerAutoloaderPath !== null){
|
||||
require $this->composerAutoloaderPath;
|
||||
}
|
||||
if($this->classLoader !== null){
|
||||
$this->classLoader->register(false);
|
||||
|
@ -82,4 +82,4 @@ class Air extends Transparent{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\inventory\AnvilInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
@ -65,7 +65,11 @@ class Anvil extends Fallable{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function recalculateBoundingBox() : ?AxisAlignedBB{
|
||||
@ -106,13 +110,9 @@ class Anvil extends Fallable{
|
||||
return $this->getLevel()->setBlock($blockReplace, $this, true, true);
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $this->getDamage() & 0x0c, 1)
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $this->getDamage() & 0x0c)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,25 +190,16 @@ class Bed extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
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, null, $player !== null); //make sure tiles get removed
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if($this->isHeadPart()){
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if($tile instanceof TileBed){
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $tile->getColor(), 1)
|
||||
ItemFactory::get($this->getItemId(), $tile->getColor())
|
||||
];
|
||||
}else{
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), 14, 1) //Red
|
||||
ItemFactory::get($this->getItemId(), 14) //Red
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -216,4 +207,15 @@ class Bed extends Transparent{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getAffectedBlocks() : array{
|
||||
if(($other = $this->getOtherHalf()) !== null){
|
||||
return [$this, $other];
|
||||
}
|
||||
|
||||
return parent::getAffectedBlocks();
|
||||
}
|
||||
}
|
||||
|
@ -49,4 +49,4 @@ class Bedrock extends Solid{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -38,20 +38,20 @@ class Beetroot extends Crops{
|
||||
return "Beetroot Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if($this->meta >= 0x07){
|
||||
return [
|
||||
ItemFactory::get(Item::BEETROOT, 0, 1),
|
||||
ItemFactory::get(Item::BEETROOT),
|
||||
ItemFactory::get(Item::BEETROOT_SEEDS, 0, mt_rand(0, 3))
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
ItemFactory::get(Item::BEETROOT_SEEDS, 0, 1)
|
||||
ItemFactory::get(Item::BEETROOT_SEEDS)
|
||||
];
|
||||
}
|
||||
|
||||
public function getPickedItem() : Item{
|
||||
return ItemFactory::get(Item::BEETROOT_SEEDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,13 +27,13 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\MovingObjectPosition;
|
||||
use pocketmine\level\Position;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\metadata\Metadatable;
|
||||
use pocketmine\metadata\MetadataValue;
|
||||
@ -195,8 +195,49 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeBrokenWith(Item $item) : bool{
|
||||
return $this->getHardness() !== -1;
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the level of tool required to harvest this block (for normal blocks). When the tool type matches the
|
||||
* block's required tool type, the tool must have a harvest level greater than or equal to this value to be able to
|
||||
* successfully harvest the block.
|
||||
*
|
||||
* If the block requires a specific minimum tier of tiered tool, the minimum tier required should be returned.
|
||||
* Otherwise, 1 should be returned if a tool is required, 0 if not.
|
||||
*
|
||||
* @see Item::getBlockToolHarvestLevel()
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getToolHarvestLevel() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the specified item is the proper tool to use for breaking this block. This checks tool type and
|
||||
* harvest level requirement.
|
||||
*
|
||||
* In most cases this is also used to determine whether block drops should be created or not, except in some
|
||||
* special cases such as vines.
|
||||
*
|
||||
* @param Item $tool
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCompatibleWithTool(Item $tool) : bool{
|
||||
if($this->getHardness() < 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
$toolType = $this->getToolType();
|
||||
$harvestLevel = $this->getToolHarvestLevel();
|
||||
return $toolType === BlockToolType::TYPE_NONE or $harvestLevel === 0 or (
|
||||
($toolType & $tool->getBlockToolType()) !== 0 and $tool->getBlockToolHarvestLevel() >= $harvestLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,41 +261,20 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* @return float
|
||||
*/
|
||||
public function getBreakTime(Item $item) : float{
|
||||
$base = $this->getHardness() * 1.5;
|
||||
if($this->canBeBrokenWith($item)){
|
||||
if($this->getToolType() === Tool::TYPE_SHEARS and $item->isShears()){
|
||||
$base /= 15;
|
||||
}elseif(
|
||||
($this->getToolType() === Tool::TYPE_PICKAXE and ($tier = $item->isPickaxe()) !== false) or
|
||||
($this->getToolType() === Tool::TYPE_AXE and ($tier = $item->isAxe()) !== false) or
|
||||
($this->getToolType() === Tool::TYPE_SHOVEL and ($tier = $item->isShovel()) !== false)
|
||||
){
|
||||
switch($tier){
|
||||
case Tool::TIER_WOODEN:
|
||||
$base /= 2;
|
||||
break;
|
||||
case Tool::TIER_STONE:
|
||||
$base /= 4;
|
||||
break;
|
||||
case Tool::TIER_IRON:
|
||||
$base /= 6;
|
||||
break;
|
||||
case Tool::TIER_DIAMOND:
|
||||
$base /= 8;
|
||||
break;
|
||||
case Tool::TIER_GOLD:
|
||||
$base /= 12;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$base = $this->getHardness();
|
||||
if($this->isCompatibleWithTool($item)){
|
||||
$base *= 1.5;
|
||||
}else{
|
||||
$base *= 3.33;
|
||||
$base *= 5;
|
||||
}
|
||||
|
||||
if($item->isSword()){
|
||||
$base /= 1.5;
|
||||
$efficiency = $item->getMiningEfficiency($this);
|
||||
if($efficiency <= 0){
|
||||
throw new \RuntimeException("Item efficiency is invalid");
|
||||
}
|
||||
|
||||
$base /= $efficiency;
|
||||
|
||||
return $base;
|
||||
}
|
||||
|
||||
@ -315,13 +335,6 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
return $this->getHardness() * 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
@ -420,11 +433,53 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getDrops(Item $item) : array{
|
||||
if($this->isCompatibleWithTool($item)){
|
||||
if($this->isAffectedBySilkTouch() and $item->hasEnchantment(Enchantment::SILK_TOUCH)){
|
||||
return $this->getSilkTouchDrops($item);
|
||||
}
|
||||
|
||||
return $this->getDropsForCompatibleTool($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of Items to be dropped when the block is broken using the correct tool type.
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $this->getVariant(), 1)
|
||||
ItemFactory::get($this->getItemId(), $this->getVariant())
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of Items to be dropped when the block is broken using a compatible Silk Touch-enchanted tool.
|
||||
*
|
||||
* @param Item $item
|
||||
*
|
||||
* @return Item[]
|
||||
*/
|
||||
public function getSilkTouchDrops(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get($this->getItemId(), $this->getVariant())
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether Silk Touch enchanted tools will cause this block to drop as itself. Since most blocks drop
|
||||
* themselves anyway, this is implicitly true.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item that players will equip when middle-clicking on this block.
|
||||
* @return Item
|
||||
@ -486,6 +541,16 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of blocks that this block is part of. In most cases, only contains the block itself, but in cases
|
||||
* such as double plants, beds and doors, will contain both halves.
|
||||
*
|
||||
* @return Block[]
|
||||
*/
|
||||
public function getAffectedBlocks() : array{
|
||||
return [$this];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -578,15 +643,15 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
* @param Vector3 $pos1
|
||||
* @param Vector3 $pos2
|
||||
*
|
||||
* @return MovingObjectPosition|null
|
||||
* @return RayTraceResult|null
|
||||
*/
|
||||
public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?MovingObjectPosition{
|
||||
public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{
|
||||
$bbs = $this->getCollisionBoxes();
|
||||
if(empty($bbs)){
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var MovingObjectPosition|null $currentHit */
|
||||
/** @var RayTraceResult|null $currentHit */
|
||||
$currentHit = null;
|
||||
/** @var int|float $currentDistance */
|
||||
$currentDistance = PHP_INT_MAX;
|
||||
@ -604,12 +669,6 @@ class Block extends Position implements BlockIds, Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
if($currentHit !== null){
|
||||
$currentHit->blockX = $this->x;
|
||||
$currentHit->blockY = $this->y;
|
||||
$currentHit->blockZ = $this->z;
|
||||
}
|
||||
|
||||
return $currentHit;
|
||||
}
|
||||
|
||||
|
@ -417,4 +417,4 @@ class BlockFactory{
|
||||
$b = self::$list[$id];
|
||||
return $b !== null and !($b instanceof UnknownBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,19 +21,19 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\item;
|
||||
namespace pocketmine\block;
|
||||
|
||||
/**
|
||||
* Types of tools that can be used to break blocks
|
||||
* Blocks may allow multiple tool types by combining these bitflags
|
||||
*/
|
||||
interface BlockToolType{
|
||||
|
||||
class DiamondPickaxe extends Tool{
|
||||
public function __construct(int $meta = 0){
|
||||
parent::__construct(self::DIAMOND_PICKAXE, $meta, "Diamond Pickaxe");
|
||||
}
|
||||
public const TYPE_NONE = 0;
|
||||
public const TYPE_SWORD = 1 << 0;
|
||||
public const TYPE_SHOVEL = 1 << 1;
|
||||
public const TYPE_PICKAXE = 1 << 2;
|
||||
public const TYPE_AXE = 1 << 3;
|
||||
public const TYPE_SHEARS = 1 << 4;
|
||||
|
||||
public function isPickaxe(){
|
||||
return Tool::TIER_DIAMOND;
|
||||
}
|
||||
|
||||
public function getAttackPoints() : int{
|
||||
return 6;
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\PillarRotationHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -46,7 +46,11 @@ class BoneBlock extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
@ -57,13 +61,4 @@ class BoneBlock extends Solid{
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x03;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Bookshelf extends Solid{
|
||||
|
||||
@ -44,10 +43,10 @@ class Bookshelf extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::BOOK, 0, 3)
|
||||
];
|
||||
@ -57,4 +56,4 @@ class Bookshelf extends Solid{
|
||||
return 300;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class BrewingStand extends Transparent{
|
||||
|
||||
@ -42,7 +42,11 @@ class BrewingStand extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
@ -50,4 +54,4 @@ class BrewingStand extends Transparent{
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class BrickStairs extends Stair{
|
||||
|
||||
@ -42,11 +42,15 @@ class BrickStairs extends Stair{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Brick Stairs";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Bricks extends Solid{
|
||||
|
||||
@ -43,18 +42,14 @@ class Bricks extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Bricks";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,4 +34,4 @@ class BrownMushroom extends RedMushroom{
|
||||
public function getLightLevel() : int{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ class BrownMushroomBlock extends RedMushroomBlock{
|
||||
return "Brown Mushroom Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
Item::get(Item::BROWN_MUSHROOM, 0, mt_rand(0, 2))
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\Player;
|
||||
@ -35,6 +35,8 @@ class BurningFurnace extends Solid{
|
||||
|
||||
protected $id = self::BURNING_FURNACE;
|
||||
|
||||
protected $itemId = self::FURNACE;
|
||||
|
||||
public function __construct(int $meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
@ -48,7 +50,11 @@ class BurningFurnace extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
@ -90,12 +96,4 @@ class BurningFurnace extends Solid{
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,4 +48,4 @@ abstract class Button extends Flowable{
|
||||
//TODO
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,4 +132,4 @@ class Cactus extends Transparent{
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\event\entity\EntityEatBlockEvent;
|
||||
use pocketmine\entity\Living;
|
||||
use pocketmine\item\FoodSource;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
@ -45,7 +45,7 @@ class Cake extends Transparent implements FoodSource{
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Cake Block";
|
||||
return "Cake";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox() : ?AxisAlignedBB{
|
||||
@ -85,25 +85,18 @@ class Cake extends Transparent implements FoodSource{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if($player !== null){
|
||||
$player->consumeObject($this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -117,6 +110,13 @@ class Cake extends Transparent implements FoodSource{
|
||||
return 0.4;
|
||||
}
|
||||
|
||||
public function requiresHunger() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Block
|
||||
*/
|
||||
public function getResidue(){
|
||||
$clone = clone $this;
|
||||
$clone->meta++;
|
||||
@ -132,4 +132,8 @@ class Cake extends Transparent implements FoodSource{
|
||||
public function getAdditionalEffects() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function onConsume(Living $consumer) : void{
|
||||
$this->level->setBlock($this, $this->getResidue());
|
||||
}
|
||||
}
|
||||
|
@ -85,4 +85,4 @@ class Carpet extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class Carrot extends Crops{
|
||||
return "Carrot Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::CARROT, 0, $this->meta >= 0x07 ? mt_rand(1, 4) : 1)
|
||||
];
|
||||
@ -47,4 +47,4 @@ class Carrot extends Crops{
|
||||
public function getPickedItem() : Item{
|
||||
return ItemFactory::get(Item::CARROT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ 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\tag\StringTag;
|
||||
@ -49,7 +48,7 @@ class Chest extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox() : ?AxisAlignedBB{
|
||||
@ -102,16 +101,6 @@ class Chest extends Transparent{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
$t = $this->getLevel()->getTile($this);
|
||||
if($t instanceof TileChest){
|
||||
$t->unpair();
|
||||
}
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
|
||||
@ -144,4 +133,4 @@ class Chest extends Transparent{
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Clay extends Solid{
|
||||
|
||||
@ -40,16 +39,16 @@ class Clay extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Clay Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::CLAY_BALL, 0, 4)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Coal extends Solid{
|
||||
|
||||
@ -39,22 +38,18 @@ class Coal extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Coal Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 16000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class CoalOre extends Solid{
|
||||
|
||||
@ -40,21 +40,21 @@ class CoalOre extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Coal Ore";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [
|
||||
ItemFactory::get(Item::COAL, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::COAL)
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Cobblestone extends Solid{
|
||||
|
||||
@ -35,7 +34,11 @@ class Cobblestone extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
@ -45,12 +48,4 @@ class Cobblestone extends Solid{
|
||||
public function getHardness() : float{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class CobblestoneStairs extends Stair{
|
||||
|
||||
@ -38,11 +38,15 @@ class CobblestoneStairs extends Stair{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Cobblestone Stairs";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
@ -38,7 +38,11 @@ class CobblestoneWall extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\ItemFactory;
|
||||
|
||||
class Cobweb extends Flowable{
|
||||
|
||||
@ -48,19 +48,24 @@ class Cobweb extends Flowable{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SWORD;
|
||||
return BlockToolType::TYPE_SWORD | BlockToolType::TYPE_SHEARS;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity) : void{
|
||||
$entity->resetFallDistance();
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
//TODO: correct drops
|
||||
return [];
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::STRING)
|
||||
];
|
||||
}
|
||||
|
||||
public function diffusesSkyLight() : bool{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,5 +35,17 @@ class CocoaBlock extends Transparent{
|
||||
return "Cocoa Block";
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 0.2;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
//TODO
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorBlockMetaHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Concrete extends Solid{
|
||||
|
||||
@ -44,15 +43,10 @@ class Concrete extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\ColorBlockMetaHelper;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class ConcretePowder extends Fallable{
|
||||
@ -44,7 +43,7 @@ class ConcretePowder extends Fallable{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function onUpdate(int $type){
|
||||
@ -75,4 +74,4 @@ class ConcretePowder extends Fallable{
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\inventory\BigCraftingGrid;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\Player;
|
||||
|
||||
class CraftingTable extends Solid{
|
||||
@ -45,7 +44,7 @@ class CraftingTable extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
@ -59,4 +58,4 @@ class CraftingTable extends Solid{
|
||||
public function getFuelTime() : int{
|
||||
return 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,4 +95,8 @@ abstract class Crops extends Flowable{
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -63,4 +63,4 @@ class Dandelion extends Flowable{
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,5 +43,9 @@ class DaylightSensor extends Transparent{
|
||||
return 300;
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
@ -54,16 +53,20 @@ class DeadBush extends Flowable{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHEARS;
|
||||
return BlockToolType::TYPE_SHEARS;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isShears()){
|
||||
return parent::getDrops($item);
|
||||
if(!$this->isCompatibleWithTool($item)){
|
||||
return [
|
||||
ItemFactory::get(Item::STICK, 0, mt_rand(0, 2))
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
ItemFactory::get(Item::STICK, 0, mt_rand(0, 2))
|
||||
];
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Diamond extends Solid{
|
||||
|
||||
@ -43,14 +42,10 @@ class Diamond extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_IRON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class DiamondOre extends Solid{
|
||||
|
||||
@ -44,16 +44,16 @@ class DiamondOre extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
ItemFactory::get(Item::DIAMOND, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_IRON;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::DIAMOND)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Dirt extends Solid{
|
||||
@ -40,7 +39,7 @@ class Dirt extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
@ -64,4 +63,4 @@ class Dirt extends Solid{
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,23 +246,6 @@ abstract class Door extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
if(($this->getDamage() & 0x08) === 0x08){
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === $this->getId()){
|
||||
$this->getLevel()->setBlock($down, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}else{
|
||||
$up = $this->getSide(Vector3::SIDE_UP);
|
||||
if($up->getId() === $this->getId()){
|
||||
$this->getLevel()->setBlock($up, BlockFactory::get(Block::AIR), true);
|
||||
}
|
||||
}
|
||||
$this->getLevel()->setBlock($this, BlockFactory::get(Block::AIR), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if(($this->getDamage() & 0x08) === 0x08){ //Top
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
@ -286,4 +269,32 @@ abstract class Door extends Transparent{
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(($this->meta & 0x08) === 0){ //bottom half only
|
||||
return parent::getDropsForCompatibleTool($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getAffectedBlocks() : array{
|
||||
if(($this->getDamage() & 0x08) === 0x08){
|
||||
$down = $this->getSide(Vector3::SIDE_DOWN);
|
||||
if($down->getId() === $this->getId()){
|
||||
return [$this, $down];
|
||||
}
|
||||
}else{
|
||||
$up = $this->getSide(Vector3::SIDE_UP);
|
||||
if($up->getId() === $this->getId()){
|
||||
return [$this, $up];
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getAffectedBlocks();
|
||||
}
|
||||
}
|
||||
|
@ -97,33 +97,39 @@ class DoublePlant extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
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 getToolType() : int{
|
||||
return ($this->meta === 2 or $this->meta === 3) ? BlockToolType::TYPE_SHEARS : BlockToolType::TYPE_NONE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return ($this->meta === 2 or $this->meta === 3) ? 1 : 0; //only grass or fern require shears
|
||||
}
|
||||
|
||||
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 [];
|
||||
if($this->isCompatibleWithTool($item)){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return parent::getDrops($item);
|
||||
if(mt_rand(0, 24) === 0){
|
||||
return [
|
||||
ItemFactory::get(Item::SEEDS)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
public function getAffectedBlocks() : array{
|
||||
if($this->isValidHalfPlant()){
|
||||
return [$this, $this->getSide(($this->meta & self::BITFLAG_TOP) !== 0 ? Vector3::SIDE_DOWN : Vector3::SIDE_UP)];
|
||||
}
|
||||
|
||||
return parent::getAffectedBlocks();
|
||||
}
|
||||
}
|
||||
|
@ -38,10 +38,13 @@ abstract class DoubleSlab extends Solid{
|
||||
return "Double " . BlockFactory::get($this->getSlabId(), $this->getVariant())->getName() . " Slab";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get($this->getSlabId(), $this->getVariant(), 2)
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class DoubleStoneSlab extends DoubleSlab{
|
||||
|
||||
@ -39,15 +38,10 @@ class DoubleStoneSlab extends DoubleSlab{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -31,4 +31,4 @@ class DoubleStoneSlab2 extends DoubleStoneSlab{
|
||||
return self::STONE_SLAB2;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class DoubleWoodenSlab extends DoubleSlab{
|
||||
|
||||
protected $id = self::DOUBLE_WOODEN_SLAB;
|
||||
@ -38,6 +36,6 @@ class DoubleWoodenSlab extends DoubleSlab{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Emerald extends Solid{
|
||||
|
||||
@ -39,18 +38,14 @@ class Emerald extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_IRON;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Emerald Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class EmeraldOre extends Solid{
|
||||
|
||||
@ -40,20 +40,20 @@ class EmeraldOre extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_IRON;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return [
|
||||
ItemFactory::get(Item::EMERALD, 0, 1)
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::EMERALD)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\inventory\EnchantInventory;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\EnchantTable as TileEnchantTable;
|
||||
@ -60,7 +60,11 @@ class EnchantingTable extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
@ -72,12 +76,4 @@ class EnchantingTable extends Transparent{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,4 +65,4 @@ class EndPortalFrame extends Solid{
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,4 +101,4 @@ class EndRod extends Flowable{
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class EndStone extends Solid{
|
||||
|
||||
@ -38,10 +38,14 @@ class EndStone extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class EndStoneBricks extends Solid{
|
||||
|
||||
@ -43,15 +42,10 @@ class EndStoneBricks extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\EnderChest as TileEnderChest;
|
||||
@ -52,7 +52,11 @@ class EnderChest extends Chest{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
@ -71,10 +75,6 @@ class EnderChest extends Chest{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
return Block::onBreak($item, $player);
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null) : bool{
|
||||
if($player instanceof Player){
|
||||
|
||||
@ -97,16 +97,14 @@ class EnderChest extends Chest{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return [ItemFactory::get(Item::OBSIDIAN, 0, 8)];
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::OBSIDIAN, 0, 8)
|
||||
];
|
||||
}
|
||||
|
||||
public function getFuelTime() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -54,4 +54,4 @@ abstract class Fallable extends Solid{
|
||||
public function tickFalling() : ?Block{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -47,7 +46,7 @@ class Farmland extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
@ -108,9 +107,13 @@ class Farmland extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
ItemFactory::get(Item::DIRT)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ 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;
|
||||
@ -37,7 +36,7 @@ class FenceGate extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,7 +79,7 @@ class Fire extends Flowable{
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -114,4 +114,4 @@ class Fire extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -42,4 +42,4 @@ abstract class Flowable extends Transparent{
|
||||
protected function recalculateBoundingBox() : ?AxisAlignedBB{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,4 +82,4 @@ class Flower extends Flowable{
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,8 +96,12 @@ class FlowerPot extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
$items = parent::getDrops($item);
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
$items = parent::getDropsForCompatibleTool($item);
|
||||
|
||||
$tile = $this->getLevel()->getTile($this);
|
||||
if($tile instanceof TileFlowerPot){
|
||||
@ -110,4 +114,7 @@ class FlowerPot extends Flowable{
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -35,4 +35,4 @@ class Furnace extends BurningFurnace{
|
||||
public function getLightLevel() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class Glass extends Transparent{
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class GlassPane extends Thin{
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -36,7 +36,11 @@ class GlazedTerracotta extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, Player $player = null) : bool{
|
||||
@ -56,12 +60,4 @@ class GlazedTerracotta extends Solid{
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class GlowingObsidian extends Solid{
|
||||
|
||||
protected $id = self::GLOWING_OBSIDIAN;
|
||||
@ -47,4 +49,12 @@ class GlowingObsidian extends Solid{
|
||||
public function getBlastResistance() : float{
|
||||
return 50;
|
||||
}
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_DIAMOND;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ class GlowingRedstoneOre extends RedstoneOre{
|
||||
|
||||
protected $id = self::GLOWING_REDSTONE_ORE;
|
||||
|
||||
protected $itemId = self::REDSTONE_ORE;
|
||||
|
||||
public function getName() : string{
|
||||
return "Glowing Redstone Ore";
|
||||
}
|
||||
@ -46,4 +48,4 @@ class GlowingRedstoneOre extends RedstoneOre{
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Glowstone extends Transparent{
|
||||
|
||||
@ -44,16 +43,16 @@ class Glowstone extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::GLOWSTONE_DUST, 0, mt_rand(2, 4))
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Gold extends Solid{
|
||||
|
||||
@ -43,14 +42,10 @@ class Gold extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_IRON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class GoldOre extends Solid{
|
||||
|
||||
@ -43,14 +42,10 @@ class GoldOre extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_IRON){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_IRON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ 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;
|
||||
@ -50,12 +49,12 @@ class Grass extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
ItemFactory::get(Item::DIRT)
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -43,7 +42,7 @@ class GrassPath extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox() : ?AxisAlignedBB{
|
||||
@ -70,9 +69,9 @@ class GrassPath extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::DIRT, 0, 1)
|
||||
ItemFactory::get(Item::DIRT)
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
|
||||
class Gravel extends Fallable{
|
||||
|
||||
@ -44,17 +43,17 @@ class Gravel extends Fallable{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_SHOVEL;
|
||||
return BlockToolType::TYPE_SHOVEL;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(mt_rand(1, 10) === 1){
|
||||
return [
|
||||
ItemFactory::get(Item::FLINT, 0, 1)
|
||||
ItemFactory::get(Item::FLINT)
|
||||
];
|
||||
}
|
||||
|
||||
return parent::getDrops($item);
|
||||
return parent::getDropsForCompatibleTool($item);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class HardenedClay extends Solid{
|
||||
|
||||
@ -38,10 +38,14 @@ class HardenedClay extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 1.25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,4 +54,4 @@ class HayBale extends Solid{
|
||||
public function getVariantBitmask() : int{
|
||||
return 0x03;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
@ -53,11 +53,14 @@ class Ice extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item, Player $player = null) : bool{
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true);
|
||||
if(!$item->hasEnchantment(Enchantment::SILK_TOUCH)){
|
||||
return $this->getLevel()->setBlock($this, BlockFactory::get(Block::WATER), true);
|
||||
}
|
||||
return parent::onBreak($item, $player);
|
||||
}
|
||||
|
||||
public function ticksRandomly() : bool{
|
||||
@ -75,7 +78,7 @@ class Ice extends Transparent{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Iron extends Solid{
|
||||
|
||||
@ -39,18 +38,14 @@ class Iron extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_STONE;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_STONE){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class IronBars extends Thin{
|
||||
|
||||
@ -43,20 +42,15 @@ class IronBars extends Thin{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class IronDoor extends Door{
|
||||
|
||||
@ -41,18 +41,14 @@ class IronDoor extends Door{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_WOODEN){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class IronOre extends Solid{
|
||||
|
||||
@ -39,18 +38,14 @@ class IronOre extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_STONE;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_STONE){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class IronTrapdoor extends Trapdoor{
|
||||
|
||||
@ -38,6 +38,10 @@ class IronTrapdoor extends Trapdoor{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_WOODEN;
|
||||
}
|
||||
}
|
||||
|
@ -99,8 +99,8 @@ class ItemFrame extends Flowable{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
$drops = parent::getDrops($item);
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
$drops = parent::getDropsForCompatibleTool($item);
|
||||
|
||||
$tile = $this->level->getTile($this);
|
||||
if($tile instanceof TileItemFrame){
|
||||
@ -112,4 +112,8 @@ class ItemFrame extends Flowable{
|
||||
|
||||
return $drops;
|
||||
}
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -122,10 +121,10 @@ class Ladder extends Transparent{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_AXE;
|
||||
return BlockToolType::TYPE_AXE;
|
||||
}
|
||||
|
||||
public function getVariantBitmask() : int{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class Lapis extends Solid{
|
||||
|
||||
@ -39,19 +38,14 @@ class Lapis extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_STONE;
|
||||
}
|
||||
|
||||
public function getHardness() : float{
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_STONE){
|
||||
return parent::getDrops($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\item\Tool;
|
||||
use pocketmine\item\TieredTool;
|
||||
|
||||
class LapisOre extends Solid{
|
||||
|
||||
@ -40,21 +40,21 @@ class LapisOre extends Solid{
|
||||
}
|
||||
|
||||
public function getToolType() : int{
|
||||
return Tool::TYPE_PICKAXE;
|
||||
return BlockToolType::TYPE_PICKAXE;
|
||||
}
|
||||
|
||||
public function getToolHarvestLevel() : int{
|
||||
return TieredTool::TIER_STONE;
|
||||
}
|
||||
|
||||
public function getName() : string{
|
||||
return "Lapis Lazuli Ore";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if($item->isPickaxe() >= Tool::TIER_STONE){
|
||||
return [
|
||||
ItemFactory::get(Item::DYE, 4, mt_rand(4, 8))
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
ItemFactory::get(Item::DYE, 4, mt_rand(4, 8))
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user