mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-08 19:02:59 +00:00
Compare commits
357 Commits
4.4.0-BETA
...
4.11.0
Author | SHA1 | Date | |
---|---|---|---|
d450264e1c | |||
641d35a30f | |||
642630a4d2 | |||
d79e6354a0 | |||
ff63983de4 | |||
588215044e | |||
5c1e9a35a9 | |||
aad9f5fb45 | |||
a8dca190c6 | |||
e5f5fe80f9 | |||
36ab34df29 | |||
dda8ff18b1 | |||
6562335120 | |||
0c463a8721 | |||
a66f966b08 | |||
cca22046ab | |||
d19f0bf7be | |||
ff2391e74a | |||
39e10da88d | |||
beed6efd4e | |||
e5bc4deb12 | |||
2fcff13578 | |||
b4b8ef1c6b | |||
9650b7f03a | |||
a3502a711d | |||
83ddcce987 | |||
732dac6fc1 | |||
d5e3636908 | |||
ef100b248b | |||
d03bbb0426 | |||
93e661aa4e | |||
50efcf7424 | |||
a7ac6070dc | |||
069062f122 | |||
bf7014e0ec | |||
824ed0a56a | |||
b3ccf41307 | |||
a39938e6b6 | |||
d5bf88acc0 | |||
2d0602d19f | |||
3a2a23b236 | |||
1a8c8af523 | |||
1e9d83f014 | |||
6153a2ac70 | |||
ed452b9ccd | |||
c19880e045 | |||
cdbdcb5d67 | |||
29301614e8 | |||
2fdc46c165 | |||
bfd1b2c635 | |||
1671405cd0 | |||
fe982c697b | |||
1572b31b8d | |||
b6f6671a81 | |||
6da467b142 | |||
44af519cd6 | |||
fb31e6085e | |||
e4548da173 | |||
0d5287bf0b | |||
a9361b3f8b | |||
6e4c62744e | |||
9a0ead6deb | |||
d74824c8d5 | |||
d4eb73abe9 | |||
7864294336 | |||
2a910c1cc2 | |||
cd04a3db2e | |||
572def9245 | |||
20f5bed926 | |||
14d17a9546 | |||
b74c092d9b | |||
7bcc663b60 | |||
b3bda788d9 | |||
2cc8a56e68 | |||
57deb60355 | |||
92e47b98f8 | |||
b84c110819 | |||
4fadb63f67 | |||
c83f0896ac | |||
0d29a138fb | |||
421379fc77 | |||
293cea7714 | |||
15645759e9 | |||
6ae7cb288e | |||
7df2719fce | |||
10b8dcfdd1 | |||
c1fbac412e | |||
3feaa18f6c | |||
41970feb57 | |||
cd4bb91676 | |||
2be527060f | |||
6f68c6d8a0 | |||
ac16378410 | |||
1f9dfa77bf | |||
0c7f8470b9 | |||
fc56c041f3 | |||
d6bbf8217d | |||
22486dd75e | |||
37ec1193ea | |||
bda0ca23b4 | |||
b21cd82e94 | |||
1c7b1e9e5d | |||
b87e4d8bd3 | |||
86a2f8e360 | |||
def2f8c145 | |||
ed7c95549d | |||
cfb0cad7e0 | |||
83e5b0adb6 | |||
4650a3bb22 | |||
5e5661de75 | |||
e2f1b10165 | |||
455f9fa92e | |||
dec188d4ad | |||
2db3498891 | |||
a7dfa0907c | |||
f448b2e685 | |||
6a0c54f850 | |||
77a18d0aea | |||
140a809c40 | |||
cb7c136035 | |||
83a136a176 | |||
3f7d8a3777 | |||
3c55db531d | |||
93d4475111 | |||
e4fc523251 | |||
7804172846 | |||
7d29ac8293 | |||
481bda8cd5 | |||
d1c75da14b | |||
89e29448ee | |||
66e70e5b0e | |||
785dc71256 | |||
d459afaa54 | |||
db586233da | |||
23e98a30f5 | |||
5bc7ca6569 | |||
f39d2a9be3 | |||
47d98af6ac | |||
9f97654f6f | |||
82ba7903c8 | |||
441b06f6c7 | |||
112974758e | |||
313850eec4 | |||
a82923acb4 | |||
67887afd6b | |||
3d03bb1301 | |||
c063198b89 | |||
f3ca6de1eb | |||
88eafdd614 | |||
6dd5fec4ea | |||
6866c86d39 | |||
a735a69870 | |||
a0ea74c08f | |||
ca4b8a5827 | |||
f88c4d9a8c | |||
66cd156d80 | |||
222049927a | |||
d72e947d15 | |||
770cca2efa | |||
033dac3d16 | |||
1ee02d7e02 | |||
85678aa356 | |||
1d253bc8c2 | |||
973a56ab28 | |||
9e0b4621be | |||
ffb3af3e0d | |||
b3f03d7ae6 | |||
2585160ca2 | |||
14d3e6c7d5 | |||
65ec318c30 | |||
a25cb3741a | |||
b7a15b6e01 | |||
456439566b | |||
5b89833d5c | |||
fb25e05416 | |||
78b5be8dd0 | |||
0a92e91a30 | |||
b3a13a2f21 | |||
08b9495bce | |||
5779622235 | |||
c16893cbac | |||
7f175b47e6 | |||
0e73ffe555 | |||
1ffd38b37b | |||
bd13f39156 | |||
0c446c276c | |||
0284e65f60 | |||
b0d787b3d3 | |||
65e3ed43d5 | |||
75eba9c9ed | |||
b5a049d1fe | |||
bd9fcffe62 | |||
feffbc2c5b | |||
53b51c99b4 | |||
5cb77c8365 | |||
bf8befc40b | |||
f75ca312cc | |||
d144832928 | |||
709a869045 | |||
ac056044ce | |||
fc8434308b | |||
5426b41447 | |||
af2babec23 | |||
5d5366a7c8 | |||
717ab1989a | |||
83db186b6a | |||
6a4e5aba8b | |||
c13170a00b | |||
98778052bb | |||
e86e8254a8 | |||
1b852ac290 | |||
10b799fadb | |||
bc5008334a | |||
d6af2b12f4 | |||
ad2d59923c | |||
792c1b62b7 | |||
e90abecf38 | |||
575dd47db7 | |||
e4a5defabb | |||
c9626c610b | |||
8fb7fff6b9 | |||
5c8d8ff61f | |||
99b55f7427 | |||
dce8bd6d21 | |||
8fa81242d6 | |||
2f4a9469b6 | |||
4d34885b15 | |||
c5b2488fc1 | |||
d62df585f2 | |||
19d7c2b552 | |||
f7ab0a3b92 | |||
036e06e889 | |||
9343a0b800 | |||
14b4644b03 | |||
464b65b25c | |||
15586ed80e | |||
0f8ad8ecf7 | |||
82b9afef77 | |||
2fc84f6c67 | |||
566f5935a3 | |||
44e4dabf6e | |||
8acc535218 | |||
e9a1cb7ce5 | |||
a21419d120 | |||
c2b599166c | |||
df7a1fcba6 | |||
d77a95e4af | |||
5c72807b16 | |||
5c6927e16c | |||
9abbb85a93 | |||
554182b2cb | |||
d669a6f0c7 | |||
16ed16722a | |||
42f9336f7a | |||
5d9f783037 | |||
01ca14c314 | |||
608c6ed6db | |||
c26631d06d | |||
b75bc61a64 | |||
3724479be3 | |||
eb916fe43d | |||
5e3b3a0700 | |||
e10a624444 | |||
b20e04539d | |||
4852f8029a | |||
2940547026 | |||
24e72ec109 | |||
c4f85e526b | |||
6cee428287 | |||
bcba064d69 | |||
dbc0b9634b | |||
86647683bc | |||
040516054f | |||
64f0e58e60 | |||
62f21516d1 | |||
c553f7cf06 | |||
fec89b7803 | |||
4e3964ffce | |||
93254523e6 | |||
2b61c025c2 | |||
e00f8e3a32 | |||
e2855aadff | |||
c7133bc2e6 | |||
4d6ec66270 | |||
baf75089f5 | |||
705df7d508 | |||
f1a63098bd | |||
75d7adfb2d | |||
4b1052022c | |||
9d535e2917 | |||
3ccd288afd | |||
06655bee78 | |||
0ad2985247 | |||
5a8983dd81 | |||
269b6ed16a | |||
f031c3c602 | |||
f3e09dd7d5 | |||
68e704bf97 | |||
9898577135 | |||
38651fde74 | |||
784d602600 | |||
15c99cfe77 | |||
d5fa0a2fc5 | |||
0da9260994 | |||
63ee03a7be | |||
df2d1fd4f9 | |||
088a2e478c | |||
9f65fb5f90 | |||
caa4b78a3f | |||
14352a05bc | |||
bb5b52d998 | |||
5e22b70b6d | |||
02513818a9 | |||
d641812c52 | |||
a851496293 | |||
35fd71eddf | |||
be168beba0 | |||
01a8bce2dd | |||
becbd562d6 | |||
82edb20e0c | |||
64a8c462f9 | |||
4ec97d0f7a | |||
016a80bb70 | |||
ce66a400a7 | |||
50776875bb | |||
bcb0e2ff1f | |||
1584768c80 | |||
5fd685e07d | |||
6ecfbd1bde | |||
b661097c51 | |||
0771295899 | |||
702816458c | |||
e040c2b281 | |||
e12e4e8fb8 | |||
d15a90899e | |||
237c2866e0 | |||
38d6284671 | |||
7355798e77 | |||
4b662d65b3 | |||
c87a3b054c | |||
4b73bedd57 | |||
8b86e43d51 | |||
eade2d2af0 | |||
f2299a562f | |||
3fcf6372e0 | |||
533cb77c50 | |||
681a9bb0e1 | |||
6c080dae55 | |||
670fb4de74 | |||
6d7318af43 | |||
97c0d72e28 | |||
4ccae2d1de | |||
b36c6ea13b | |||
39b8daeeec | |||
c492352d50 | |||
8f1452acd1 | |||
227f28a6d2 |
8
.github/workflows/build-docker-image.yml
vendored
8
.github/workflows/build-docker-image.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
||||
run: echo ::set-output name=NAME::$(echo "${GITHUB_REPOSITORY,,}")
|
||||
|
||||
- name: Build image for tag
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -59,7 +59,7 @@ jobs:
|
||||
|
||||
- name: Build image for major tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -72,7 +72,7 @@ jobs:
|
||||
|
||||
- name: Build image for minor tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -85,7 +85,7 @@ jobs:
|
||||
|
||||
- name: Build image for latest tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v3.0.0
|
||||
uses: docker/build-push-action@v3.2.0
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
|
100
.github/workflows/discord-release-embed.php
vendored
Normal file
100
.github/workflows/discord-release-embed.php
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\utils\Internet;
|
||||
use function dirname;
|
||||
use function fwrite;
|
||||
use function is_array;
|
||||
use function json_decode;
|
||||
use function json_encode;
|
||||
use const JSON_THROW_ON_ERROR;
|
||||
use const STDERR;
|
||||
|
||||
require dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* @phpstan-return array<string, mixed>
|
||||
*/
|
||||
function generateDiscordEmbed(string $version, string $channel, string $description, string $detailsUrl, string $sourceUrl, string $pharDownloadUrl, string $buildLogUrl) : array{
|
||||
return [
|
||||
"embeds" => [
|
||||
[
|
||||
"title" => "New PocketMine-MP release: $version ($channel)",
|
||||
"description" => <<<DESCRIPTION
|
||||
$description
|
||||
|
||||
[Details]($detailsUrl) | [Source Code]($sourceUrl) | [Build Log]($buildLogUrl) | [Download]($pharDownloadUrl)
|
||||
DESCRIPTION,
|
||||
"url" => $detailsUrl,
|
||||
"color" => $channel === "stable" ? 0x57ab5a : 0xc69026
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
if(count($argv) !== 5){
|
||||
fwrite(STDERR, "Required arguments: github repo, version, API token\n");
|
||||
exit(1);
|
||||
}
|
||||
[, $repo, $tagName, $token, $hookURL] = $argv;
|
||||
|
||||
$result = Internet::getURL('https://api.github.com/repos/' . $repo . '/releases/tags/' . $tagName, extraHeaders: [
|
||||
'Authorization: token ' . $token
|
||||
]);
|
||||
if($result === null){
|
||||
fwrite(STDERR, "failed to access GitHub API\n");
|
||||
return;
|
||||
}
|
||||
if($result->getCode() !== 200){
|
||||
fwrite(STDERR, "Error accessing GitHub API: " . $result->getCode() . "\n");
|
||||
fwrite(STDERR, $result->getBody() . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$releaseInfoJson = json_decode($result->getBody(), true, JSON_THROW_ON_ERROR);
|
||||
if(!is_array($releaseInfoJson)){
|
||||
fwrite(STDERR, "Invalid release JSON returned from GitHub API\n");
|
||||
exit(1);
|
||||
}
|
||||
$buildInfoPath = 'https://github.com/' . $repo . '/releases/download/' . $tagName . '/build_info.json';
|
||||
|
||||
$buildInfoResult = Internet::getURL($buildInfoPath, extraHeaders: [
|
||||
'Authorization: token ' . $token
|
||||
]);
|
||||
if($buildInfoResult === null){
|
||||
fwrite(STDERR, "missing build_info.json\n");
|
||||
exit(1);
|
||||
}
|
||||
if($buildInfoResult->getCode() !== 200){
|
||||
fwrite(STDERR, "error accessing build_info.json: " . $buildInfoResult->getCode() . "\n");
|
||||
fwrite(STDERR, $buildInfoResult->getBody() . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$buildInfoJson = json_decode($buildInfoResult->getBody(), true, JSON_THROW_ON_ERROR);
|
||||
if(!is_array($buildInfoJson)){
|
||||
fwrite(STDERR, "invalid build_info.json\n");
|
||||
exit(1);
|
||||
}
|
||||
$detailsUrl = $buildInfoJson["details_url"];
|
||||
$sourceUrl = $buildInfoJson["source_url"];
|
||||
$pharDownloadUrl = $buildInfoJson["download_url"];
|
||||
$buildLogUrl = $buildInfoJson["build_log_url"];
|
||||
|
||||
$description = $releaseInfoJson["body"];
|
||||
|
||||
$discordPayload = generateDiscordEmbed($buildInfoJson["base_version"], $buildInfoJson["channel"], $description, $detailsUrl, $sourceUrl, $pharDownloadUrl, $buildLogUrl);
|
||||
|
||||
$response = Internet::postURL(
|
||||
$hookURL,
|
||||
json_encode($discordPayload, JSON_THROW_ON_ERROR),
|
||||
extraHeaders: ['Content-Type: application/json']
|
||||
);
|
||||
if($response?->getCode() !== 204){
|
||||
fwrite(STDERR, "failed to send Discord webhook\n");
|
||||
fwrite(STDERR, $response?->getBody() ?? "no response body\n");
|
||||
exit(1);
|
||||
}
|
38
.github/workflows/discord-release-notify.yml
vendored
Normal file
38
.github/workflows/discord-release-notify.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: Notify Discord webhook of release
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP and tools
|
||||
uses: shivammathur/setup-php@2.22.0
|
||||
with:
|
||||
php-version: 8.0
|
||||
|
||||
- name: Restore Composer package cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/composer/files
|
||||
~/.cache/composer/vcs
|
||||
key: "composer-v2-cache-${{ hashFiles('./composer.lock') }}"
|
||||
restore-keys: |
|
||||
composer-v2-cache-
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --no-dev --prefer-dist --no-interaction --ignore-platform-reqs
|
||||
|
||||
- name: Get actual tag name
|
||||
id: tag-name
|
||||
run: echo ::set-output name=TAG_NAME::$(echo "${{ github.ref }}" | sed 's{^refs/tags/{{')
|
||||
|
||||
- name: Run webhook post script
|
||||
run: php .github/workflows/discord-release-embed.php ${{ github.repository }} ${{ steps.tag-name.outputs.TAG_NAME }} ${{ github.token }} ${{ secrets.DISCORD_RELEASE_WEBHOOK }}
|
8
.github/workflows/draft-release.yml
vendored
8
.github/workflows/draft-release.yml
vendored
@ -18,7 +18,7 @@ jobs:
|
||||
submodules: true
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@2.18.1
|
||||
uses: shivammathur/setup-php@2.22.0
|
||||
with:
|
||||
php-version: 8.0
|
||||
|
||||
@ -57,7 +57,7 @@ jobs:
|
||||
echo ::set-output name=PM_VERSION_MD::$(php -r 'require "vendor/autoload.php"; echo str_replace(".", "", \pocketmine\VersionInfo::BASE_VERSION);')
|
||||
|
||||
- name: Generate build info
|
||||
run: php build/generate-build-info-json.php ${{ github.sha }} ${{ steps.get-pm-version.outputs.PM_VERSION }} ${{ github.repository }} ${{ steps.build-number.outputs.BUILD_NUMBER }} > build_info.json
|
||||
run: php build/generate-build-info-json.php ${{ github.sha }} ${{ steps.get-pm-version.outputs.PM_VERSION }} ${{ github.repository }} ${{ steps.build-number.outputs.BUILD_NUMBER }} ${{ github.run_id }} > build_info.json
|
||||
|
||||
- name: Upload release artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
@ -69,7 +69,7 @@ jobs:
|
||||
${{ github.workspace }}/build_info.json
|
||||
|
||||
- name: Create draft release
|
||||
uses: ncipollo/release-action@v1.10.0
|
||||
uses: ncipollo/release-action@v1.11.1
|
||||
with:
|
||||
artifacts: ${{ github.workspace }}/PocketMine-MP.phar,${{ github.workspace }}/start.*,${{ github.workspace }}/build_info.json
|
||||
commit: ${{ github.sha }}
|
||||
@ -80,4 +80,4 @@ jobs:
|
||||
body: |
|
||||
**For Minecraft: Bedrock Edition ${{ steps.get-pm-version.outputs.MCPE_VERSION }}**
|
||||
|
||||
Please see the [changelogs](/changelogs/${{ steps.get-pm-version.outputs.PM_VERSION_SHORT }}.md#${{ steps.get-pm-version.outputs.PM_VERSION_MD }}) for details.
|
||||
Please see the [changelogs](${{ github.server_url }}/${{ github.repository }}/blob/${{ steps.get-pm-version.outputs.PM_VERSION }}/changelogs/${{ steps.get-pm-version.outputs.PM_VERSION_SHORT }}.md#${{ steps.get-pm-version.outputs.PM_VERSION_MD }}) for details.
|
||||
|
24
.github/workflows/main.yml
vendored
24
.github/workflows/main.yml
vendored
@ -13,11 +13,11 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.18]
|
||||
php: [8.0.23, 8.1.10]
|
||||
|
||||
steps:
|
||||
- name: Build and prepare PHP cache
|
||||
uses: pmmp/setup-php-action@aa636a4fe0c1c035fd9a3f05e360eadd86e06440
|
||||
uses: pmmp/setup-php-action@82a44d659bf5046612c69f036af3e14dc32e3fa8
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -31,13 +31,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.18]
|
||||
php: [8.0.23, 8.1.10]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: pmmp/setup-php-action@aa636a4fe0c1c035fd9a3f05e360eadd86e06440
|
||||
uses: pmmp/setup-php-action@82a44d659bf5046612c69f036af3e14dc32e3fa8
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -69,13 +69,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.18]
|
||||
php: [8.0.23, 8.1.10]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: pmmp/setup-php-action@aa636a4fe0c1c035fd9a3f05e360eadd86e06440
|
||||
uses: pmmp/setup-php-action@82a44d659bf5046612c69f036af3e14dc32e3fa8
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -107,7 +107,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.18]
|
||||
php: [8.0.23, 8.1.10]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -115,7 +115,7 @@ jobs:
|
||||
submodules: true
|
||||
|
||||
- name: Setup PHP
|
||||
uses: pmmp/setup-php-action@aa636a4fe0c1c035fd9a3f05e360eadd86e06440
|
||||
uses: pmmp/setup-php-action@82a44d659bf5046612c69f036af3e14dc32e3fa8
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -147,13 +147,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [ubuntu-20.04]
|
||||
php: [8.0.18]
|
||||
php: [8.0.23, 8.1.10]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: pmmp/setup-php-action@aa636a4fe0c1c035fd9a3f05e360eadd86e06440
|
||||
uses: pmmp/setup-php-action@82a44d659bf5046612c69f036af3e14dc32e3fa8
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
install-path: "./bin"
|
||||
@ -195,10 +195,10 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP and tools
|
||||
uses: shivammathur/setup-php@2.18.1
|
||||
uses: shivammathur/setup-php@2.22.0
|
||||
with:
|
||||
php-version: 8.0
|
||||
tools: php-cs-fixer:3.2
|
||||
tools: php-cs-fixer:3.11
|
||||
|
||||
- name: Run PHP-CS-Fixer
|
||||
run: php-cs-fixer fix --dry-run --diff --ansi
|
||||
|
9
.github/workflows/support.yml
vendored
9
.github/workflows/support.yml
vendored
@ -13,7 +13,14 @@ jobs:
|
||||
github-token: ${{ github.token }}
|
||||
support-label: "Support request"
|
||||
issue-comment: >
|
||||
Thanks, but this issue tracker is not intended for support requests. Please read the guidelines on [submitting an issue](https://github.com/pmmp/PocketMine-MP/blob/master/CONTRIBUTING.md#creating-an-issue).
|
||||
Hi, we only accept **bug reports** on this issue tracker, but this issue looks like a support request.
|
||||
|
||||
|
||||
Instead of creating an issue, try the following:
|
||||
|
||||
- Check our [Documentation](https://doc.pmmp.io) to see if you can find answers there
|
||||
|
||||
- Ask the community on our [Discord server](https://discord.gg/bmSAZBG) or our [Forums](https://forums.pmmp.io)
|
||||
|
||||
|
||||
[Docs](https://pmmp.rtfd.io) | [Discord](https://discord.gg/bmSAZBG) | [Forums](https://forums.pmmp.io)
|
||||
|
3
.github/workflows/update-php-versions.php
vendored
3
.github/workflows/update-php-versions.php
vendored
@ -22,7 +22,8 @@
|
||||
declare(strict_types=1);
|
||||
|
||||
const VERSIONS = [
|
||||
"8.0"
|
||||
"8.0",
|
||||
"8.1"
|
||||
];
|
||||
|
||||
$workflowFile = file_get_contents(__DIR__ . '/main.yml');
|
||||
|
2
.idea/fileTemplates/includes/PHP File Header.php
generated
2
.idea/fileTemplates/includes/PHP File Header.php
generated
@ -16,6 +16,6 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
@ -42,12 +42,38 @@ return (new PhpCsFixer\Config)
|
||||
'import_functions' => true,
|
||||
'import_classes' => null,
|
||||
],
|
||||
'header_comment' => [
|
||||
'comment_type' => 'comment',
|
||||
'header' => <<<BODY
|
||||
|
||||
____ _ _ __ __ _ __ __ ____
|
||||
| _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
| |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
| __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
|_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
@author PocketMine Team
|
||||
@link http://www.pocketmine.net/
|
||||
|
||||
|
||||
BODY,
|
||||
'location' => 'after_open'
|
||||
],
|
||||
'indentation_type' => true,
|
||||
'logical_operators' => true,
|
||||
'native_function_invocation' => [
|
||||
'scope' => 'namespaced',
|
||||
'include' => ['@all'],
|
||||
],
|
||||
'new_with_braces' => [
|
||||
'named_class' => true,
|
||||
'anonymous_class' => false,
|
||||
],
|
||||
'no_closing_tag' => true,
|
||||
'no_empty_phpdoc' => true,
|
||||
'no_extra_blank_lines' => true,
|
||||
|
@ -18,6 +18,32 @@ Larger contributions like feature additions should be preceded by a [Change Prop
|
||||
## Other things you'll need
|
||||
- [git](https://git-scm.com/)
|
||||
|
||||
## Choosing a target branch
|
||||
PocketMine-MP has three primary branches of development.
|
||||
|
||||
| Type of change | `stable` | `next-minor` | `next-major` |
|
||||
|:---------------|:--------:|:------------:|:------------:|
|
||||
| Bug fixes | ✔️ | ✔️ | ✔️ |
|
||||
| Improvements to API docs | ✔️ | ✔️ | ✔️ |
|
||||
| Cleaning up code | ❌ | ✔️ | ✔️ |
|
||||
| Changing code formatting or style | ❌ | ✔️ | ✔️ |
|
||||
| Addition of new core features | ❌ | 🟡 Only if non-disruptive | ✔️ |
|
||||
| Changing core behaviour (e.g. making something use threads) | ❌ | ✔️ | ✔️ |
|
||||
| Addition of new configuration options | ❌ | 🟡 Only if optional | ✔️ |
|
||||
| Addition of new API classes, methods or constants | ❌ | ✔️ | ✔️ |
|
||||
| Deprecating API classes, methods or constants | ❌ | ✔️ | ✔️ |
|
||||
| Adding optional parameters to an API method | ❌ | ✔️ | ✔️ |
|
||||
| Changing API behaviour | ❌ | 🟡 Only if backwards-compatible | ✔️ |
|
||||
| Removal of API | ❌ | ❌ | ✔️ |
|
||||
| Backwards-incompatible API change (e.g. renaming a method) | ❌ | ❌ | ✔️ |
|
||||
|
||||
### Notes
|
||||
- **Non-disruptive** means that usage should not be significantly altered by the change.
|
||||
- Examples of **non-disruptive** changes include adding new commands, or gameplay features like blocks and items.
|
||||
- Examples of **disruptive** changes include changing the way the server is run, world format changes (since those require downtime for the user to convert their world).
|
||||
- **API** includes all public and protected classes, functions and constants (unless marked as `@internal`).
|
||||
- Private members are not part of the API, **unless in a trait**.
|
||||
|
||||
## Making a pull request
|
||||
The basic procedure to create a pull request is:
|
||||
1. [Fork the repository on GitHub](https://github.com/pmmp/PocketMine-MP/fork). This gives you your own copy of the repository to make changes to.
|
||||
|
@ -7,10 +7,11 @@ GitHub is public and anyone can see the issues you post on the issue tracker, in
|
||||
|
||||
**WARNING: You may put live servers at risk by reporting a vulnerability on the GitHub issue tracker.**
|
||||
|
||||
**Contact us** by sending an email to [**team@pmmp.io**](mailto:team@pmmp.io?subject=Security%20Vulnerability%20in%20PocketMine-MP). Include the following information:
|
||||
**Contact us** by sending an email to [**security@pmmp.io**](mailto:security@pmmp.io). Include the following information:
|
||||
|
||||
- Version of PocketMine-MP
|
||||
- Detailed description of the vulnerability (e.g. how to exploit it, what the effects are)
|
||||
- Your GitHub username, if you wish to be credited for reporting the problem in the security advisory
|
||||
|
||||
Please note that we can't guarantee a reply to every email.
|
||||
|
||||
|
@ -17,14 +17,14 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
if(count($argv) !== 5){
|
||||
fwrite(STDERR, "required args: <git hash> <tag name> <github repo (owner/name)> <build number>");
|
||||
if(count($argv) !== 6){
|
||||
fwrite(STDERR, "required args: <git hash> <tag name> <github repo (owner/name)> <build number> <github actions run ID>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -40,4 +40,5 @@ echo json_encode([
|
||||
"details_url" => "https://github.com/$argv[3]/releases/tag/$argv[2]",
|
||||
"download_url" => "https://github.com/$argv[3]/releases/download/$argv[2]/PocketMine-MP.phar",
|
||||
"source_url" => "https://github.com/$argv[3]/tree/$argv[2]",
|
||||
"build_log_url" => "https://github.com/$argv[3]/actions/runs/$argv[5]",
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR) . "\n";
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -25,7 +25,7 @@ namespace pocketmine\build\generate_known_translation_apis;
|
||||
|
||||
use pocketmine\lang\Translatable;
|
||||
use pocketmine\utils\Utils;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function array_map;
|
||||
use function count;
|
||||
use function dirname;
|
||||
@ -75,7 +75,7 @@ const SHARED_HEADER = <<<'HEADER'
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -29,7 +29,9 @@ use function count;
|
||||
use function dirname;
|
||||
use function file_get_contents;
|
||||
use function file_put_contents;
|
||||
use function fwrite;
|
||||
use function implode;
|
||||
use function is_dir;
|
||||
use function ksort;
|
||||
use function mb_strtoupper;
|
||||
use function preg_match;
|
||||
@ -39,7 +41,8 @@ use function substr;
|
||||
use const SORT_STRING;
|
||||
|
||||
if(count($argv) !== 2){
|
||||
die("Provide a path to process");
|
||||
fwrite(STDERR, "Provide a path to process\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,30 +83,24 @@ function generateMethodAnnotations(string $namespaceName, array $members) : stri
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
/** @var string $file */
|
||||
foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_PATHNAME)) as $file){
|
||||
if(substr($file, -4) !== ".php"){
|
||||
continue;
|
||||
}
|
||||
function processFile(string $file) : void{
|
||||
$contents = file_get_contents($file);
|
||||
if($contents === false){
|
||||
throw new \RuntimeException("Failed to get contents of $file");
|
||||
}
|
||||
|
||||
if(preg_match("/(*ANYCRLF)^namespace (.+);$/m", $contents, $matches) !== 1 || preg_match('/(*ANYCRLF)^((final|abstract)\s+)?class /m', $contents) !== 1){
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
$shortClassName = basename($file, ".php");
|
||||
$className = $matches[1] . "\\" . $shortClassName;
|
||||
if(!class_exists($className)){
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
$reflect = new \ReflectionClass($className);
|
||||
$docComment = $reflect->getDocComment();
|
||||
if($docComment === false || preg_match("/(*ANYCRLF)^\s*\*\s*@generate-registry-docblock$/m", $docComment) !== 1){
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
echo "Found registry in $file\n";
|
||||
|
||||
@ -117,3 +114,18 @@ foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1],
|
||||
echo "No changes made to file $file\n";
|
||||
}
|
||||
}
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
if(is_dir($argv[1])){
|
||||
/** @var string $file */
|
||||
foreach(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($argv[1], \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_PATHNAME)) as $file){
|
||||
if(substr($file, -4) !== ".php"){
|
||||
continue;
|
||||
}
|
||||
|
||||
processFile($file);
|
||||
}
|
||||
}else{
|
||||
processFile($argv[1]);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
Submodule build/php updated: 8138c6a4a4...9353116fa8
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
38
changelogs/4.10.md
Normal file
38
changelogs/4.10.md
Normal file
@ -0,0 +1,38 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.40**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.10.0
|
||||
Released 26th October 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.40.
|
||||
- Removed support for older versions.
|
||||
|
||||
## Fixes
|
||||
- Fixed incorrect command descriptions showing in `/help` when multiple commands use the same name. Previously, the most recently registered command would show, even though it wouldn't actually be invoked.
|
||||
- Fixed splash potions affecting players in spectator mode.
|
||||
- Fixed `World->addParticle()` sending particles to players who couldn't possibly see them when a list of targets was used.
|
||||
- Fixed `World->addSound()` sending sounds to players who couldn't possibly hear them when a list of targets was used.
|
||||
|
||||
## Documentation
|
||||
- Improved type information available for various API methods in `World`.
|
||||
|
||||
# 4.10.1
|
||||
Released 7th November 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed spawning in the void if spawn terrain in a world is solid at the default spawn position.
|
||||
- Fixed totems of undying activating when the player has 1 HP remaining.
|
||||
- Fixed durable items such as tools becoming unbreakable when in stacks larger than 1. Now, the durability correctly resets when the tool breaks.
|
||||
- TPS below 12 now correctly shows as red in `/status`. Previously, it showed as orange due to a condition ordering bug.
|
||||
- Improved handling of missing arguments in user-defined `pocketmine.yml` command aliases. Previously, missing arguments would be filled with an empty string, which caused a variety of unexpected behaviour.
|
||||
|
||||
## Internals
|
||||
- Added validation for the array given to `BaseInventory->setContents()` to ensure that it contains only `Item` instances.
|
||||
- Silenced `PlayerAuthInputPacket` spam when the session is in the "spawn response" state.
|
||||
- Updated to PHPStan 1.9.
|
92
changelogs/4.11-beta.md
Normal file
92
changelogs/4.11-beta.md
Normal file
@ -0,0 +1,92 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.40**
|
||||
|
||||
This is a minor feature release for PocketMine-MP, introducing some new features and improvements.
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.11.0-BETA1
|
||||
Released 7th November 2022.
|
||||
|
||||
## General
|
||||
- Packet receive timings have now been split into two subcategories - Decode and Handle.
|
||||
- Console command entry can now be disabled via the `console.enable-input` setting in `pocketmine.yml`.
|
||||
- Best suited for headless servers (e.g. in a Docker container) where the console will never be used anyway.
|
||||
- Disabling the console reader slightly reduces memory usage, because console reading currently requires an additional subprocess.
|
||||
- Console command output now appears on the terminal only, and is not written to the log file.
|
||||
- The output from console commands now appears with a `Command output |` prefix, instead of as a log message.
|
||||
- Introduced validation for the `--data` and `--plugins` command line options.
|
||||
- Encrypted resource packs are now supported, by means of adding a `.key` file alongside the pack in the `resource_packs` folder.
|
||||
- e.g. `MyEncryptedPack.zip` -> `MyEncryptedPack.zip.key`
|
||||
|
||||
## Gameplay
|
||||
- Fixed supporting blocks of dead bush to be in line with vanilla.
|
||||
- Sugarcane can now be grown using bonemeal on any part of the sugarcane. Previously, it only worked when used on the bottom block.
|
||||
- Fixed modifier values for Instant Damage and Regeneration effects.
|
||||
|
||||
## API
|
||||
### General
|
||||
- Plugins are now always disabled before their dependencies, to ensure that they are able to shutdown properly (e.g. a core plugin depending on a database plugin may want to save data to a DB during `onDisable()`).
|
||||
- [`webmozart/path-util`](https://packagist.org/packages/webmozart/path-util) has been deprecated, and will be dropped in favour of [`symfony/filesystem`](https://packagist.org/packages/symfony/filesystem) in PM5.
|
||||
- To prepare for this change, simply replace any usage of `Webmozart\PathUtil\Path` with `Symfony\Component\Filesystem\Path`, which is available as a dependency in this release.
|
||||
|
||||
### `pocketmine`
|
||||
- The following API methods are now deprecated:
|
||||
- `Server->getPlayerByPrefix()`
|
||||
|
||||
### `pocketmine\entity`
|
||||
- `EntitySpawnEvent` and `ItemSpawnEvent` are now fired on the first tick after the entity is added to the world. Previously, these events were called directly from the entity constructor, making it impossible to get properties like velocity which are often set after the entity is created.
|
||||
- The following API methods are now deprecated:
|
||||
- `Living->hasLineOfSight()`
|
||||
|
||||
### `pocketmine\item`
|
||||
- The following new API methods have been added:
|
||||
- `public Armor->clearCustomColor() : $this`
|
||||
|
||||
### `pocketmine\inventory\transaction`
|
||||
- Introduced a `TransactionBuilder` class. This makes it less of a hassle to build an `InventoryTransaction` server-side, since the regular `Inventory` API methods can be used, rather than having to manually create `SlotChangeAction`s.
|
||||
|
||||
### `pocketmine\player`
|
||||
- The following new API methods have been added:
|
||||
- `public Player->sendToastNotification(string $title, string $body) : void` - makes a grey box appear at the top of the player's screen containing the specified message
|
||||
|
||||
### `pocketmine\utils`
|
||||
- The following new API methods have been added:
|
||||
- `public static TextFormat::addBase(string $baseFormat, string $string) : string` - used for coloured log messages, changes the base formatting of a string by inserting the given formatting codes after every RESET code
|
||||
|
||||
## Internals
|
||||
- Improved performance of `ContainerTrait` dropping items on block destroy. (24e72ec109c1442b09558df89b6833cf2f2e0ec7)
|
||||
- Avoid repeated calls to `Position->getWorld()` (use local variables). (2940547026db40ce76deb46e992870de3ead79ad)
|
||||
- Revamped the way `InventoryManager` handles fake inventory slot mappings for stuff like crafting tables. (e90abecf38d9c57635fa0497514bba7e546a2469)
|
||||
- Console polling is now done on the main thread (no longer a performance concern).
|
||||
- Console reader subprocess should now automatically die if the server main process is killed, instead of persisting as a zombie.
|
||||
- `ConsoleCommandSender` is no longer responsible for relaying broadcast messages to `MainLogger`. A new `BroadcastLoggerForwarder` has been added, which is subscribed to the appropriate server broadcast channels in order to relay messages. This ensures that chat messages and command audit messages are logged.
|
||||
- `DelegateInventory` now uses `WeakReference` to track its inventory listener. This allows the delegate to be reused.
|
||||
|
||||
# 4.11.0-BETA2
|
||||
Released 13th November 2022.
|
||||
|
||||
## Configuration
|
||||
- The `chunk-ticking.per-tick` setting is now deprecated, and will be removed in a future release.
|
||||
- The functionality of this setting has been removed, since it caused more problems than it solved.
|
||||
- Setting it to zero will still disable chunk ticking (for now), but this should now be done by setting `chunk-ticking.tick-radius` to `0` instead.
|
||||
|
||||
## Gameplay
|
||||
- Improved chunk random ticking:
|
||||
- Removed the limit on chunks ticked per tick, and its associated config option is no longer respected.
|
||||
- This change significantly improves crop and plant growth with large numbers of players, but may cause higher CPU usage.
|
||||
- This limit was causing a linear decrease in chunk ticking speed with larger numbers of players, leading to worsened gameplay experience.
|
||||
- Every chunk within the configured tick radius of a player will be ticked. Previously, chunks were randomly selected from the radius.
|
||||
- Implemented Darkness effect.
|
||||
|
||||
## API
|
||||
### `pocketmine\world`
|
||||
- The following new API methods have been added:
|
||||
- `public World->getChunkTickRadius() : int` - returns the world's simulation radius
|
||||
- `public World->setChunkTickRadius(int $radius) : void` - sets the world's simulation radius
|
||||
|
||||
## Internals
|
||||
- Non-arrow projectile damage is now unscaled. Scaling according to velocity is only applied to arrows. This currently doesn't cause any observable change in behaviour, but is required for future additions.
|
102
changelogs/4.11.md
Normal file
102
changelogs/4.11.md
Normal file
@ -0,0 +1,102 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.40**
|
||||
|
||||
This is a minor feature release for PocketMine-MP, introducing some new features and improvements.
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.11.0
|
||||
Released 25th November 2022.
|
||||
|
||||
## General
|
||||
- Packet receive timings have now been split into two subcategories - Decode and Handle.
|
||||
- Console command entry can now be disabled via the `console.enable-input` setting in `pocketmine.yml`.
|
||||
- Best suited for headless servers (e.g. in a Docker container) where the console will never be used anyway.
|
||||
- Disabling the console reader slightly reduces memory usage, because console reading currently requires an additional subprocess.
|
||||
- Console command output now appears on the terminal only, and is not written to the log file.
|
||||
- The output from console commands now appears with a `Command output |` prefix, instead of as a log message.
|
||||
- User-defined `pocketmine.yml` custom commands now use a generic description which makes clear the command is config-defined.
|
||||
- Introduced validation for the `--data` and `--plugins` command line options.
|
||||
- Encrypted resource packs are now supported, by means of adding a `.key` file alongside the pack in the `resource_packs` folder.
|
||||
- e.g. `MyEncryptedPack.zip` -> `MyEncryptedPack.zip.key`
|
||||
- The file must contain the raw key bytes, and must not end with a newline.
|
||||
|
||||
## Configuration
|
||||
- The `chunk-ticking.per-tick` setting is now deprecated, and will be removed in a future release.
|
||||
- The functionality of this setting has been removed, since it caused more problems than it solved.
|
||||
- Setting it to zero will still disable chunk ticking (for now), but this should now be done by setting `chunk-ticking.tick-radius` to `0` instead.
|
||||
|
||||
## Gameplay
|
||||
- Fixed supporting blocks of dead bush to be in line with vanilla.
|
||||
- Sugarcane can now be grown using bonemeal on any part of the sugarcane. Previously, it only worked when used on the bottom block.
|
||||
- Fixed missing sounds when adding, rotating, or removing items in item frames.
|
||||
- Fixed modifier values for Instant Damage and Regeneration effects.
|
||||
- Implemented Darkness effect.
|
||||
- Improved chunk random ticking:
|
||||
- Removed the limit on chunks ticked per tick, and its associated config option is no longer respected.
|
||||
- This change significantly improves crop and plant growth with large numbers of players.
|
||||
- This limit was causing a linear decrease in chunk ticking speed with larger numbers of players, leading to worsened gameplay experience.
|
||||
- **Warning: This change will result in increased CPU usage if players are spread over a very large area.**
|
||||
- Every chunk within the configured tick radius of a player will be ticked. Previously, chunks were randomly selected from the radius.
|
||||
|
||||
## API
|
||||
### General
|
||||
- Plugins are now always disabled before their dependencies, to ensure that they are able to shutdown properly (e.g. a core plugin depending on a database plugin may want to save data to a DB during `onDisable()`).
|
||||
- [`webmozart/path-util`](https://packagist.org/packages/webmozart/path-util) has been deprecated, and will be dropped in favour of [`symfony/filesystem`](https://packagist.org/packages/symfony/filesystem) in PM5.
|
||||
- To prepare for this change, simply replace any usage of `Webmozart\PathUtil\Path` with `Symfony\Component\Filesystem\Path`, which is available as a dependency in this release.
|
||||
|
||||
### `pocketmine`
|
||||
- The following API methods are now deprecated:
|
||||
- `Server->getPlayerByPrefix()`
|
||||
|
||||
### `pocketmine\entity`
|
||||
- `EntitySpawnEvent` and `ItemSpawnEvent` are now fired on the first tick after the entity is added to the world. Previously, these events were called directly from the entity constructor, making it impossible to get properties like velocity which are often set after the entity is created.
|
||||
- The following API methods are now deprecated:
|
||||
- `Living->hasLineOfSight()`
|
||||
|
||||
### `pocketmine\event\block`
|
||||
- The following new classes have been added:
|
||||
- `BlockDeathEvent` - event called when coral or coral blocks die due to lack of water
|
||||
|
||||
### `pocketmine\item`
|
||||
- The following new API methods have been added:
|
||||
- `public Armor->clearCustomColor() : $this`
|
||||
|
||||
### `pocketmine\inventory\transaction`
|
||||
- Introduced a `TransactionBuilder` class. This makes it less of a hassle to build an `InventoryTransaction` server-side, since the regular `Inventory` API methods can be used, rather than having to manually create `SlotChangeAction`s.
|
||||
|
||||
### `pocketmine\lang`
|
||||
- The following new API methods have been added:
|
||||
- `public Language->getAll() : array<string, string>`
|
||||
|
||||
### `pocketmine\player`
|
||||
- The following new API methods have been added:
|
||||
- `public Player->sendToastNotification(string $title, string $body) : void` - makes a grey box appear at the top of the player's screen containing the specified message
|
||||
|
||||
### `pocketmine\utils`
|
||||
- The following new API methods have been added:
|
||||
- `public static TextFormat::addBase(string $baseFormat, string $string) : string` - used for coloured log messages, changes the base formatting of a string by inserting the given formatting codes after every RESET code
|
||||
|
||||
### `pocketmine\world`
|
||||
- The following new API methods have been added:
|
||||
- `public World->getChunkTickRadius() : int` - returns the world's simulation radius
|
||||
- `public World->setChunkTickRadius(int $radius) : void` - sets the world's simulation radius
|
||||
|
||||
### `pocketmine\world\sound`
|
||||
- The following new classes have been added:
|
||||
- `ItemFrameAddItemSound`
|
||||
- `ItemFrameRemoveItemSound`
|
||||
- `ItemFrameRotateItemSound`
|
||||
|
||||
## Internals
|
||||
- Improved performance of `ContainerTrait` dropping items on block destroy. (24e72ec109c1442b09558df89b6833cf2f2e0ec7)
|
||||
- Avoid repeated calls to `Position->getWorld()` (use local variables). (2940547026db40ce76deb46e992870de3ead79ad)
|
||||
- Revamped the way `InventoryManager` handles fake inventory slot mappings for stuff like crafting tables. (e90abecf38d9c57635fa0497514bba7e546a2469)
|
||||
- Console polling is now done on the main thread (no longer a performance concern).
|
||||
- Console reader subprocess should now automatically die if the server main process is killed, instead of persisting as a zombie.
|
||||
- `ConsoleCommandSender` is no longer responsible for relaying broadcast messages to `MainLogger`. A new `BroadcastLoggerForwarder` has been added, which is subscribed to the appropriate server broadcast channels in order to relay messages. This ensures that chat messages and command audit messages are logged.
|
||||
- `DelegateInventory` now uses `WeakReference` to track its inventory listener. This allows the delegate to be reused.
|
||||
- Non-arrow projectile damage is now unscaled. Scaling according to velocity is only applied to arrows. This currently doesn't cause any observable change in behaviour, but is required for future additions.
|
@ -19,7 +19,7 @@ Released 25th May 2022.
|
||||
- Any world mentioned in `server.properties` or `pocketmine.yml` fails to generate (e.g. due to invalid generator settings)
|
||||
- Enabling the server whitelist while the server is running (e.g. using `/whitelist on`) will now kick any non-whitelisted players currently on the server (**PR [#4774](https://github.com/pmmp/PocketMine-MP/pull/4774)**).
|
||||
- Help for commands (`/help <name of command>`) now displays a list of aliases of that command.
|
||||
- A CRITICIAL log message is now generated if a plugin disables itself when enabling, in case the plugin doesn't emit any error of its own.
|
||||
- A CRITICAL log message is now generated if a plugin disables itself when enabling, in case the plugin doesn't emit any error of its own.
|
||||
- The `/give` command now shows the alias used to find the given item in the success message, instead of the item ID/meta.
|
||||
|
||||
## Fixes
|
||||
|
97
changelogs/4.4.md
Normal file
97
changelogs/4.4.md
Normal file
@ -0,0 +1,97 @@
|
||||
**For Minecraft: Bedrock Edition 1.18.30**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.4.0
|
||||
Released 1st June 2022.
|
||||
|
||||
## General
|
||||
- The server will now shut itself down if any of the following errors occur during startup:
|
||||
- Any plugin fails to load or enable (plugins loaded by other plugins post-startup are **not** affected by this change) (**PR [#4951](https://github.com/pmmp/PocketMine-MP/pull/4951)**)
|
||||
- The motivation for this change is to prevent situations where plugins failing to load could result in adverse outcomes, such as a world protection plugin leaving a lobby unprotected from griefing.
|
||||
- If you encounter this problem, remove the offending plugin(s) or prevent it from loading using `plugin_list.yml`.
|
||||
- See **PR [#4951](https://github.com/pmmp/PocketMine-MP/pull/4951)** for more detail on this change.
|
||||
- Any world mentioned in `server.properties` or `pocketmine.yml` fails to load (worlds loaded by plugins are **not** affected by this change)
|
||||
- Any world mentioned in `server.properties` or `pocketmine.yml` fails to generate (e.g. due to invalid generator settings)
|
||||
- Enabling the server whitelist while the server is running (e.g. using `/whitelist on`) will now kick any non-whitelisted players currently on the server (**PR [#4774](https://github.com/pmmp/PocketMine-MP/pull/4774)**).
|
||||
- Help for commands (`/help <name of command>`) now displays a list of aliases of that command.
|
||||
- A CRITICAL log message is now generated if a plugin disables itself when enabling, in case the plugin doesn't emit any error of its own.
|
||||
- The `/give` command now shows the alias used to find the given item in the success message, instead of the item ID/meta.
|
||||
|
||||
## Fixes
|
||||
- Block placement has been fixed in many places where it previously didn't work correctly (**PR [#4886](https://github.com/pmmp/PocketMine-MP/pull/4886)**):
|
||||
- torches on top of slabs, upside-down stairs
|
||||
- torches on the back face of stairs
|
||||
- flower pots on top of fences
|
||||
- the list goes on and on ...
|
||||
- Fixed backslash escapes not getting properly removed from commands in some cases.
|
||||
- Fixed aliases defined in the `aliases` section of `pocketmine.yml` not being treated as quote-aware.
|
||||
|
||||
## Gameplay
|
||||
- Plants in flower pots can now be removed by right-clicking on the flower pot.
|
||||
- Leaves now have a 2% chance of dropping sticks when destroyed by hand (**PR [#5019](https://github.com/pmmp/PocketMine-MP/pull/5019)**).
|
||||
- Food exhaustion now matches Bedrock 1.18.30 (**PR [#5034](https://github.com/pmmp/PocketMine-MP/pull/5034)**).
|
||||
- Implemented Stonecutter block (**PR [#4732](https://github.com/pmmp/PocketMine-MP/pull/4732)**).
|
||||
|
||||
## API
|
||||
### Block
|
||||
- Added `Block->getSupportType(Facing) : SupportType` (**PR [#4886](https://github.com/pmmp/PocketMine-MP/pull/4886)**).
|
||||
- This is used to determine the kind of support a block face can provide to a block (e.g. a torch) placed on it.
|
||||
- Added `utils\SupportType` enum (**PR [#4886](https://github.com/pmmp/PocketMine-MP/pull/4886)**).
|
||||
- `tile\Spawnable->isDirty()` and `tile\Spawnable->setDirty()` are now `@deprecated`.
|
||||
|
||||
### Command
|
||||
- Added `CommandStringHelper::parseQuoteAware()`. This static method contains the code used by `SimpleCommandMap` used to parse quoted command arguments.
|
||||
|
||||
### Entity
|
||||
- Added `Human::emote()` (**PR [#4610](https://github.com/pmmp/PocketMine-MP/pull/4610)**)
|
||||
|
||||
### Event
|
||||
- `PlayerCommandPreprocessEvent` is now `@deprecated`, since its functionality is entirely replaced by other, general-purpose events.
|
||||
- Use `CommandEvent` to intercept commands.
|
||||
- Use `PlayerChatEvent` to intercept chat messages.
|
||||
- To convert a chat message into a command, pass it directly to `Server->dispatchCommand()` with the player as sender.
|
||||
- Added `PlayerPostChunkSendEvent` (**PR [#4937](https://github.com/pmmp/PocketMine-MP/pull/4937)**).
|
||||
- Added `PlayerDeathEvent->setKeepXp()` (**PR [#4015](https://github.com/pmmp/PocketMine-MP/pull/4015)**).
|
||||
- `InventoryCloseEvent` is now called **after** the target window has been removed. This fixes various feedback loops caused by trying to open new windows to a player while there was one still active.
|
||||
- As a side effect, this now means that `Player->getCurrentWindow()` will return `null` during `InventoryCloseEvent`. Use `InventoryCloseEvent->getInventory()` instead.
|
||||
|
||||
### Item
|
||||
- `StringToItemParser` now recognizes `cod`, `raw_cod` and `cooked_cod` aliases.
|
||||
|
||||
### Plugin
|
||||
- `DisablePluginException` may now be thrown from `Plugin::onEnable()` to make the server gracefully disable the plugin (without crashing) (**PR [#4780](https://github.com/pmmp/PocketMine-MP/pull/4780)**).
|
||||
- `PluginManager->registerEvent()` now returns the `RegisteredListener` created for the handler, to permit unregistering it later.
|
||||
|
||||
## Internals
|
||||
- Private property declarations now use typed properties (PHP 7.4) and promoted constructor properties (PHP 8.0) wherever possible.
|
||||
- Protected and public properties remain unchanged, since they can't be changed without breaking subclasses.
|
||||
- Promoted constructor properties are only used when it's consistently possible to promote most or all properties in a class.
|
||||
- Simplified and improved legibility of `FormattedCommandAlias`.
|
||||
- Added unit tests for the quote-aware command parser used by `SimpleCommandMap`.
|
||||
- Various hardcoded values in `block` package classes have been moved to private constants to improve readability.
|
||||
- Added various constants used in the `LevelDB` world provider.
|
||||
|
||||
# 4.4.1
|
||||
Released 5th June 2022.
|
||||
|
||||
## General
|
||||
- The server process will now exit with an error code if plugins, worlds or network interfaces failed to start.
|
||||
|
||||
## Fixes
|
||||
- Fixed graylisted plugins preventing the server from starting.
|
||||
- Fixed `composer make-devtools` command.
|
||||
- Fixed the `Maximum memory (manager)` units being incorrectly displayed in `/status`.
|
||||
- Fixed `Player->removeCurrentWindow()` breaking inventory windows.
|
||||
|
||||
# 4.4.2
|
||||
Released 7th June 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed a crash when arbitrary item IDs appeared in network items in some cases.
|
||||
- Fixed saved paintings being deleted when loaded from disk (regression from 4.3.4).
|
||||
- Fixed max stack size of fishing rods.
|
28
changelogs/4.5.md
Normal file
28
changelogs/4.5.md
Normal file
@ -0,0 +1,28 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.0**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.5.0
|
||||
Released 7th June 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.0.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.5.1
|
||||
Released 8th June 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed commands defined in `pocketmine.yml` `aliases` not passing the correct arguments.
|
||||
- Updated BedrockProtocol to fix command argument types displayed on client-side command suggestions.
|
||||
|
||||
# 4.5.2
|
||||
Released 29th June 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed terrain getting redrawn when flying in spectator mode (or when using `Player->setHasBlockCollision(false)`).
|
||||
- Fixed skulls with the `noDrops` flag set being treated as unknown blocks.
|
42
changelogs/4.6.md
Normal file
42
changelogs/4.6.md
Normal file
@ -0,0 +1,42 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.10**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.6.0
|
||||
Released 13th July 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.10.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.6.1
|
||||
Released 22nd July 2022.
|
||||
|
||||
## Tools
|
||||
- `build/generate-registry-annotations.php` now supports processing single files (useful for PhpStorm file watchers).
|
||||
|
||||
## API
|
||||
- Updated documentation for `AsyncTask`.
|
||||
|
||||
## Fixes
|
||||
- Fixed incorrect items being displayed in item frames.
|
||||
- Fixed books not showing in lecterns.
|
||||
- Fixed incorrect damage interval of Wither status effect.
|
||||
- Fixed incorrect fire ticks when being set on fire by lava (8 seconds in Bedrock instead of 15).
|
||||
- `Entity->attack()` now cancels damage from `FIRE` and `FIRE_TICK` damage causes if the entity is fireproof.
|
||||
- Fixed inventory windows getting force-closed when the client attempts to use an enchanting table or anvil.
|
||||
|
||||
# 4.6.2
|
||||
Released 6th August 2022.
|
||||
|
||||
## Core
|
||||
- Improved server-side performance of `PlayerAuthInputPacket` handler.
|
||||
- Improved client-side performance of `FloatingTextParticle` by using an invisible falling block entity. This offered a roughly 5x performance improvement over using tiny invisible players in local testing.
|
||||
|
||||
## Fixes
|
||||
- Fixed assert failures and debug spam on debug Minecraft clients related to abilities in `AddPlayerPacket`.
|
||||
- Fixed crash in `ReversePriorityQueue` on PHP 8.1 by adding `#[ReturnTypeWillChange]` attribute.
|
46
changelogs/4.7.md
Normal file
46
changelogs/4.7.md
Normal file
@ -0,0 +1,46 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.20**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.7.0
|
||||
Released 9th August 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.20.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.7.1
|
||||
Released 14th August 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed server crash when loading items from disk which have negative meta values.
|
||||
- Fixed Turtle Master potions not giving any effects.
|
||||
- Unimplemented items are no longer craftable.
|
||||
- Fixed incorrect items appearing in item frames (due to an obsolete workaround for 1.19.10).
|
||||
|
||||
# 4.7.2
|
||||
Released 16th August 2022.
|
||||
|
||||
## Fixes
|
||||
- Fixed crash when processing player skins with invalid geometry data.
|
||||
- Fixed spectator players being able to pick blocks using mousewheel click.
|
||||
- Improved supporting requirements for sugarcane.
|
||||
|
||||
# 4.7.3
|
||||
Released 22nd August 2022.
|
||||
|
||||
## General
|
||||
- Added complete translations for Spanish and Vietnamese.
|
||||
- All continuous integration (static analysis, unit tests, integration tests) are now performed on PHP 8.1 as well as 8.0.
|
||||
- InventoryTransaction now verifies that stack sizes of items after the transaction don't exceed the maximum stack size of the item type or the containing inventory.
|
||||
|
||||
## Fixes
|
||||
- Fixed Normal generator crash on PHP 8.1.
|
||||
- Fixed a race condition during async worker shutdown that could lead to tasks executing in the wrong order. This (very rarely) led to a crash in `PopulationTask` due to its preceding `GeneratorRegisterTask` not being executed.
|
||||
- Fixed `/give` accepting negative amounts or amounts larger than 32767 (vanilla max).
|
||||
- Fixed placement conditions for vines (no longer able to be placed on the side of cacti).
|
||||
- Fixed incorrect documentation of `SignText::__construct()`.
|
23
changelogs/4.8.md
Normal file
23
changelogs/4.8.md
Normal file
@ -0,0 +1,23 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.21**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.8.0
|
||||
Released 24th August 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.21.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.8.1
|
||||
Released 26th August 2022.
|
||||
|
||||
## General
|
||||
- Crashdumps now include JIT mode information for use by the Crash Archive.
|
||||
|
||||
## Fixes
|
||||
- Fixed uninitialized offset error in `DyeColorIdMap` when given invalid dye color IDs.
|
36
changelogs/4.9.md
Normal file
36
changelogs/4.9.md
Normal file
@ -0,0 +1,36 @@
|
||||
**For Minecraft: Bedrock Edition 1.19.30**
|
||||
|
||||
### Note about API versions
|
||||
Plugins which don't touch the protocol and compatible with any previous 4.x.y version will also run on these releases and do not need API bumps.
|
||||
Plugin developers should **only** update their required API to this version if you need the changes in this build.
|
||||
|
||||
**WARNING: If your plugin uses the protocol, you're not shielded by API change constraints.** You should consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you do.
|
||||
|
||||
# 4.9.0
|
||||
Released 20th September 2022.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.19.30.
|
||||
- Removed support for older versions.
|
||||
|
||||
# 4.9.1
|
||||
Released 11th October 2022.
|
||||
|
||||
## Documentation
|
||||
- Added and improved documentation for many API methods in `Player` and `Block`.
|
||||
- Added missing `@internal` tag for `TaskHandler->setNextRun()`, `TaskHandler->remove()` and `TaskHandler->run()`.
|
||||
|
||||
## Fixes
|
||||
- Flight state is now locked by the server in spectator mode. This prevents any attempt by the client to toggle flight mode.
|
||||
- Fixed entity health exceeding its max health after the expiry of Health Boost effect.
|
||||
- Fixed burp sound not being played when a player eats food.
|
||||
- Fixed placement conditions for mushrooms - they can now only be placed when the light level at the target is <= 12, or on podzol or mycelium.
|
||||
- Fixed sign text appearing to change colour and/or glow when using dye on a sign - since this feature is not yet implemented, no change should occur.
|
||||
- Fixed players drowning when sprint-swimming on the surface of water.
|
||||
|
||||
## Internals
|
||||
- Added more detailed debug logging during the player login sequence.
|
||||
- Silenced debug spam during `PreSpawnPacketHandler`, considerably reducing debug noise when players join.
|
||||
- Fixed an edge case in `InventoryManager->removeWindow()`. This bug didn't have any effect on stable versions, but caused a `next-minor` development version to crash.
|
||||
- `Item`s returned by event getters are now cloned if modifying the result will have no useful side effects.
|
||||
- Updated `pocketmine/bedrock-data` to [`1.11.1`](https://github.com/pmmp/BedrockData/tree/1.11.1%2Bbedrock-1.19.30), which reduces bandwidth consumption during logins by not sending useless biome generation data.
|
@ -34,14 +34,14 @@
|
||||
"adhocore/json-comment": "^1.1",
|
||||
"fgrosse/phpasn1": "^2.3",
|
||||
"netresearch/jsonmapper": "^4.0",
|
||||
"pocketmine/bedrock-data": "~1.7.0+bedrock-1.18.30",
|
||||
"pocketmine/bedrock-protocol": "~9.0.0+bedrock-1.18.30",
|
||||
"pocketmine/bedrock-data": "~1.12.0+bedrock-1.19.40",
|
||||
"pocketmine/bedrock-protocol": "~16.0.0+bedrock-1.19.40",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"pocketmine/classloader": "^0.2.0",
|
||||
"pocketmine/color": "^0.2.0",
|
||||
"pocketmine/errorhandler": "^0.6.0",
|
||||
"pocketmine/locale-data": "~2.8.0",
|
||||
"pocketmine/locale-data": "~2.11.0",
|
||||
"pocketmine/log": "^0.4.0",
|
||||
"pocketmine/log-pthreads": "^0.4.0",
|
||||
"pocketmine/math": "^0.4.0",
|
||||
@ -50,10 +50,11 @@
|
||||
"pocketmine/raklib-ipc": "^0.1.0",
|
||||
"pocketmine/snooze": "^0.3.0",
|
||||
"ramsey/uuid": "^4.1",
|
||||
"symfony/filesystem": "^5.4",
|
||||
"webmozart/path-util": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.7.1",
|
||||
"phpstan/phpstan": "1.9.2",
|
||||
"phpstan/phpstan-phpunit": "^1.1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.2.0",
|
||||
"phpunit/phpunit": "^9.2"
|
||||
@ -79,7 +80,7 @@
|
||||
"sort-packages": true
|
||||
},
|
||||
"scripts": {
|
||||
"make-devtools": "@php -dphar.readonly=0 tests/plugins/DevTools/src/ConsoleScript.php --make tests/plugins/DevTools --out plugins/DevTools.phar",
|
||||
"make-devtools": "@php -dphar.readonly=0 tests/plugins/DevTools/src/ConsoleScript.php --make ./ --relative tests/plugins/DevTools --out plugins/DevTools.phar",
|
||||
"make-server": [
|
||||
"@composer install --no-dev --classmap-authoritative --ignore-platform-reqs",
|
||||
"@php -dphar.readonly=0 build/server-phar.php"
|
||||
|
796
composer.lock
generated
796
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
||||
includes:
|
||||
- tests/phpstan/analyse-for-current-php-version.neon.php
|
||||
- tests/phpstan/configs/actual-problems.neon
|
||||
- tests/phpstan/configs/gc-hacks.neon
|
||||
- tests/phpstan/configs/impossible-generics.neon
|
||||
|
@ -119,8 +119,6 @@ chunk-sending:
|
||||
spawn-radius: 4
|
||||
|
||||
chunk-ticking:
|
||||
#Max amount of chunks processed each tick
|
||||
per-tick: 40
|
||||
#Radius of chunks around a player to tick
|
||||
tick-radius: 3
|
||||
#Number of blocks inside ticking areas' subchunks that get ticked every tick. Higher values will accelerate events
|
||||
@ -168,6 +166,9 @@ timings:
|
||||
host: timings.pmmp.io
|
||||
|
||||
console:
|
||||
#Whether to accept commands via the console. If disabled, anything typed on the console will be ignored.
|
||||
#Useful to save resources on headless servers where the console is never used (e.g. hosted server, Docker, etc.)
|
||||
enable-input: true
|
||||
#Choose whether to enable server stats reporting on the console title.
|
||||
#NOTE: The title ticker will be disabled regardless if console colours are not enabled.
|
||||
title-tick: true
|
||||
|
@ -10,3 +10,4 @@ resource_stack:
|
||||
# - natural.zip
|
||||
# - vanilla.zip
|
||||
#If you want to force clients to use vanilla resources, you must place a vanilla resource pack in your resources folder and add it to the stack here.
|
||||
#To specify a resource encryption key, put the key in the <resource>.key file alongside the resource pack. Example: vanilla.zip.key
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -30,7 +30,7 @@ use pocketmine\scheduler\GarbageCollectionTask;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\Process;
|
||||
use pocketmine\utils\Utils;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function arsort;
|
||||
use function count;
|
||||
use function fclose;
|
||||
@ -398,7 +398,7 @@ class MemoryManager{
|
||||
|
||||
do{
|
||||
$continue = false;
|
||||
foreach($objects as $hash => $object){
|
||||
foreach(Utils::stringifyKeys($objects) as $hash => $object){
|
||||
if(!is_object($object)){
|
||||
continue;
|
||||
}
|
||||
@ -483,6 +483,11 @@ class MemoryManager{
|
||||
* @param object[] $objects reference parameter
|
||||
* @param int[] $refCounts reference parameter
|
||||
*
|
||||
* @phpstan-param array<string, object> $objects
|
||||
* @phpstan-param array<string, int> $refCounts
|
||||
* @phpstan-param-out array<string, object> $objects
|
||||
* @phpstan-param-out array<string, int> $refCounts
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private static function continueDump($from, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
|
||||
|
@ -34,9 +34,10 @@ namespace pocketmine {
|
||||
use pocketmine\utils\Timezone;
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\SetupWizard;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function defined;
|
||||
use function extension_loaded;
|
||||
use function function_exists;
|
||||
use function getcwd;
|
||||
use function phpversion;
|
||||
use function preg_match;
|
||||
@ -160,7 +161,7 @@ namespace pocketmine {
|
||||
if(PHP_DEBUG !== 0){
|
||||
$logger->warning("This PHP binary was compiled in debug mode. This has a major impact on performance.");
|
||||
}
|
||||
if(extension_loaded("xdebug")){
|
||||
if(extension_loaded("xdebug") && (!function_exists('xdebug_info') || count(xdebug_info('mode')) !== 0)){
|
||||
$logger->warning("Xdebug extension is enabled. This has a major impact on performance.");
|
||||
}
|
||||
if(((int) ini_get('zend.assertions')) !== -1){
|
||||
@ -176,10 +177,10 @@ namespace pocketmine {
|
||||
|
||||
|
||||
--------------------------------------- ! WARNING ! ---------------------------------------
|
||||
You're using PHP 8.0 with JIT enabled. This provides significant performance improvements.
|
||||
You're using PHP with JIT enabled. This provides significant performance improvements.
|
||||
HOWEVER, it is EXPERIMENTAL, and has already been seen to cause weird and unexpected bugs.
|
||||
Proceed with caution.
|
||||
If you want to report any bugs, make sure to mention that you are using PHP 8.0 with JIT.
|
||||
If you want to report any bugs, make sure to mention that you have enabled PHP JIT.
|
||||
To turn off JIT, change `opcache.jit` to `0` in your php.ini file.
|
||||
-------------------------------------------------------------------------------------------
|
||||
|
||||
@ -200,6 +201,22 @@ JIT_WARNING
|
||||
ini_set('assert.exception', '1');
|
||||
}
|
||||
|
||||
function getopt_string(string $opt) : ?string{
|
||||
$opts = getopt("", ["$opt:"]);
|
||||
if(isset($opts[$opt])){
|
||||
if(is_string($opts[$opt])){
|
||||
return $opts[$opt];
|
||||
}
|
||||
if(is_array($opts[$opt])){
|
||||
critical_error("Cannot specify --$opt multiple times");
|
||||
}else{
|
||||
critical_error("Missing value for --$opt");
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
@ -251,16 +268,22 @@ JIT_WARNING
|
||||
|
||||
ErrorToExceptionHandler::set();
|
||||
|
||||
$opts = getopt("", ["data:", "plugins:", "no-wizard", "enable-ansi", "disable-ansi"]);
|
||||
|
||||
$cwd = Utils::assumeNotFalse(realpath(Utils::assumeNotFalse(getcwd())));
|
||||
$dataPath = isset($opts["data"]) ? $opts["data"] . DIRECTORY_SEPARATOR : $cwd . DIRECTORY_SEPARATOR;
|
||||
$pluginPath = isset($opts["plugins"]) ? $opts["plugins"] . DIRECTORY_SEPARATOR : $cwd . DIRECTORY_SEPARATOR . "plugins" . DIRECTORY_SEPARATOR;
|
||||
$dataPath = getopt_string("data") ?? $cwd;
|
||||
$pluginPath = getopt_string("plugins") ?? $cwd . DIRECTORY_SEPARATOR . "plugins";
|
||||
Filesystem::addCleanedPath($pluginPath, Filesystem::CLEAN_PATH_PLUGINS_PREFIX);
|
||||
|
||||
if(!file_exists($dataPath)){
|
||||
mkdir($dataPath, 0777, true);
|
||||
if(!@mkdir($dataPath, 0777, true) && (!is_dir($dataPath) || !is_writable($dataPath))){
|
||||
critical_error("Unable to create/access data directory at $dataPath. Check that the target location is accessible by the current user.");
|
||||
exit(1);
|
||||
}
|
||||
//this has to be done after we're sure the data path exists
|
||||
$dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
|
||||
if(!@mkdir($pluginPath, 0777, true) && (!is_dir($pluginPath) || !is_writable($pluginPath))){
|
||||
critical_error("Unable to create plugin directory at $pluginPath. Check that the target location is accessible by the current user.");
|
||||
exit(1);
|
||||
}
|
||||
$pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
|
||||
|
||||
$lockFilePath = Path::join($dataPath, 'server.lock');
|
||||
if(($pid = Filesystem::createLockFile($lockFilePath)) !== null){
|
||||
@ -272,6 +295,7 @@ JIT_WARNING
|
||||
//Logger has a dependency on timezone
|
||||
Timezone::init();
|
||||
|
||||
$opts = getopt("", ["no-wizard", "enable-ansi", "disable-ansi"]);
|
||||
if(isset($opts["enable-ansi"])){
|
||||
Terminal::init(true);
|
||||
}elseif(isset($opts["disable-ansi"])){
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -31,7 +31,7 @@ use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\SimpleCommandMap;
|
||||
use pocketmine\console\ConsoleCommandSender;
|
||||
use pocketmine\console\ConsoleReaderThread;
|
||||
use pocketmine\console\ConsoleReaderChildProcessDaemon;
|
||||
use pocketmine\crafting\CraftingManager;
|
||||
use pocketmine\crafting\CraftingManagerFromDataHelper;
|
||||
use pocketmine\crash\CrashDump;
|
||||
@ -88,12 +88,12 @@ use pocketmine\promise\PromiseResolver;
|
||||
use pocketmine\resourcepacks\ResourcePackManager;
|
||||
use pocketmine\scheduler\AsyncPool;
|
||||
use pocketmine\snooze\SleeperHandler;
|
||||
use pocketmine\snooze\SleeperNotifier;
|
||||
use pocketmine\stats\SendUsageTask;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
use pocketmine\updater\UpdateChecker;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\BroadcastLoggerForwarder;
|
||||
use pocketmine\utils\Config;
|
||||
use pocketmine\utils\Filesystem;
|
||||
use pocketmine\utils\Internet;
|
||||
@ -115,7 +115,7 @@ use pocketmine\world\World;
|
||||
use pocketmine\world\WorldCreationOptions;
|
||||
use pocketmine\world\WorldManager;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
use Webmozart\PathUtil\Path;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
use function array_sum;
|
||||
use function base64_encode;
|
||||
use function cli_set_process_title;
|
||||
@ -132,6 +132,7 @@ use function get_class;
|
||||
use function ini_set;
|
||||
use function is_array;
|
||||
use function is_dir;
|
||||
use function is_int;
|
||||
use function is_object;
|
||||
use function is_resource;
|
||||
use function is_string;
|
||||
@ -165,7 +166,6 @@ use function zlib_encode;
|
||||
use const DIRECTORY_SEPARATOR;
|
||||
use const PHP_EOL;
|
||||
use const PHP_INT_MAX;
|
||||
use const PTHREADS_INHERIT_NONE;
|
||||
use const ZLIB_ENCODING_GZIP;
|
||||
|
||||
/**
|
||||
@ -225,7 +225,8 @@ class Server{
|
||||
|
||||
private MemoryManager $memoryManager;
|
||||
|
||||
private ConsoleReaderThread $console;
|
||||
private ?ConsoleReaderChildProcessDaemon $console = null;
|
||||
private ?ConsoleCommandSender $consoleSender = null;
|
||||
|
||||
private SimpleCommandMap $commandMap;
|
||||
|
||||
@ -570,6 +571,7 @@ class Server{
|
||||
$playerPos = null;
|
||||
$spawn = $world->getSpawnLocation();
|
||||
}
|
||||
/** @phpstan-var PromiseResolver<Player> $playerPromiseResolver */
|
||||
$playerPromiseResolver = new PromiseResolver();
|
||||
$world->requestChunkPopulation($spawn->getFloorX() >> Chunk::COORD_BIT_SIZE, $spawn->getFloorZ() >> Chunk::COORD_BIT_SIZE, null)->onCompletion(
|
||||
function() use ($playerPromiseResolver, $class, $session, $playerInfo, $authenticated, $world, $playerPos, $spawn, $offlinePlayerData) : void{
|
||||
@ -607,6 +609,10 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method's results are unpredictable. The string "Steve" will return the player named "SteveJobs",
|
||||
* until another player named "SteveJ" joins the server, at which point it will return that player instead. Prefer
|
||||
* filtering the results of {@link Server::getOnlinePlayers()} yourself.
|
||||
*
|
||||
* Returns an online player whose name begins with or equals the given string (case insensitive).
|
||||
* The closest match will be returned, or null if there are no online matches.
|
||||
*
|
||||
@ -861,7 +867,7 @@ class Server{
|
||||
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error3()));
|
||||
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error4("settings.enable-dev-builds")));
|
||||
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_server_devBuild_error5("https://github.com/pmmp/PocketMine-MP/releases")));
|
||||
$this->forceShutdown();
|
||||
$this->forceShutdownExit();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -976,7 +982,7 @@ class Server{
|
||||
$pluginGraylist = PluginGraylist::fromArray(yaml_parse(file_get_contents($graylistFile)));
|
||||
}catch(\InvalidArgumentException $e){
|
||||
$this->logger->emergency("Failed to load $graylistFile: " . $e->getMessage());
|
||||
$this->forceShutdown();
|
||||
$this->forceShutdownExit();
|
||||
return;
|
||||
}
|
||||
$this->pluginManager = new PluginManager($this, $this->configGroup->getPropertyBool("plugins.legacy-data-dir", true) ? null : Path::join($this->getDataPath(), "plugin_data"), $pluginGraylist);
|
||||
@ -1007,28 +1013,28 @@ class Server{
|
||||
$this->pluginManager->loadPlugins($this->pluginPath, $loadErrorCount);
|
||||
if($loadErrorCount > 0){
|
||||
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_plugin_someLoadErrors()));
|
||||
$this->forceShutdown();
|
||||
$this->forceShutdownExit();
|
||||
return;
|
||||
}
|
||||
if(!$this->enablePlugins(PluginEnableOrder::STARTUP())){
|
||||
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_plugin_someEnableErrors()));
|
||||
$this->forceShutdown();
|
||||
$this->forceShutdownExit();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$this->startupPrepareWorlds()){
|
||||
$this->forceShutdown();
|
||||
$this->forceShutdownExit();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$this->enablePlugins(PluginEnableOrder::POSTWORLD())){
|
||||
$this->logger->emergency($this->language->translate(KnownTranslationFactory::pocketmine_plugin_someEnableErrors()));
|
||||
$this->forceShutdown();
|
||||
$this->forceShutdownExit();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$this->startupPrepareNetworkInterfaces()){
|
||||
$this->forceShutdown();
|
||||
$this->forceShutdownExit();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1043,22 +1049,14 @@ class Server{
|
||||
$this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_donate(TextFormat::AQUA . "https://patreon.com/pocketminemp" . TextFormat::RESET)));
|
||||
$this->logger->info($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_server_startFinished(strval(round(microtime(true) - $this->startTime, 3)))));
|
||||
|
||||
//TODO: move console parts to a separate component
|
||||
$consoleSender = new ConsoleCommandSender($this, $this->language);
|
||||
$this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_ADMINISTRATIVE, $consoleSender);
|
||||
$this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_USERS, $consoleSender);
|
||||
$forwarder = new BroadcastLoggerForwarder($this, $this->logger, $this->language);
|
||||
$this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_ADMINISTRATIVE, $forwarder);
|
||||
$this->subscribeToBroadcastChannel(self::BROADCAST_CHANNEL_USERS, $forwarder);
|
||||
|
||||
$consoleNotifier = new SleeperNotifier();
|
||||
$commandBuffer = new \Threaded();
|
||||
$this->console = new ConsoleReaderThread($commandBuffer, $consoleNotifier);
|
||||
$this->tickSleeper->addNotifier($consoleNotifier, function() use ($commandBuffer, $consoleSender) : void{
|
||||
Timings::$serverCommand->startTiming();
|
||||
while(($line = $commandBuffer->shift()) !== null){
|
||||
$this->dispatchCommand($consoleSender, (string) $line);
|
||||
}
|
||||
Timings::$serverCommand->stopTiming();
|
||||
});
|
||||
$this->console->start(PTHREADS_INHERIT_NONE);
|
||||
//TODO: move console parts to a separate component
|
||||
if($this->configGroup->getPropertyBool("console.enable-input", true)){
|
||||
$this->console = new ConsoleReaderChildProcessDaemon($this->logger);
|
||||
}
|
||||
|
||||
$this->tickProcessor();
|
||||
$this->forceShutdown();
|
||||
@ -1456,6 +1454,11 @@ class Server{
|
||||
}
|
||||
}
|
||||
|
||||
private function forceShutdownExit() : void{
|
||||
$this->forceShutdown();
|
||||
Process::kill(Process::pid(), true);
|
||||
}
|
||||
|
||||
public function forceShutdown() : void{
|
||||
if($this->hasStopped){
|
||||
return;
|
||||
@ -1506,7 +1509,7 @@ class Server{
|
||||
$this->configGroup->save();
|
||||
}
|
||||
|
||||
if(isset($this->console)){
|
||||
if($this->console !== null){
|
||||
$this->getLogger()->debug("Closing console");
|
||||
$this->console->quit();
|
||||
}
|
||||
@ -1645,12 +1648,14 @@ class Server{
|
||||
], 10, [], $postUrlError);
|
||||
|
||||
if($reply !== null && is_object($data = json_decode($reply->getBody()))){
|
||||
if(isset($data->crashId) && isset($data->crashUrl)){
|
||||
if(isset($data->crashId) && is_int($data->crashId) && isset($data->crashUrl) && is_string($data->crashUrl)){
|
||||
$reportId = $data->crashId;
|
||||
$reportUrl = $data->crashUrl;
|
||||
$this->logger->emergency($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_crash_archive($reportUrl, (string) $reportId)));
|
||||
}elseif(isset($data->error)){
|
||||
}elseif(isset($data->error) && is_string($data->error)){
|
||||
$this->logger->emergency("Automatic crash report submission failed: $data->error");
|
||||
}else{
|
||||
$this->logger->emergency("Invalid JSON response received from crash archive: " . $reply->getBody());
|
||||
}
|
||||
}else{
|
||||
$this->logger->emergency("Failed to communicate with crash archive: $postUrlError");
|
||||
@ -1711,7 +1716,7 @@ class Server{
|
||||
$session = $player->getNetworkSession();
|
||||
$position = $player->getPosition();
|
||||
$this->logger->info($this->language->translate(KnownTranslationFactory::pocketmine_player_logIn(
|
||||
TextFormat::AQUA . $player->getName() . TextFormat::WHITE,
|
||||
TextFormat::AQUA . $player->getName() . TextFormat::RESET,
|
||||
$session->getIp(),
|
||||
(string) $session->getPort(),
|
||||
(string) $player->getId(),
|
||||
@ -1848,6 +1853,15 @@ class Server{
|
||||
|
||||
$this->getMemoryManager()->check();
|
||||
|
||||
if($this->console !== null){
|
||||
Timings::$serverCommand->startTiming();
|
||||
while(($line = $this->console->readLine()) !== null){
|
||||
$this->consoleSender ??= new ConsoleCommandSender($this, $this->language);
|
||||
$this->dispatchCommand($this->consoleSender, $line);
|
||||
}
|
||||
Timings::$serverCommand->stopTiming();
|
||||
}
|
||||
|
||||
Timings::$serverTick->stopTiming();
|
||||
|
||||
$now = microtime(true);
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -31,9 +31,9 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "4.4.0-BETA1";
|
||||
public const BASE_VERSION = "4.11.0";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "beta";
|
||||
public const BUILD_CHANNEL = "stable";
|
||||
|
||||
private function __construct(){
|
||||
//NOOP
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -164,9 +164,10 @@ class Bamboo extends Transparent{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$below = $this->position->getWorld()->getBlock($this->position->down());
|
||||
$world = $this->position->getWorld();
|
||||
$below = $world->getBlock($this->position->down());
|
||||
if(!$this->canBeSupportedBy($below) && !$below->isSameType($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
$world->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,7 +213,7 @@ class Bamboo extends Transparent{
|
||||
}
|
||||
}
|
||||
|
||||
$tx = new BlockTransaction($this->position->getWorld());
|
||||
$tx = new BlockTransaction($world);
|
||||
foreach($newBlocks as $idx => $newBlock){
|
||||
$tx->addBlock($this->position->subtract(0, $idx - $growAmount, 0), $newBlock);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -82,8 +82,9 @@ final class BambooSapling extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->position->getWorld()->getBlock($this->position->down()))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
$world = $this->position->getWorld();
|
||||
if(!$this->canBeSupportedBy($world->getBlock($this->position->down()))){
|
||||
$world->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -26,6 +26,7 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\CoralTypeTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\event\block\BlockDeathEvent;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
abstract class BaseCoral extends Transparent{
|
||||
@ -50,7 +51,11 @@ abstract class BaseCoral extends Transparent{
|
||||
|
||||
//TODO: check water inside the block itself (not supported on the API yet)
|
||||
if(!$hasWater){
|
||||
$world->setBlock($this->position, $this->setDead(true));
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$world->setBlock($this->position, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -162,6 +162,7 @@ abstract class BaseRail extends Flowable{
|
||||
$thisConnections = $this->getConnectedDirections();
|
||||
$changed = false;
|
||||
|
||||
$world = $this->position->getWorld();
|
||||
do{
|
||||
$possible = $this->getPossibleConnectionDirections($thisConnections);
|
||||
$continue = false;
|
||||
@ -189,7 +190,7 @@ abstract class BaseRail extends Flowable{
|
||||
if(isset($otherPossible[$otherSide])){
|
||||
$otherConnections[] = $otherSide;
|
||||
$other->setConnections($otherConnections);
|
||||
$this->position->getWorld()->setBlock($other->position, $other);
|
||||
$world->setBlock($other->position, $other);
|
||||
|
||||
$changed = true;
|
||||
$thisConnections[] = $thisSide;
|
||||
@ -202,7 +203,7 @@ abstract class BaseRail extends Flowable{
|
||||
|
||||
if($changed){
|
||||
$this->setConnections($thisConnections);
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$world->setBlock($this->position, $this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,12 +221,13 @@ abstract class BaseRail extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if(!$this->getSide(Facing::DOWN)->getSupportType(Facing::UP)->hasEdgeSupport()){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
foreach($this->getCurrentShapeConnections() as $connection){
|
||||
if(($connection & RailConnectionInfo::FLAG_ASCEND) !== 0 && !$this->getSide($connection & ~RailConnectionInfo::FLAG_ASCEND)->getSupportType(Facing::UP)->hasEdgeSupport()){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
$world->useBreakOn($this->position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -179,10 +179,11 @@ final class Bell extends Transparent{
|
||||
}
|
||||
|
||||
public function ring(int $faceHit) : void{
|
||||
$this->position->getWorld()->addSound($this->position, new BellRingSound());
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
$world = $this->position->getWorld();
|
||||
$world->addSound($this->position, new BellRingSound());
|
||||
$tile = $world->getTile($this->position);
|
||||
if($tile instanceof TileBell){
|
||||
$this->position->getWorld()->broadcastPacketToViewers($this->position, $tile->createFakeUpdatePacket($faceHit));
|
||||
$world->broadcastPacketToViewers($this->position, $tile->createFakeUpdatePacket($faceHit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -78,25 +78,47 @@ class Block{
|
||||
$this->position = clone $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object containing information about how to identify and store this block type, such as its legacy
|
||||
* numeric ID(s), tile type (if any), and legacy variant metadata.
|
||||
*/
|
||||
public function getIdInfo() : BlockIdentifier{
|
||||
return $this->idInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the printable English name of the block.
|
||||
*/
|
||||
public function getName() : string{
|
||||
return $this->fallbackName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* Returns the legacy numeric Minecraft block ID.
|
||||
*/
|
||||
public function getId() : int{
|
||||
return $this->idInfo->getBlockId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Returns the full blockstate ID of this block. This is a compact way of representing a blockstate used to store
|
||||
* blocks in chunks at runtime.
|
||||
*
|
||||
* This ID can be used to later obtain a copy of this block using {@link BlockFactory::get()}.
|
||||
*/
|
||||
public function getFullId() : int{
|
||||
return ($this->getId() << self::INTERNAL_METADATA_BITS) | $this->getMeta();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the block as an item.
|
||||
* State information such as facing, powered/unpowered, open/closed, etc., is discarded.
|
||||
* Type information such as colour, wood type, etc. is preserved.
|
||||
*/
|
||||
public function asItem() : Item{
|
||||
return ItemFactory::getInstance()->get(
|
||||
$this->idInfo->getItemId(),
|
||||
@ -104,6 +126,12 @@ class Block{
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* Returns the legacy Minecraft block meta value. This is a mixed-purpose value, which is used to store different
|
||||
* things for different blocks.
|
||||
*/
|
||||
public function getMeta() : int{
|
||||
$stateMeta = $this->writeStateToMeta();
|
||||
assert(($stateMeta & ~$this->getStateBitmask()) === 0);
|
||||
@ -116,6 +144,7 @@ class Block{
|
||||
|
||||
/**
|
||||
* Returns a bitmask used to extract state bits from block metadata.
|
||||
* This is used to remove unwanted information from the legacy meta value when getting the block as an item.
|
||||
*/
|
||||
public function getStateBitmask() : int{
|
||||
return 0;
|
||||
@ -143,11 +172,18 @@ class Block{
|
||||
$this->collisionBoxes = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes information about the block into the world. This writes the blockstate ID into the chunk, and creates
|
||||
* and/or removes tiles as necessary.
|
||||
*
|
||||
* Note: Do not call this directly. Pass the block to {@link World::setBlock()} instead.
|
||||
*/
|
||||
public function writeStateToWorld() : void{
|
||||
$this->position->getWorld()->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getFullId());
|
||||
$world = $this->position->getWorld();
|
||||
$world->getOrLoadChunkAtPosition($this->position)->setFullBlock($this->position->x & Chunk::COORD_MASK, $this->position->y, $this->position->z & Chunk::COORD_MASK, $this->getFullId());
|
||||
|
||||
$tileType = $this->idInfo->getTileClass();
|
||||
$oldTile = $this->position->getWorld()->getTile($this->position);
|
||||
$oldTile = $world->getTile($this->position);
|
||||
if($oldTile !== null){
|
||||
if($tileType === null || !($oldTile instanceof $tileType)){
|
||||
$oldTile->close();
|
||||
@ -161,13 +197,13 @@ class Block{
|
||||
* @var Tile $tile
|
||||
* @see Tile::__construct()
|
||||
*/
|
||||
$tile = new $tileType($this->position->getWorld(), $this->position->asVector3());
|
||||
$this->position->getWorld()->addTile($tile);
|
||||
$tile = new $tileType($world, $this->position->asVector3());
|
||||
$world->addTile($tile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type ID that identifies this type of block. This does not include information like facing, colour,
|
||||
* Returns a type ID that identifies this type of block. This does not include information like facing, open/closed,
|
||||
* powered/unpowered, etc.
|
||||
*/
|
||||
public function getTypeId() : int{
|
||||
@ -198,22 +234,36 @@ class Block{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block can be replaced by another block placed in the same position.
|
||||
*/
|
||||
public function canBeReplaced() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this block can replace the given block in the given placement conditions.
|
||||
* This is used to allow slabs of the same type to combine into double slabs.
|
||||
*/
|
||||
public function canBePlacedAt(Block $blockReplace, Vector3 $clickVector, int $face, bool $isClickedBlock) : bool{
|
||||
return $blockReplace->canBeReplaced();
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the Block, using block space and block target, and side. Returns if the block has been placed.
|
||||
* Generates a block transaction to set all blocks affected by placing this block. Usually this is just the block
|
||||
* itself, but may be multiple blocks in some cases (such as doors).
|
||||
*
|
||||
* @return bool whether the placement should go ahead
|
||||
*/
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$tx->addBlock($blockReplace->position, $this);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called immediately after the block has been placed in the world. Since placement uses a block transaction, some
|
||||
* things may not be possible until after the transaction has been executed.
|
||||
*/
|
||||
public function onPostPlace() : void{
|
||||
|
||||
}
|
||||
@ -229,10 +279,11 @@ class Block{
|
||||
* Do the actions needed so the block is broken with the Item
|
||||
*/
|
||||
public function onBreak(Item $item, ?Player $player = null) : bool{
|
||||
if(($t = $this->position->getWorld()->getTile($this->position)) !== null){
|
||||
$world = $this->position->getWorld();
|
||||
if(($t = $world->getTile($this->position)) !== null){
|
||||
$t->onBlockDestroyed();
|
||||
}
|
||||
$this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR());
|
||||
$world->setBlock($this->position, VanillaBlocks::AIR());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -252,7 +303,7 @@ class Block{
|
||||
|
||||
/**
|
||||
* Called when this block is randomly updated due to chunk ticking.
|
||||
* WARNING: This will not be called if ticksRandomly() does not return true!
|
||||
* WARNING: This will not be called if {@link Block::ticksRandomly()} does not return true!
|
||||
*/
|
||||
public function onRandomTick() : void{
|
||||
|
||||
@ -273,8 +324,7 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this block is attacked (left-clicked). This is called when a player left-clicks the block to try and
|
||||
* start to break it in survival mode.
|
||||
* Called when this block is attacked (left-clicked) by a player attempting to start breaking it in survival.
|
||||
*
|
||||
* @return bool if an action took place, prevents starting to break the block if true.
|
||||
*/
|
||||
@ -282,11 +332,19 @@ class Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a multiplier applied to the velocity of entities moving on top of this block. A higher value will make
|
||||
* the block more slippery (like ice).
|
||||
*
|
||||
* @return float 0.0-1.0
|
||||
*/
|
||||
public function getFrictionFactor() : float{
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of light emitted by this block.
|
||||
*
|
||||
* @return int 0-15
|
||||
*/
|
||||
public function getLightLevel() : int{
|
||||
@ -329,10 +387,6 @@ class Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasEntityCollision() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether entities can climb up this block.
|
||||
*/
|
||||
@ -340,10 +394,6 @@ class Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function addVelocityToEntity(Entity $entity) : ?Vector3{
|
||||
return null;
|
||||
}
|
||||
|
||||
final public function getPosition() : Position{
|
||||
return $this->position;
|
||||
}
|
||||
@ -426,6 +476,7 @@ class Block{
|
||||
|
||||
/**
|
||||
* Returns the item that players will equip when middle-clicking on this block.
|
||||
* If addUserData is true, additional data may be added, such as banner patterns, chest contents, etc.
|
||||
*/
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
$item = $this->asItem();
|
||||
@ -549,7 +600,7 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for collision against an AxisAlignedBB
|
||||
* Returns whether any of the block's collision boxes intersect with the given AxisAlignedBB.
|
||||
*/
|
||||
public function collidesWithBB(AxisAlignedBB $bb) : bool{
|
||||
foreach($this->getCollisionBoxes() as $bb2){
|
||||
@ -561,10 +612,21 @@ class Block{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the block has actions to be executed when an entity enters its cell (full cube space).
|
||||
*
|
||||
* @see Block::onEntityInside()
|
||||
*/
|
||||
public function hasEntityCollision() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an entity's bounding box clips inside this block's cell. Note that the entity may not be intersecting
|
||||
* with the collision box or bounding box.
|
||||
*
|
||||
* WARNING: This will not be called if {@link Block::hasEntityCollision()} returns false.
|
||||
*
|
||||
* @return bool Whether the block is still the same after the intersection. If it changed (e.g. due to an explosive
|
||||
* being ignited), this should return false.
|
||||
*/
|
||||
@ -572,6 +634,19 @@ class Block{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a direction vector describing which way an entity intersecting this block should be pushed.
|
||||
* This is used by liquids to push entities in liquid currents.
|
||||
*
|
||||
* The returned vector is summed with vectors from every other block the entity is intersecting, and normalized to
|
||||
* produce a final direction vector.
|
||||
*
|
||||
* WARNING: This will not be called if {@link Block::hasEntityCollision()} does not return true!
|
||||
*/
|
||||
public function addVelocityToEntity(Entity $entity) : ?Vector3{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an entity lands on this block (usually due to falling).
|
||||
* @return float|null The new vertical velocity of the entity, or null if unchanged.
|
||||
@ -581,6 +656,13 @@ class Block{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of collision bounding boxes for this block.
|
||||
* These are used for:
|
||||
* - entity movement collision checks (to ensure entities can't clip through blocks)
|
||||
* - projectile flight paths
|
||||
* - block placement (to ensure the player can't place blocks inside itself or another entity)
|
||||
* - anti-cheat checks in plugins
|
||||
*
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
final public function getCollisionBoxes() : array{
|
||||
@ -611,6 +693,10 @@ class Block{
|
||||
return [AxisAlignedBB::one()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of support that the block can provide on the given face. This is used to determine whether
|
||||
* blocks placed on the given face can be supported by this block.
|
||||
*/
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::FULL();
|
||||
}
|
||||
@ -621,6 +707,10 @@ class Block{
|
||||
return count($bb) === 1 && $bb[0]->getAverageEdgeLength() >= 1 && $bb[0]->isCube();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a ray trace along the line between the two positions using the block's collision boxes.
|
||||
* Returns the intersection point closest to pos1, or null if no intersection occurred.
|
||||
*/
|
||||
public function calculateIntercept(Vector3 $pos1, Vector3 $pos2) : ?RayTraceResult{
|
||||
$bbs = $this->getCollisionBoxes();
|
||||
if(count($bbs) === 0){
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,16 +17,18 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\BlockBreakInfo as BreakInfo;
|
||||
use pocketmine\block\BlockIdentifier as BID;
|
||||
use pocketmine\block\BlockIdentifierFlattened as BIDFlattened;
|
||||
use pocketmine\block\BlockLegacyIds as Ids;
|
||||
use pocketmine\block\BlockLegacyMetadata as Meta;
|
||||
use pocketmine\block\BlockToolType as ToolType;
|
||||
use pocketmine\block\tile\Banner as TileBanner;
|
||||
use pocketmine\block\tile\Barrel as TileBarrel;
|
||||
use pocketmine\block\tile\Beacon as TileBeacon;
|
||||
@ -112,184 +114,184 @@ class BlockFactory{
|
||||
$this->blocksDirectSkyLight = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, false));
|
||||
$this->blastResistance = \SplFixedArray::fromArray(array_fill(0, 1024 << Block::INTERNAL_METADATA_BITS, 0.0));
|
||||
|
||||
$railBreakInfo = new BlockBreakInfo(0.7);
|
||||
$railBreakInfo = new BreakInfo(0.7);
|
||||
$this->registerAllMeta(new ActivatorRail(new BID(Ids::ACTIVATOR_RAIL, 0), "Activator Rail", $railBreakInfo));
|
||||
$this->registerAllMeta(new Air(new BID(Ids::AIR, 0), "Air", BlockBreakInfo::indestructible(-1.0)));
|
||||
$this->registerAllMeta(new Anvil(new BID(Ids::ANVIL, 0), "Anvil", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)));
|
||||
$this->registerAllMeta(new Bamboo(new BID(Ids::BAMBOO, 0), "Bamboo", new class(2.0 /* 1.0 in PC */, BlockToolType::AXE) extends BlockBreakInfo{
|
||||
$this->registerAllMeta(new Air(new BID(Ids::AIR, 0), "Air", BreakInfo::indestructible(-1.0)));
|
||||
$this->registerAllMeta(new Anvil(new BID(Ids::ANVIL, 0), "Anvil", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)));
|
||||
$this->registerAllMeta(new Bamboo(new BID(Ids::BAMBOO, 0), "Bamboo", new class(2.0 /* 1.0 in PC */, ToolType::AXE) extends BreakInfo{
|
||||
public function getBreakTime(Item $item) : float{
|
||||
if($item->getBlockToolType() === BlockToolType::SWORD){
|
||||
if($item->getBlockToolType() === ToolType::SWORD){
|
||||
return 0.0;
|
||||
}
|
||||
return parent::getBreakTime($item);
|
||||
}
|
||||
}));
|
||||
$this->registerAllMeta(new BambooSapling(new BID(Ids::BAMBOO_SAPLING, 0), "Bamboo Sapling", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new BambooSapling(new BID(Ids::BAMBOO_SAPLING, 0), "Bamboo Sapling", BreakInfo::instant()));
|
||||
|
||||
$bannerBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE);
|
||||
$bannerBreakInfo = new BreakInfo(1.0, ToolType::AXE);
|
||||
$this->registerAllMeta(new FloorBanner(new BID(Ids::STANDING_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Banner", $bannerBreakInfo));
|
||||
$this->registerAllMeta(new WallBanner(new BID(Ids::WALL_BANNER, 0, ItemIds::BANNER, TileBanner::class), "Wall Banner", $bannerBreakInfo));
|
||||
$this->registerAllMeta(new Barrel(new BID(Ids::BARREL, 0, null, TileBarrel::class), "Barrel", new BlockBreakInfo(2.5, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new Transparent(new BID(Ids::BARRIER, 0), "Barrier", BlockBreakInfo::indestructible()));
|
||||
$this->registerAllMeta(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BlockBreakInfo(3.0)));
|
||||
$this->registerAllMeta(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block", new BlockBreakInfo(0.2)));
|
||||
$this->registerAllMeta(new Bedrock(new BID(Ids::BEDROCK, 0), "Bedrock", BlockBreakInfo::indestructible()));
|
||||
$this->registerAllMeta(new Barrel(new BID(Ids::BARREL, 0, null, TileBarrel::class), "Barrel", new BreakInfo(2.5, ToolType::AXE)));
|
||||
$this->registerAllMeta(new Transparent(new BID(Ids::BARRIER, 0), "Barrier", BreakInfo::indestructible()));
|
||||
$this->registerAllMeta(new Beacon(new BID(Ids::BEACON, 0, null, TileBeacon::class), "Beacon", new BreakInfo(3.0)));
|
||||
$this->registerAllMeta(new Bed(new BID(Ids::BED_BLOCK, 0, ItemIds::BED, TileBed::class), "Bed Block", new BreakInfo(0.2)));
|
||||
$this->registerAllMeta(new Bedrock(new BID(Ids::BEDROCK, 0), "Bedrock", BreakInfo::indestructible()));
|
||||
|
||||
$this->registerAllMeta(new Beetroot(new BID(Ids::BEETROOT_BLOCK, 0), "Beetroot Block", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Bell(new BID(Ids::BELL, 0, null, TileBell::class), "Bell", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new BlueIce(new BID(Ids::BLUE_ICE, 0), "Blue Ice", new BlockBreakInfo(2.8, BlockToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new BoneBlock(new BID(Ids::BONE_BLOCK, 0), "Bone Block", new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Bookshelf(new BID(Ids::BOOKSHELF, 0), "Bookshelf", new BlockBreakInfo(1.5, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Beetroot(new BID(Ids::BEETROOT_BLOCK, 0), "Beetroot Block", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Bell(new BID(Ids::BELL, 0, null, TileBell::class), "Bell", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new BlueIce(new BID(Ids::BLUE_ICE, 0), "Blue Ice", new BreakInfo(2.8, ToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new BoneBlock(new BID(Ids::BONE_BLOCK, 0), "Bone Block", new BreakInfo(2.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Bookshelf(new BID(Ids::BOOKSHELF, 0), "Bookshelf", new BreakInfo(1.5, ToolType::AXE)));
|
||||
$this->registerAllMeta(new BrewingStand(new BID(Ids::BREWING_STAND_BLOCK, 0, ItemIds::BREWING_STAND, TileBrewingStand::class), "Brewing Stand", new BreakInfo(0.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
|
||||
$bricksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$bricksBreakInfo = new BreakInfo(2.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::BRICK_STAIRS, 0), "Brick Stairs", $bricksBreakInfo));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::BRICK_BLOCK, 0), "Bricks", $bricksBreakInfo));
|
||||
|
||||
$this->registerAllMeta(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM, 0), "Brown Mushroom", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Cactus(new BID(Ids::CACTUS, 0), "Cactus", new BlockBreakInfo(0.4)));
|
||||
$this->registerAllMeta(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake", new BlockBreakInfo(0.5)));
|
||||
$this->registerAllMeta(new Carrot(new BID(Ids::CARROTS, 0), "Carrot Block", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new BrownMushroom(new BID(Ids::BROWN_MUSHROOM, 0), "Brown Mushroom", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Cactus(new BID(Ids::CACTUS, 0), "Cactus", new BreakInfo(0.4)));
|
||||
$this->registerAllMeta(new Cake(new BID(Ids::CAKE_BLOCK, 0, ItemIds::CAKE), "Cake", new BreakInfo(0.5)));
|
||||
$this->registerAllMeta(new Carrot(new BID(Ids::CARROTS, 0), "Carrot Block", BreakInfo::instant()));
|
||||
|
||||
$chestBreakInfo = new BlockBreakInfo(2.5, BlockToolType::AXE);
|
||||
$chestBreakInfo = new BreakInfo(2.5, ToolType::AXE);
|
||||
$this->registerAllMeta(new Chest(new BID(Ids::CHEST, 0, null, TileChest::class), "Chest", $chestBreakInfo));
|
||||
$this->registerAllMeta(new Clay(new BID(Ids::CLAY_BLOCK, 0), "Clay Block", new BlockBreakInfo(0.6, BlockToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Coal(new BID(Ids::COAL_BLOCK, 0), "Coal Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new CoalOre(new BID(Ids::COAL_ORE, 0), "Coal Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Clay(new BID(Ids::CLAY_BLOCK, 0), "Clay Block", new BreakInfo(0.6, ToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Coal(new BID(Ids::COAL_BLOCK, 0), "Coal Block", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new CoalOre(new BID(Ids::COAL_ORE, 0), "Coal Ore", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
|
||||
$cobblestoneBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$cobblestoneBreakInfo = new BreakInfo(2.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$this->registerAllMeta($cobblestone = new Opaque(new BID(Ids::COBBLESTONE, 0), "Cobblestone", $cobblestoneBreakInfo));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::MOSSY_COBBLESTONE, 0), "Mossy Cobblestone", $cobblestoneBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::COBBLESTONE_STAIRS, 0), "Cobblestone Stairs", $cobblestoneBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::MOSSY_COBBLESTONE_STAIRS, 0), "Mossy Cobblestone Stairs", $cobblestoneBreakInfo));
|
||||
|
||||
$this->registerAllMeta(new Cobweb(new BID(Ids::COBWEB, 0), "Cobweb", new BlockBreakInfo(4.0, BlockToolType::SWORD | BlockToolType::SHEARS, 1)));
|
||||
$this->registerAllMeta(new CocoaBlock(new BID(Ids::COCOA, 0), "Cocoa Block", new BlockBreakInfo(0.2, BlockToolType::AXE, 0, 15.0)));
|
||||
$this->registerAllMeta(new CoralBlock(new BID(Ids::CORAL_BLOCK, 0), "Coral Block", new BlockBreakInfo(7.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new CraftingTable(new BID(Ids::CRAFTING_TABLE, 0), "Crafting Table", new BlockBreakInfo(2.5, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, [Ids::DAYLIGHT_DETECTOR_INVERTED], 0, null, TileDaylightSensor::class), "Daylight Sensor", new BlockBreakInfo(0.2, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new DeadBush(new BID(Ids::DEADBUSH, 0), "Dead Bush", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)));
|
||||
$this->registerAllMeta(new Cobweb(new BID(Ids::COBWEB, 0), "Cobweb", new BreakInfo(4.0, ToolType::SWORD | ToolType::SHEARS, 1)));
|
||||
$this->registerAllMeta(new CocoaBlock(new BID(Ids::COCOA, 0), "Cocoa Block", new BreakInfo(0.2, ToolType::AXE, 0, 15.0)));
|
||||
$this->registerAllMeta(new CoralBlock(new BID(Ids::CORAL_BLOCK, 0), "Coral Block", new BreakInfo(7.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new CraftingTable(new BID(Ids::CRAFTING_TABLE, 0), "Crafting Table", new BreakInfo(2.5, ToolType::AXE)));
|
||||
$this->registerAllMeta(new DaylightSensor(new BIDFlattened(Ids::DAYLIGHT_DETECTOR, [Ids::DAYLIGHT_DETECTOR_INVERTED], 0, null, TileDaylightSensor::class), "Daylight Sensor", new BreakInfo(0.2, ToolType::AXE)));
|
||||
$this->registerAllMeta(new DeadBush(new BID(Ids::DEADBUSH, 0), "Dead Bush", BreakInfo::instant(ToolType::SHEARS, 1)));
|
||||
$this->registerAllMeta(new DetectorRail(new BID(Ids::DETECTOR_RAIL, 0), "Detector Rail", $railBreakInfo));
|
||||
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::DIAMOND_BLOCK, 0), "Diamond Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Dirt(new BID(Ids::DIRT, 0), "Dirt", new BlockBreakInfo(0.5, BlockToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::DIAMOND_BLOCK, 0), "Diamond Block", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new DiamondOre(new BID(Ids::DIAMOND_ORE, 0), "Diamond Ore", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Dirt(new BID(Ids::DIRT, 0), "Dirt", new BreakInfo(0.5, ToolType::SHOVEL)));
|
||||
$this->registerAllMeta(
|
||||
new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower", BlockBreakInfo::instant()),
|
||||
new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac", BlockBreakInfo::instant()),
|
||||
new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush", BlockBreakInfo::instant()),
|
||||
new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony", BlockBreakInfo::instant()),
|
||||
new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)),
|
||||
new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)),
|
||||
new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_SUNFLOWER), "Sunflower", BreakInfo::instant()),
|
||||
new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LILAC), "Lilac", BreakInfo::instant()),
|
||||
new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_ROSE_BUSH), "Rose Bush", BreakInfo::instant()),
|
||||
new DoublePlant(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_PEONY), "Peony", BreakInfo::instant()),
|
||||
new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_TALLGRASS), "Double Tallgrass", BreakInfo::instant(ToolType::SHEARS, 1)),
|
||||
new DoubleTallGrass(new BID(Ids::DOUBLE_PLANT, Meta::DOUBLE_PLANT_LARGE_FERN), "Large Fern", BreakInfo::instant(ToolType::SHEARS, 1)),
|
||||
);
|
||||
$this->registerAllMeta(new DragonEgg(new BID(Ids::DRAGON_EGG, 0), "Dragon Egg", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK, 0), "Dried Kelp Block", new BlockBreakInfo(0.5, BlockToolType::NONE, 0, 12.5)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::EMERALD_BLOCK, 0), "Emerald Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new EmeraldOre(new BID(Ids::EMERALD_ORE, 0), "Emerald Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)));
|
||||
$this->registerAllMeta(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME, 0), "End Portal Frame", BlockBreakInfo::indestructible()));
|
||||
$this->registerAllMeta(new EndRod(new BID(Ids::END_ROD, 0), "End Rod", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::END_STONE, 0), "End Stone", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0)));
|
||||
$this->registerAllMeta(new DragonEgg(new BID(Ids::DRAGON_EGG, 0), "Dragon Egg", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new DriedKelp(new BID(Ids::DRIED_KELP_BLOCK, 0), "Dried Kelp Block", new BreakInfo(0.5, ToolType::NONE, 0, 12.5)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::EMERALD_BLOCK, 0), "Emerald Block", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new EmeraldOre(new BID(Ids::EMERALD_ORE, 0), "Emerald Ore", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new EnchantingTable(new BID(Ids::ENCHANTING_TABLE, 0, null, TileEnchantingTable::class), "Enchanting Table", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 6000.0)));
|
||||
$this->registerAllMeta(new EndPortalFrame(new BID(Ids::END_PORTAL_FRAME, 0), "End Portal Frame", BreakInfo::indestructible()));
|
||||
$this->registerAllMeta(new EndRod(new BID(Ids::END_ROD, 0), "End Rod", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::END_STONE, 0), "End Stone", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 45.0)));
|
||||
|
||||
$endBrickBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 4.0);
|
||||
$endBrickBreakInfo = new BreakInfo(0.8, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 4.0);
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::END_BRICKS, 0), "End Stone Bricks", $endBrickBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::END_BRICK_STAIRS, 0), "End Stone Brick Stairs", $endBrickBreakInfo));
|
||||
|
||||
$this->registerAllMeta(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest", new BlockBreakInfo(22.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0)));
|
||||
$this->registerAllMeta(new Farmland(new BID(Ids::FARMLAND, 0), "Farmland", new BlockBreakInfo(0.6, BlockToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Fire(new BID(Ids::FIRE, 0), "Fire Block", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new FletchingTable(new BID(Ids::FLETCHING_TABLE, 0), "Fletching Table", new BlockBreakInfo(2.5, BlockToolType::AXE, 0, 2.5)));
|
||||
$this->registerAllMeta(new Flower(new BID(Ids::DANDELION, 0), "Dandelion", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new EnderChest(new BID(Ids::ENDER_CHEST, 0, null, TileEnderChest::class), "Ender Chest", new BreakInfo(22.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 3000.0)));
|
||||
$this->registerAllMeta(new Farmland(new BID(Ids::FARMLAND, 0), "Farmland", new BreakInfo(0.6, ToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Fire(new BID(Ids::FIRE, 0), "Fire Block", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new FletchingTable(new BID(Ids::FLETCHING_TABLE, 0), "Fletching Table", new BreakInfo(2.5, ToolType::AXE, 0, 2.5)));
|
||||
$this->registerAllMeta(new Flower(new BID(Ids::DANDELION, 0), "Dandelion", BreakInfo::instant()));
|
||||
$this->registerAllMeta(
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip", BlockBreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_POPPY), "Poppy", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ALLIUM), "Allium", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_AZURE_BLUET), "Azure Bluet", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_BLUE_ORCHID), "Blue Orchid", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_CORNFLOWER), "Cornflower", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_LILY_OF_THE_VALLEY), "Lily of the Valley", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_ORANGE_TULIP), "Orange Tulip", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_OXEYE_DAISY), "Oxeye Daisy", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_PINK_TULIP), "Pink Tulip", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_RED_TULIP), "Red Tulip", BreakInfo::instant()),
|
||||
new Flower(new BID(Ids::RED_FLOWER, Meta::FLOWER_WHITE_TULIP), "White Tulip", BreakInfo::instant()),
|
||||
);
|
||||
$this->registerAllMeta(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice", new BlockBreakInfo(2.5, BlockToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileNormalFurnace::class), "Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Furnace(new BIDFlattened(Ids::BLAST_FURNACE, [Ids::LIT_BLAST_FURNACE], 0, null, TileBlastFurnace::class), "Blast Furnace", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Furnace(new BIDFlattened(Ids::SMOKER, [Ids::LIT_SMOKER], 0, null, TileSmoker::class), "Smoker", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new FlowerPot(new BID(Ids::FLOWER_POT_BLOCK, 0, ItemIds::FLOWER_POT, TileFlowerPot::class), "Flower Pot", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new FrostedIce(new BID(Ids::FROSTED_ICE, 0), "Frosted Ice", new BreakInfo(2.5, ToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new Furnace(new BIDFlattened(Ids::FURNACE, [Ids::LIT_FURNACE], 0, null, TileNormalFurnace::class), "Furnace", new BreakInfo(3.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Furnace(new BIDFlattened(Ids::BLAST_FURNACE, [Ids::LIT_BLAST_FURNACE], 0, null, TileBlastFurnace::class), "Blast Furnace", new BreakInfo(3.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Furnace(new BIDFlattened(Ids::SMOKER, [Ids::LIT_SMOKER], 0, null, TileSmoker::class), "Smoker", new BreakInfo(3.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
|
||||
$glassBreakInfo = new BlockBreakInfo(0.3);
|
||||
$glassBreakInfo = new BreakInfo(0.3);
|
||||
$this->registerAllMeta(new Glass(new BID(Ids::GLASS, 0), "Glass", $glassBreakInfo));
|
||||
$this->registerAllMeta(new GlassPane(new BID(Ids::GLASS_PANE, 0), "Glass Pane", $glassBreakInfo));
|
||||
$this->registerAllMeta(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN, 0), "Glowing Obsidian", new BlockBreakInfo(10.0, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 50.0)));
|
||||
$this->registerAllMeta(new Glowstone(new BID(Ids::GLOWSTONE, 0), "Glowstone", new BlockBreakInfo(0.3, BlockToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::GOLD_BLOCK, 0), "Gold Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::GOLD_ORE, 0), "Gold Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new GlowingObsidian(new BID(Ids::GLOWINGOBSIDIAN, 0), "Glowing Obsidian", new BreakInfo(10.0, ToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 50.0)));
|
||||
$this->registerAllMeta(new Glowstone(new BID(Ids::GLOWSTONE, 0), "Glowstone", new BreakInfo(0.3, ToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::GOLD_BLOCK, 0), "Gold Block", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::GOLD_ORE, 0), "Gold Ore", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())));
|
||||
|
||||
$grassBreakInfo = new BlockBreakInfo(0.6, BlockToolType::SHOVEL);
|
||||
$grassBreakInfo = new BreakInfo(0.6, ToolType::SHOVEL);
|
||||
$this->registerAllMeta(new Grass(new BID(Ids::GRASS, 0), "Grass", $grassBreakInfo));
|
||||
$this->registerAllMeta(new GrassPath(new BID(Ids::GRASS_PATH, 0), "Grass Path", $grassBreakInfo));
|
||||
$this->registerAllMeta(new Gravel(new BID(Ids::GRAVEL, 0), "Gravel", new BlockBreakInfo(0.6, BlockToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Gravel(new BID(Ids::GRAVEL, 0), "Gravel", new BreakInfo(0.6, ToolType::SHOVEL)));
|
||||
|
||||
$hardenedClayBreakInfo = new BlockBreakInfo(1.25, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 21.0);
|
||||
$hardenedClayBreakInfo = new BreakInfo(1.25, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 21.0);
|
||||
$this->registerAllMeta(new HardenedClay(new BID(Ids::HARDENED_CLAY, 0), "Hardened Clay", $hardenedClayBreakInfo));
|
||||
|
||||
$hardenedGlassBreakInfo = new BlockBreakInfo(10.0);
|
||||
$hardenedGlassBreakInfo = new BreakInfo(10.0);
|
||||
$this->registerAllMeta(new HardenedGlass(new BID(Ids::HARD_GLASS, 0), "Hardened Glass", $hardenedGlassBreakInfo));
|
||||
$this->registerAllMeta(new HardenedGlassPane(new BID(Ids::HARD_GLASS_PANE, 0), "Hardened Glass Pane", $hardenedGlassBreakInfo));
|
||||
$this->registerAllMeta(new HayBale(new BID(Ids::HAY_BALE, 0), "Hay Bale", new BlockBreakInfo(0.5)));
|
||||
$this->registerAllMeta(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0)));
|
||||
$this->registerAllMeta(new Ice(new BID(Ids::ICE, 0), "Ice", new BlockBreakInfo(0.5, BlockToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new HayBale(new BID(Ids::HAY_BALE, 0), "Hay Bale", new BreakInfo(0.5)));
|
||||
$this->registerAllMeta(new Hopper(new BID(Ids::HOPPER_BLOCK, 0, ItemIds::HOPPER, TileHopper::class), "Hopper", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 15.0)));
|
||||
$this->registerAllMeta(new Ice(new BID(Ids::ICE, 0), "Ice", new BreakInfo(0.5, ToolType::PICKAXE)));
|
||||
|
||||
$updateBlockBreakInfo = new BlockBreakInfo(1.0);
|
||||
$updateBlockBreakInfo = new BreakInfo(1.0);
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::INFO_UPDATE, 0), "update!", $updateBlockBreakInfo));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::INFO_UPDATE2, 0), "ate!upd", $updateBlockBreakInfo));
|
||||
$this->registerAllMeta(new Transparent(new BID(Ids::INVISIBLEBEDROCK, 0), "Invisible Bedrock", BlockBreakInfo::indestructible()));
|
||||
$this->registerAllMeta(new Transparent(new BID(Ids::INVISIBLEBEDROCK, 0), "Invisible Bedrock", BreakInfo::indestructible()));
|
||||
|
||||
$ironBreakInfo = new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0);
|
||||
$ironBreakInfo = new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel(), 30.0);
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::IRON_BLOCK, 0), "Iron Block", $ironBreakInfo));
|
||||
$this->registerAllMeta(new Thin(new BID(Ids::IRON_BARS, 0), "Iron Bars", $ironBreakInfo));
|
||||
$ironDoorBreakInfo = new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0);
|
||||
$ironDoorBreakInfo = new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 25.0);
|
||||
$this->registerAllMeta(new Door(new BID(Ids::IRON_DOOR_BLOCK, 0, ItemIds::IRON_DOOR), "Iron Door", $ironDoorBreakInfo));
|
||||
$this->registerAllMeta(new Trapdoor(new BID(Ids::IRON_TRAPDOOR, 0), "Iron Trapdoor", $ironDoorBreakInfo));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::IRON_ORE, 0), "Iron Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame", new BlockBreakInfo(0.25)));
|
||||
$this->registerAllMeta(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox", new BlockBreakInfo(0.8, BlockToolType::AXE))); //TODO: in PC the hardness is 2.0, not 0.8, unsure if this is a MCPE bug or not
|
||||
$this->registerAllMeta(new Ladder(new BID(Ids::LADDER, 0), "Ladder", new BlockBreakInfo(0.4, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new Lantern(new BID(Ids::LANTERN, 0), "Lantern", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::LAPIS_BLOCK, 0), "Lapis Lazuli Block", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, [Ids::STILL_LAVA], 0), "Lava", BlockBreakInfo::indestructible(500.0)));
|
||||
$this->registerAllMeta(new Lectern(new BID(Ids::LECTERN, 0, ItemIds::LECTERN, TileLectern::class), "Lectern", new BlockBreakInfo(2.0, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new Lever(new BID(Ids::LEVER, 0), "Lever", new BlockBreakInfo(0.5)));
|
||||
$this->registerAllMeta(new Loom(new BID(Ids::LOOM, 0), "Loom", new BlockBreakInfo(2.5, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new Magma(new BID(Ids::MAGMA, 0), "Magma Block", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Melon(new BID(Ids::MELON_BLOCK, 0), "Melon Block", new BlockBreakInfo(1.0, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Mycelium(new BID(Ids::MYCELIUM, 0), "Mycelium", new BlockBreakInfo(0.6, BlockToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::IRON_ORE, 0), "Iron Ore", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new ItemFrame(new BID(Ids::FRAME_BLOCK, 0, ItemIds::FRAME, TileItemFrame::class), "Item Frame", new BreakInfo(0.25)));
|
||||
$this->registerAllMeta(new Jukebox(new BID(Ids::JUKEBOX, 0, ItemIds::JUKEBOX, TileJukebox::class), "Jukebox", new BreakInfo(0.8, ToolType::AXE))); //TODO: in PC the hardness is 2.0, not 0.8, unsure if this is a MCPE bug or not
|
||||
$this->registerAllMeta(new Ladder(new BID(Ids::LADDER, 0), "Ladder", new BreakInfo(0.4, ToolType::AXE)));
|
||||
$this->registerAllMeta(new Lantern(new BID(Ids::LANTERN, 0), "Lantern", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::LAPIS_BLOCK, 0), "Lapis Lazuli Block", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new LapisOre(new BID(Ids::LAPIS_ORE, 0), "Lapis Lazuli Ore", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::STONE()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Lava(new BIDFlattened(Ids::FLOWING_LAVA, [Ids::STILL_LAVA], 0), "Lava", BreakInfo::indestructible(500.0)));
|
||||
$this->registerAllMeta(new Lectern(new BID(Ids::LECTERN, 0, ItemIds::LECTERN, TileLectern::class), "Lectern", new BreakInfo(2.0, ToolType::AXE)));
|
||||
$this->registerAllMeta(new Lever(new BID(Ids::LEVER, 0), "Lever", new BreakInfo(0.5)));
|
||||
$this->registerAllMeta(new Loom(new BID(Ids::LOOM, 0), "Loom", new BreakInfo(2.5, ToolType::AXE)));
|
||||
$this->registerAllMeta(new Magma(new BID(Ids::MAGMA, 0), "Magma Block", new BreakInfo(0.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Melon(new BID(Ids::MELON_BLOCK, 0), "Melon Block", new BreakInfo(1.0, ToolType::AXE)));
|
||||
$this->registerAllMeta(new MelonStem(new BID(Ids::MELON_STEM, 0, ItemIds::MELON_SEEDS), "Melon Stem", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new MonsterSpawner(new BID(Ids::MOB_SPAWNER, 0, null, TileMonsterSpawner::class), "Monster Spawner", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Mycelium(new BID(Ids::MYCELIUM, 0), "Mycelium", new BreakInfo(0.6, ToolType::SHOVEL)));
|
||||
|
||||
$netherBrickBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$netherBrickBreakInfo = new BreakInfo(2.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::NETHER_BRICK_BLOCK, 0), "Nether Bricks", $netherBrickBreakInfo));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::RED_NETHER_BRICK, 0), "Red Nether Bricks", $netherBrickBreakInfo));
|
||||
$this->registerAllMeta(new Fence(new BID(Ids::NETHER_BRICK_FENCE, 0), "Nether Brick Fence", $netherBrickBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::NETHER_BRICK_STAIRS, 0), "Nether Brick Stairs", $netherBrickBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::RED_NETHER_BRICK_STAIRS, 0), "Red Nether Brick Stairs", $netherBrickBreakInfo));
|
||||
$this->registerAllMeta(new NetherPortal(new BID(Ids::PORTAL, 0), "Nether Portal", BlockBreakInfo::indestructible(0.0)));
|
||||
$this->registerAllMeta(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE, 0), "Nether Quartz Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new NetherReactor(new BID(Ids::NETHERREACTOR, 0), "Nether Reactor Core", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::NETHER_WART_BLOCK, 0), "Nether Wart Block", new BlockBreakInfo(1.0, BlockToolType::HOE)));
|
||||
$this->registerAllMeta(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Netherrack(new BID(Ids::NETHERRACK, 0), "Netherrack", new BlockBreakInfo(0.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block", new BlockBreakInfo(0.8, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::OBSIDIAN, 0), "Obsidian", new BlockBreakInfo(35.0 /* 50 in PC */, BlockToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0)));
|
||||
$this->registerAllMeta(new PackedIce(new BID(Ids::PACKED_ICE, 0), "Packed Ice", new BlockBreakInfo(0.5, BlockToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new Podzol(new BID(Ids::PODZOL, 0), "Podzol", new BlockBreakInfo(0.5, BlockToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Potato(new BID(Ids::POTATOES, 0), "Potato Block", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new NetherPortal(new BID(Ids::PORTAL, 0), "Nether Portal", BreakInfo::indestructible(0.0)));
|
||||
$this->registerAllMeta(new NetherQuartzOre(new BID(Ids::NETHER_QUARTZ_ORE, 0), "Nether Quartz Ore", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new NetherReactor(new BID(Ids::NETHERREACTOR, 0), "Nether Reactor Core", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::NETHER_WART_BLOCK, 0), "Nether Wart Block", new BreakInfo(1.0, ToolType::HOE)));
|
||||
$this->registerAllMeta(new NetherWartPlant(new BID(Ids::NETHER_WART_PLANT, 0, ItemIds::NETHER_WART), "Nether Wart", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Netherrack(new BID(Ids::NETHERRACK, 0), "Netherrack", new BreakInfo(0.4, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Note(new BID(Ids::NOTEBLOCK, 0, null, TileNote::class), "Note Block", new BreakInfo(0.8, ToolType::AXE)));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::OBSIDIAN, 0), "Obsidian", new BreakInfo(35.0 /* 50 in PC */, ToolType::PICKAXE, ToolTier::DIAMOND()->getHarvestLevel(), 6000.0)));
|
||||
$this->registerAllMeta(new PackedIce(new BID(Ids::PACKED_ICE, 0), "Packed Ice", new BreakInfo(0.5, ToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new Podzol(new BID(Ids::PODZOL, 0), "Podzol", new BreakInfo(0.5, ToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Potato(new BID(Ids::POTATOES, 0), "Potato Block", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new PoweredRail(new BID(Ids::GOLDEN_RAIL, 0), "Powered Rail", $railBreakInfo));
|
||||
|
||||
$prismarineBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$prismarineBreakInfo = new BreakInfo(1.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$this->registerAllMeta(
|
||||
new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_NORMAL), "Prismarine", $prismarineBreakInfo),
|
||||
new Opaque(new BID(Ids::PRISMARINE, Meta::PRISMARINE_DARK), "Dark Prismarine", $prismarineBreakInfo),
|
||||
@ -299,21 +301,21 @@ class BlockFactory{
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::DARK_PRISMARINE_STAIRS, 0), "Dark Prismarine Stairs", $prismarineBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::PRISMARINE_STAIRS, 0), "Prismarine Stairs", $prismarineBreakInfo));
|
||||
|
||||
$pumpkinBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE);
|
||||
$pumpkinBreakInfo = new BreakInfo(1.0, ToolType::AXE);
|
||||
$this->registerAllMeta(new Pumpkin(new BID(Ids::PUMPKIN, 0), "Pumpkin", $pumpkinBreakInfo));
|
||||
$this->registerAllMeta(new CarvedPumpkin(new BID(Ids::CARVED_PUMPKIN, 0), "Carved Pumpkin", $pumpkinBreakInfo));
|
||||
$this->registerAllMeta(new LitPumpkin(new BID(Ids::JACK_O_LANTERN, 0), "Jack o'Lantern", $pumpkinBreakInfo));
|
||||
|
||||
$this->registerAllMeta(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new PumpkinStem(new BID(Ids::PUMPKIN_STEM, 0, ItemIds::PUMPKIN_SEEDS), "Pumpkin Stem", BreakInfo::instant()));
|
||||
|
||||
$purpurBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$purpurBreakInfo = new BreakInfo(1.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$this->registerAllMeta(
|
||||
new Opaque(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_NORMAL), "Purpur Block", $purpurBreakInfo),
|
||||
new SimplePillar(new BID(Ids::PURPUR_BLOCK, Meta::PURPUR_PILLAR), "Purpur Pillar", $purpurBreakInfo)
|
||||
);
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::PURPUR_STAIRS, 0), "Purpur Stairs", $purpurBreakInfo));
|
||||
|
||||
$quartzBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$quartzBreakInfo = new BreakInfo(0.8, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$this->registerAllMeta(
|
||||
new Opaque(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_NORMAL), "Quartz Block", $quartzBreakInfo),
|
||||
new SimplePillar(new BID(Ids::QUARTZ_BLOCK, Meta::QUARTZ_CHISELED), "Chiseled Quartz Block", $quartzBreakInfo),
|
||||
@ -324,33 +326,33 @@ class BlockFactory{
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_QUARTZ_STAIRS, 0), "Smooth Quartz Stairs", $quartzBreakInfo));
|
||||
|
||||
$this->registerAllMeta(new Rail(new BID(Ids::RAIL, 0), "Rail", $railBreakInfo));
|
||||
$this->registerAllMeta(new RedMushroom(new BID(Ids::RED_MUSHROOM, 0), "Red Mushroom", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Redstone(new BID(Ids::REDSTONE_BLOCK, 0), "Redstone Block", new BlockBreakInfo(5.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, [Ids::POWERED_COMPARATOR], 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, [Ids::LIT_REDSTONE_LAMP], 0), "Redstone Lamp", new BlockBreakInfo(0.3)));
|
||||
$this->registerAllMeta(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, [Ids::LIT_REDSTONE_ORE], 0), "Redstone Ore", new BlockBreakInfo(3.0, BlockToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, [Ids::POWERED_REPEATER], 0, ItemIds::REPEATER), "Redstone Repeater", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, [Ids::UNLIT_REDSTONE_TORCH], 0), "Redstone Torch", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new RedMushroom(new BID(Ids::RED_MUSHROOM, 0), "Red Mushroom", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Redstone(new BID(Ids::REDSTONE_BLOCK, 0), "Redstone Block", new BreakInfo(5.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0)));
|
||||
$this->registerAllMeta(new RedstoneComparator(new BIDFlattened(Ids::UNPOWERED_COMPARATOR, [Ids::POWERED_COMPARATOR], 0, ItemIds::COMPARATOR, TileComparator::class), "Redstone Comparator", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new RedstoneLamp(new BIDFlattened(Ids::REDSTONE_LAMP, [Ids::LIT_REDSTONE_LAMP], 0), "Redstone Lamp", new BreakInfo(0.3)));
|
||||
$this->registerAllMeta(new RedstoneOre(new BIDFlattened(Ids::REDSTONE_ORE, [Ids::LIT_REDSTONE_ORE], 0), "Redstone Ore", new BreakInfo(3.0, ToolType::PICKAXE, ToolTier::IRON()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new RedstoneRepeater(new BIDFlattened(Ids::UNPOWERED_REPEATER, [Ids::POWERED_REPEATER], 0, ItemIds::REPEATER), "Redstone Repeater", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new RedstoneTorch(new BIDFlattened(Ids::REDSTONE_TORCH, [Ids::UNLIT_REDSTONE_TORCH], 0), "Redstone Torch", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new RedstoneWire(new BID(Ids::REDSTONE_WIRE, 0, ItemIds::REDSTONE), "Redstone", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Reserved6(new BID(Ids::RESERVED6, 0), "reserved6", BreakInfo::instant()));
|
||||
|
||||
$sandBreakInfo = new BlockBreakInfo(0.5, BlockToolType::SHOVEL);
|
||||
$sandBreakInfo = new BreakInfo(0.5, ToolType::SHOVEL);
|
||||
$this->registerAllMeta(
|
||||
new Sand(new BID(Ids::SAND, 0), "Sand", $sandBreakInfo),
|
||||
new Sand(new BID(Ids::SAND, 1), "Red Sand", $sandBreakInfo)
|
||||
);
|
||||
$this->registerAllMeta(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern", new BlockBreakInfo(0.3)));
|
||||
$this->registerAllMeta(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, ItemIds::SKULL, TileSkull::class), "Mob Head", new BlockBreakInfo(1.0)));
|
||||
$this->registerAllMeta(new Slime(new BID(Ids::SLIME, 0), "Slime Block", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Snow(new BID(Ids::SNOW, 0), "Snow Block", new BlockBreakInfo(0.2, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer", new BlockBreakInfo(0.1, BlockToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand", new BlockBreakInfo(0.5, BlockToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Sponge(new BID(Ids::SPONGE, 0), "Sponge", new BlockBreakInfo(0.6, BlockToolType::HOE)));
|
||||
$shulkerBoxBreakInfo = new BlockBreakInfo(2, BlockToolType::PICKAXE);
|
||||
$this->registerAllMeta(new SeaLantern(new BID(Ids::SEALANTERN, 0), "Sea Lantern", new BreakInfo(0.3)));
|
||||
$this->registerAllMeta(new SeaPickle(new BID(Ids::SEA_PICKLE, 0), "Sea Pickle", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Skull(new BID(Ids::MOB_HEAD_BLOCK, 0, ItemIds::SKULL, TileSkull::class), "Mob Head", new BreakInfo(1.0)));
|
||||
$this->registerAllMeta(new Slime(new BID(Ids::SLIME, 0), "Slime Block", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Snow(new BID(Ids::SNOW, 0), "Snow Block", new BreakInfo(0.2, ToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new SnowLayer(new BID(Ids::SNOW_LAYER, 0), "Snow Layer", new BreakInfo(0.1, ToolType::SHOVEL, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new SoulSand(new BID(Ids::SOUL_SAND, 0), "Soul Sand", new BreakInfo(0.5, ToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Sponge(new BID(Ids::SPONGE, 0), "Sponge", new BreakInfo(0.6, ToolType::HOE)));
|
||||
$shulkerBoxBreakInfo = new BreakInfo(2, ToolType::PICKAXE);
|
||||
$this->registerAllMeta(new ShulkerBox(new BID(Ids::UNDYED_SHULKER_BOX, 0, null, TileShulkerBox::class), "Shulker Box", $shulkerBoxBreakInfo));
|
||||
|
||||
$stoneBreakInfo = new BlockBreakInfo(1.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$stoneBreakInfo = new BreakInfo(1.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$this->registerAllMeta(
|
||||
$stone = new class(new BID(Ids::STONE, Meta::STONE_NORMAL), "Stone", $stoneBreakInfo) extends Opaque{
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
@ -374,7 +376,7 @@ class BlockFactory{
|
||||
$crackedStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CRACKED), "Cracked Stone Bricks", $stoneBreakInfo),
|
||||
$chiseledStoneBrick = new Opaque(new BID(Ids::STONEBRICK, Meta::STONE_BRICK_CHISELED), "Chiseled Stone Bricks", $stoneBreakInfo)
|
||||
);
|
||||
$infestedStoneBreakInfo = new BlockBreakInfo(0.75, BlockToolType::PICKAXE);
|
||||
$infestedStoneBreakInfo = new BreakInfo(0.75, ToolType::PICKAXE);
|
||||
$this->registerAllMeta(
|
||||
new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE), "Infested Stone", $infestedStoneBreakInfo, $stone),
|
||||
new InfestedStone(new BID(Ids::MONSTER_EGG, Meta::INFESTED_STONE_BRICK), "Infested Stone Brick", $infestedStoneBreakInfo, $stoneBrick),
|
||||
@ -393,12 +395,12 @@ class BlockFactory{
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::POLISHED_GRANITE_STAIRS, 0), "Polished Granite Stairs", $stoneBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::STONE_BRICK_STAIRS, 0), "Stone Brick Stairs", $stoneBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::MOSSY_STONE_BRICK_STAIRS, 0), "Mossy Stone Brick Stairs", $stoneBreakInfo));
|
||||
$this->registerAllMeta(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button", new BlockBreakInfo(0.5, BlockToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new Stonecutter(new BID(Ids::STONECUTTER_BLOCK, 0, ItemIds::STONECUTTER_BLOCK), "Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate", new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new StoneButton(new BID(Ids::STONE_BUTTON, 0), "Stone Button", new BreakInfo(0.5, ToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new Stonecutter(new BID(Ids::STONECUTTER_BLOCK, 0, ItemIds::STONECUTTER_BLOCK), "Stonecutter", new BreakInfo(3.5, ToolType::PICKAXE)));
|
||||
$this->registerAllMeta(new StonePressurePlate(new BID(Ids::STONE_PRESSURE_PLATE, 0), "Stone Pressure Plate", new BreakInfo(0.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
|
||||
//TODO: in the future this won't be the same for all the types
|
||||
$stoneSlabBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$stoneSlabBreakInfo = new BreakInfo(2.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
|
||||
$getStoneSlabId = static fn(int $stoneSlabId, int $meta) => BlockLegacyIdHelper::getStoneSlabIdentifier($stoneSlabId, $meta);
|
||||
foreach([
|
||||
@ -435,50 +437,50 @@ class BlockFactory{
|
||||
$this->registerSlabWithDoubleHighBitsRemapping($slabType);
|
||||
}
|
||||
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::STONECUTTER, 0), "Legacy Stonecutter", new BlockBreakInfo(3.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new TNT(new BID(Ids::TNT, 0), "TNT", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::STONECUTTER, 0), "Legacy Stonecutter", new BreakInfo(3.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new Sugarcane(new BID(Ids::REEDS_BLOCK, 0, ItemIds::REEDS), "Sugarcane", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new SweetBerryBush(new BID(Ids::SWEET_BERRY_BUSH, 0, ItemIds::SWEET_BERRIES), "Sweet Berry Bush", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new TNT(new BID(Ids::TNT, 0), "TNT", BreakInfo::instant()));
|
||||
$this->registerAllMeta(
|
||||
new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern", BlockBreakInfo::instant(BlockToolType::SHEARS, 1)),
|
||||
new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass", BlockBreakInfo::instant(BlockToolType::SHEARS, 1))
|
||||
new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_FERN), "Fern", BreakInfo::instant(ToolType::SHEARS, 1)),
|
||||
new TallGrass(new BID(Ids::TALLGRASS, Meta::TALLGRASS_NORMAL), "Tall Grass", BreakInfo::instant(ToolType::SHEARS, 1))
|
||||
);
|
||||
$this->registerAllMeta(
|
||||
new Torch(new BID(Ids::COLORED_TORCH_BP, 0), "Blue Torch", BlockBreakInfo::instant()),
|
||||
new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch", BlockBreakInfo::instant())
|
||||
new Torch(new BID(Ids::COLORED_TORCH_BP, 0), "Blue Torch", BreakInfo::instant()),
|
||||
new Torch(new BID(Ids::COLORED_TORCH_BP, 8), "Purple Torch", BreakInfo::instant())
|
||||
);
|
||||
$this->registerAllMeta(
|
||||
new Torch(new BID(Ids::COLORED_TORCH_RG, 0), "Red Torch", BlockBreakInfo::instant()),
|
||||
new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch", BlockBreakInfo::instant())
|
||||
new Torch(new BID(Ids::COLORED_TORCH_RG, 0), "Red Torch", BreakInfo::instant()),
|
||||
new Torch(new BID(Ids::COLORED_TORCH_RG, 8), "Green Torch", BreakInfo::instant())
|
||||
);
|
||||
$this->registerAllMeta(new Torch(new BID(Ids::TORCH, 0), "Torch", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Torch(new BID(Ids::TORCH, 0), "Torch", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new TrappedChest(new BID(Ids::TRAPPED_CHEST, 0, null, TileChest::class), "Trapped Chest", $chestBreakInfo));
|
||||
$this->registerAllMeta(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK, 0), "Tripwire Hook", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH, 0), "Underwater Torch", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Vine(new BID(Ids::VINE, 0), "Vines", new BlockBreakInfo(0.2, BlockToolType::AXE)));
|
||||
$this->registerAllMeta(new Water(new BIDFlattened(Ids::FLOWING_WATER, [Ids::STILL_WATER], 0), "Water", BlockBreakInfo::indestructible(500.0)));
|
||||
$this->registerAllMeta(new WaterLily(new BID(Ids::LILY_PAD, 0), "Lily Pad", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Tripwire(new BID(Ids::TRIPWIRE, 0, ItemIds::STRING), "Tripwire", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new TripwireHook(new BID(Ids::TRIPWIRE_HOOK, 0), "Tripwire Hook", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new UnderwaterTorch(new BID(Ids::UNDERWATER_TORCH, 0), "Underwater Torch", BreakInfo::instant()));
|
||||
$this->registerAllMeta(new Vine(new BID(Ids::VINE, 0), "Vines", new BreakInfo(0.2, ToolType::AXE)));
|
||||
$this->registerAllMeta(new Water(new BIDFlattened(Ids::FLOWING_WATER, [Ids::STILL_WATER], 0), "Water", BreakInfo::indestructible(500.0)));
|
||||
$this->registerAllMeta(new WaterLily(new BID(Ids::LILY_PAD, 0), "Lily Pad", BreakInfo::instant()));
|
||||
|
||||
$weightedPressurePlateBreakInfo = new BlockBreakInfo(0.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$weightedPressurePlateBreakInfo = new BreakInfo(0.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$this->registerAllMeta(new WeightedPressurePlateHeavy(new BID(Ids::HEAVY_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Heavy", $weightedPressurePlateBreakInfo));
|
||||
$this->registerAllMeta(new WeightedPressurePlateLight(new BID(Ids::LIGHT_WEIGHTED_PRESSURE_PLATE, 0), "Weighted Pressure Plate Light", $weightedPressurePlateBreakInfo));
|
||||
$this->registerAllMeta(new Wheat(new BID(Ids::WHEAT_BLOCK, 0), "Wheat Block", BlockBreakInfo::instant()));
|
||||
$this->registerAllMeta(new Wheat(new BID(Ids::WHEAT_BLOCK, 0), "Wheat Block", BreakInfo::instant()));
|
||||
|
||||
$planksBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE, 0, 15.0);
|
||||
$leavesBreakInfo = new class(0.2, BlockToolType::HOE) extends BlockBreakInfo{
|
||||
$planksBreakInfo = new BreakInfo(2.0, ToolType::AXE, 0, 15.0);
|
||||
$leavesBreakInfo = new class(0.2, ToolType::HOE) extends BreakInfo{
|
||||
public function getBreakTime(Item $item) : float{
|
||||
if($item->getBlockToolType() === BlockToolType::SHEARS){
|
||||
if($item->getBlockToolType() === ToolType::SHEARS){
|
||||
return 0.0;
|
||||
}
|
||||
return parent::getBreakTime($item);
|
||||
}
|
||||
};
|
||||
$signBreakInfo = new BlockBreakInfo(1.0, BlockToolType::AXE);
|
||||
$logBreakInfo = new BlockBreakInfo(2.0, BlockToolType::AXE);
|
||||
$woodenDoorBreakInfo = new BlockBreakInfo(3.0, BlockToolType::AXE, 0, 15.0);
|
||||
$woodenButtonBreakInfo = new BlockBreakInfo(0.5, BlockToolType::AXE);
|
||||
$woodenPressurePlateBreakInfo = new BlockBreakInfo(0.5, BlockToolType::AXE);
|
||||
$signBreakInfo = new BreakInfo(1.0, ToolType::AXE);
|
||||
$logBreakInfo = new BreakInfo(2.0, ToolType::AXE);
|
||||
$woodenDoorBreakInfo = new BreakInfo(3.0, ToolType::AXE, 0, 15.0);
|
||||
$woodenButtonBreakInfo = new BreakInfo(0.5, ToolType::AXE);
|
||||
$woodenPressurePlateBreakInfo = new BreakInfo(0.5, ToolType::AXE);
|
||||
|
||||
$planks = [];
|
||||
$saplings = [];
|
||||
@ -489,7 +491,7 @@ class BlockFactory{
|
||||
$magicNumber = $treeType->getMagicNumber();
|
||||
$name = $treeType->getDisplayName();
|
||||
$planks[] = new Planks(new BID(Ids::PLANKS, $magicNumber), $name . " Planks", $planksBreakInfo);
|
||||
$saplings[] = new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", BlockBreakInfo::instant(), $treeType);
|
||||
$saplings[] = new Sapling(new BID(Ids::SAPLING, $magicNumber), $name . " Sapling", BreakInfo::instant(), $treeType);
|
||||
$fences[] = new WoodenFence(new BID(Ids::FENCE, $magicNumber), $name . " Fence", $planksBreakInfo);
|
||||
$this->registerSlabWithDoubleHighBitsRemapping(new WoodenSlab(new BIDFlattened(Ids::WOODEN_SLAB, [Ids::DOUBLE_WOODEN_SLAB], $magicNumber), $name, $planksBreakInfo));
|
||||
|
||||
@ -521,27 +523,26 @@ class BlockFactory{
|
||||
$this->registerAllMeta(...$leaves);
|
||||
$this->registerAllMeta(...$allSidedLogs);
|
||||
|
||||
static $sandstoneTypes = [
|
||||
Meta::SANDSTONE_NORMAL => "",
|
||||
Meta::SANDSTONE_CHISELED => "Chiseled ",
|
||||
Meta::SANDSTONE_CUT => "Cut ",
|
||||
Meta::SANDSTONE_SMOOTH => "Smooth "
|
||||
];
|
||||
$sandstoneBreakInfo = new BlockBreakInfo(0.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$sandstoneBreakInfo = new BreakInfo(0.8, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::RED_SANDSTONE_STAIRS, 0), "Red Sandstone Stairs", $sandstoneBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_RED_SANDSTONE_STAIRS, 0), "Smooth Red Sandstone Stairs", $sandstoneBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::SANDSTONE_STAIRS, 0), "Sandstone Stairs", $sandstoneBreakInfo));
|
||||
$this->registerAllMeta(new Stair(new BID(Ids::SMOOTH_SANDSTONE_STAIRS, 0), "Smooth Sandstone Stairs", $sandstoneBreakInfo));
|
||||
$sandstones = [];
|
||||
$redSandstones = [];
|
||||
foreach($sandstoneTypes as $variant => $prefix){
|
||||
foreach([
|
||||
Meta::SANDSTONE_NORMAL => "",
|
||||
Meta::SANDSTONE_CHISELED => "Chiseled ",
|
||||
Meta::SANDSTONE_CUT => "Cut ",
|
||||
Meta::SANDSTONE_SMOOTH => "Smooth "
|
||||
] as $variant => $prefix){
|
||||
$sandstones[] = new Opaque(new BID(Ids::SANDSTONE, $variant), $prefix . "Sandstone", $sandstoneBreakInfo);
|
||||
$redSandstones[] = new Opaque(new BID(Ids::RED_SANDSTONE, $variant), $prefix . "Red Sandstone", $sandstoneBreakInfo);
|
||||
}
|
||||
$this->registerAllMeta(...$sandstones);
|
||||
$this->registerAllMeta(...$redSandstones);
|
||||
|
||||
$glazedTerracottaBreakInfo = new BlockBreakInfo(1.4, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$glazedTerracottaBreakInfo = new BreakInfo(1.4, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
foreach(DyeColor::getAll() as $color){
|
||||
$coloredName = function(string $name) use($color) : string{
|
||||
return $color->getDisplayName() . " " . $name;
|
||||
@ -554,13 +555,13 @@ class BlockFactory{
|
||||
$this->registerAllMeta(new StainedHardenedClay(new BID(Ids::STAINED_CLAY, 0), "Stained Clay", $hardenedClayBreakInfo));
|
||||
$this->registerAllMeta(new StainedHardenedGlass(new BID(Ids::HARD_STAINED_GLASS, 0), "Stained Hardened Glass", $hardenedGlassBreakInfo));
|
||||
$this->registerAllMeta(new StainedHardenedGlassPane(new BID(Ids::HARD_STAINED_GLASS_PANE, 0), "Stained Hardened Glass Pane", $hardenedGlassBreakInfo));
|
||||
$this->registerAllMeta(new Carpet(new BID(Ids::CARPET, 0), "Carpet", new BlockBreakInfo(0.1)));
|
||||
$this->registerAllMeta(new Concrete(new BID(Ids::CONCRETE, 0), "Concrete", new BlockBreakInfo(1.8, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, 0), "Concrete Powder", new BlockBreakInfo(0.5, BlockToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Wool(new BID(Ids::WOOL, 0), "Wool", new class(0.8, BlockToolType::SHEARS) extends BlockBreakInfo{
|
||||
$this->registerAllMeta(new Carpet(new BID(Ids::CARPET, 0), "Carpet", new BreakInfo(0.1)));
|
||||
$this->registerAllMeta(new Concrete(new BID(Ids::CONCRETE, 0), "Concrete", new BreakInfo(1.8, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel())));
|
||||
$this->registerAllMeta(new ConcretePowder(new BID(Ids::CONCRETE_POWDER, 0), "Concrete Powder", new BreakInfo(0.5, ToolType::SHOVEL)));
|
||||
$this->registerAllMeta(new Wool(new BID(Ids::WOOL, 0), "Wool", new class(0.8, ToolType::SHEARS) extends BreakInfo{
|
||||
public function getBreakTime(Item $item) : float{
|
||||
$time = parent::getBreakTime($item);
|
||||
if($item->getBlockToolType() === BlockToolType::SHEARS){
|
||||
if($item->getBlockToolType() === ToolType::SHEARS){
|
||||
$time *= 3; //shears break compatible blocks 15x faster, but wool 5x
|
||||
}
|
||||
|
||||
@ -569,7 +570,7 @@ class BlockFactory{
|
||||
}));
|
||||
|
||||
//TODO: in the future these won't all have the same hardness; they only do now because of the old metadata crap
|
||||
$wallBreakInfo = new BlockBreakInfo(2.0, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$wallBreakInfo = new BreakInfo(2.0, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel(), 30.0);
|
||||
$this->registerAllMeta(
|
||||
new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_COBBLESTONE), "Cobblestone Wall", $wallBreakInfo),
|
||||
new Wall(new BID(Ids::COBBLESTONE_WALL, Meta::WALL_ANDESITE), "Andesite Wall", $wallBreakInfo),
|
||||
@ -589,7 +590,7 @@ class BlockFactory{
|
||||
|
||||
$this->registerElements();
|
||||
|
||||
$chemistryTableBreakInfo = new BlockBreakInfo(2.5, BlockToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$chemistryTableBreakInfo = new BreakInfo(2.5, ToolType::PICKAXE, ToolTier::WOOD()->getHarvestLevel());
|
||||
$this->registerAllMeta(
|
||||
new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_COMPOUND_CREATOR), "Compound Creator", $chemistryTableBreakInfo),
|
||||
new ChemistryTable(new BID(Ids::CHEMISTRY_TABLE, Meta::CHEMISTRY_ELEMENT_CONSTRUCTOR), "Element Constructor", $chemistryTableBreakInfo),
|
||||
@ -604,17 +605,17 @@ class BlockFactory{
|
||||
$this->registerAllMeta(new Coral(
|
||||
new BID(Ids::CORAL, 0),
|
||||
"Coral",
|
||||
BlockBreakInfo::instant(),
|
||||
BreakInfo::instant(),
|
||||
));
|
||||
$this->registerAllMeta(new FloorCoralFan(
|
||||
new BlockIdentifierFlattened(Ids::CORAL_FAN, [Ids::CORAL_FAN_DEAD], 0, ItemIds::CORAL_FAN),
|
||||
"Coral Fan",
|
||||
BlockBreakInfo::instant(),
|
||||
BreakInfo::instant(),
|
||||
));
|
||||
$this->registerAllMeta(new WallCoralFan(
|
||||
new BlockIdentifierFlattened(Ids::CORAL_FAN_HANG, [Ids::CORAL_FAN_HANG2, Ids::CORAL_FAN_HANG3], 0, ItemIds::CORAL_FAN),
|
||||
"Wall Coral Fan",
|
||||
BlockBreakInfo::instant(),
|
||||
BreakInfo::instant(),
|
||||
));
|
||||
|
||||
//region --- auto-generated TODOs for bedrock-1.11.0 ---
|
||||
@ -756,7 +757,7 @@ class BlockFactory{
|
||||
//shrooms have to be handled one by one because some metas are variants and others aren't, and they can't be
|
||||
//separated by a bitmask
|
||||
|
||||
$mushroomBlockBreakInfo = new BlockBreakInfo(0.2, BlockToolType::AXE);
|
||||
$mushroomBlockBreakInfo = new BreakInfo(0.2, ToolType::AXE);
|
||||
|
||||
$mushroomBlocks = [
|
||||
new BrownMushroomBlock(new BID(Ids::BROWN_MUSHROOM_BLOCK, 0), "Brown Mushroom Block", $mushroomBlockBreakInfo),
|
||||
@ -800,7 +801,7 @@ class BlockFactory{
|
||||
}
|
||||
|
||||
private function registerElements() : void{
|
||||
$instaBreak = BlockBreakInfo::instant();
|
||||
$instaBreak = BreakInfo::instant();
|
||||
$this->registerAllMeta(new Opaque(new BID(Ids::ELEMENT_0, 0), "???", $instaBreak));
|
||||
|
||||
$this->registerAllMeta(new Element(new BID(Ids::ELEMENT_1, 0), "Hydrogen", $instaBreak, "h", 1, 5));
|
||||
@ -1054,7 +1055,7 @@ class BlockFactory{
|
||||
if($this->fullList[$index] !== null){
|
||||
$block = clone $this->fullList[$index];
|
||||
}else{
|
||||
$block = new UnknownBlock(new BID($id, $meta), BlockBreakInfo::instant());
|
||||
$block = new UnknownBlock(new BID($id, $meta), BreakInfo::instant());
|
||||
}
|
||||
|
||||
return $block;
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -130,10 +130,11 @@ class BrewingStand extends Transparent{
|
||||
}
|
||||
|
||||
public function onScheduledUpdate() : void{
|
||||
$brewing = $this->position->getWorld()->getTile($this->position);
|
||||
$world = $this->position->getWorld();
|
||||
$brewing = $world->getTile($this->position);
|
||||
if($brewing instanceof TileBrewingStand){
|
||||
if($brewing->onUpdate()){
|
||||
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, 1);
|
||||
$world->scheduleDelayedBlockUpdate($this->position, 1);
|
||||
}
|
||||
|
||||
$changed = false;
|
||||
@ -146,7 +147,7 @@ class BrewingStand extends Transparent{
|
||||
}
|
||||
|
||||
if($changed){
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$world->setBlock($this->position, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -73,9 +73,10 @@ abstract class Button extends Flowable{
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->pressed){
|
||||
$this->pressed = true;
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, $this->getActivationTime());
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), new RedstonePowerOnSound());
|
||||
$world = $this->position->getWorld();
|
||||
$world->setBlock($this->position, $this);
|
||||
$world->scheduleDelayedBlockUpdate($this->position, $this->getActivationTime());
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new RedstonePowerOnSound());
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -84,8 +85,9 @@ abstract class Button extends Flowable{
|
||||
public function onScheduledUpdate() : void{
|
||||
if($this->pressed){
|
||||
$this->pressed = false;
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), new RedstonePowerOffSound());
|
||||
$world = $this->position->getWorld();
|
||||
$world->setBlock($this->position, $this);
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new RedstonePowerOffSound());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -72,7 +72,7 @@ class Cactus extends Transparent{
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
static $shrinkSize = 1 / 16;
|
||||
$shrinkSize = 1 / 16;
|
||||
return [AxisAlignedBB::one()->contract($shrinkSize, 0, $shrinkSize)->trim(Facing::UP, $shrinkSize)];
|
||||
}
|
||||
|
||||
@ -88,13 +88,14 @@ class Cactus extends Transparent{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
$world = $this->position->getWorld();
|
||||
if($down->getId() !== BlockLegacyIds::SAND && !$down->isSameType($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
foreach(Facing::HORIZONTAL as $side){
|
||||
$b = $this->getSide($side);
|
||||
if($b->isSolid()){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
$world->useBreakOn($this->position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -107,28 +108,29 @@ class Cactus extends Transparent{
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if(!$this->getSide(Facing::DOWN)->isSameType($this)){
|
||||
$world = $this->position->getWorld();
|
||||
if($this->age === self::MAX_AGE){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
if(!$this->position->getWorld()->isInWorld($this->position->x, $this->position->y + $y, $this->position->z)){
|
||||
if(!$world->isInWorld($this->position->x, $this->position->y + $y, $this->position->z)){
|
||||
break;
|
||||
}
|
||||
$b = $this->position->getWorld()->getBlockAt($this->position->x, $this->position->y + $y, $this->position->z);
|
||||
$b = $world->getBlockAt($this->position->x, $this->position->y + $y, $this->position->z);
|
||||
if($b->getId() === BlockLegacyIds::AIR){
|
||||
$ev = new BlockGrowEvent($b, VanillaBlocks::CACTUS());
|
||||
$ev->call();
|
||||
if($ev->isCancelled()){
|
||||
break;
|
||||
}
|
||||
$this->position->getWorld()->setBlock($b->position, $ev->getNewState());
|
||||
$world->setBlock($b->position, $ev->getNewState());
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->age = 0;
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$world->setBlock($this->position, $this);
|
||||
}else{
|
||||
++$this->age;
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$world->setBlock($this->position, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -51,13 +51,13 @@ class Chest extends Transparent{
|
||||
}
|
||||
|
||||
public function onPostPlace() : void{
|
||||
$tile = $this->position->getWorld()->getTile($this->position);
|
||||
$world = $this->position->getWorld();
|
||||
$tile = $world->getTile($this->position);
|
||||
if($tile instanceof TileChest){
|
||||
foreach([false, true] as $clockwise){
|
||||
$side = Facing::rotateY($this->facing, $clockwise);
|
||||
$c = $this->getSide($side);
|
||||
if($c instanceof Chest && $c->isSameType($this) && $c->facing === $this->facing){
|
||||
$world = $this->position->getWorld();
|
||||
$pair = $world->getTile($c->position);
|
||||
if($pair instanceof TileChest && !$pair->isPaired()){
|
||||
[$left, $right] = $clockwise ? [$c, $this] : [$this, $c];
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -27,6 +27,7 @@ use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\CoralTypeTrait;
|
||||
use pocketmine\block\utils\InvalidBlockStateException;
|
||||
use pocketmine\data\bedrock\CoralTypeIdMap;
|
||||
use pocketmine\event\block\BlockDeathEvent;
|
||||
use pocketmine\item\Item;
|
||||
use function mt_rand;
|
||||
|
||||
@ -77,7 +78,11 @@ final class CoralBlock extends Opaque{
|
||||
}
|
||||
}
|
||||
if(!$hasWater){
|
||||
$world->setBlock($this->position, $this->setDead(true));
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$world->setBlock($this->position, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -100,21 +100,23 @@ class DaylightSensor extends Transparent{
|
||||
}
|
||||
|
||||
public function onScheduledUpdate() : void{
|
||||
$world = $this->position->getWorld();
|
||||
$signalStrength = $this->recalculateSignalStrength();
|
||||
if($this->signalStrength !== $signalStrength){
|
||||
$this->signalStrength = $signalStrength;
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$world->setBlock($this->position, $this);
|
||||
}
|
||||
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, 20);
|
||||
$world->scheduleDelayedBlockUpdate($this->position, 20);
|
||||
}
|
||||
|
||||
private function recalculateSignalStrength() : int{
|
||||
$lightLevel = $this->position->getWorld()->getRealBlockSkyLightAt($this->position->x, $this->position->y, $this->position->z);
|
||||
$world = $this->position->getWorld();
|
||||
$lightLevel = $world->getRealBlockSkyLightAt($this->position->x, $this->position->y, $this->position->z);
|
||||
if($this->inverted){
|
||||
return 15 - $lightLevel;
|
||||
}
|
||||
|
||||
$sunAngle = $this->position->getWorld()->getSunAnglePercentage();
|
||||
$sunAngle = $world->getSunAnglePercentage();
|
||||
return max(0, (int) round($lightLevel * cos(($sunAngle + ((($sunAngle < 0.5 ? 0 : 1) - $sunAngle) / 5)) * 2 * M_PI)));
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -34,7 +34,7 @@ use function mt_rand;
|
||||
class DeadBush extends Flowable{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->getSide(Facing::DOWN)->isTransparent()){
|
||||
if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ class DeadBush extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->getSide(Facing::DOWN)->isTransparent()){
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
@ -64,4 +64,14 @@ class DeadBush extends Flowable{
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
$blockId = $block->getId();
|
||||
return $blockId === BlockLegacyIds::SAND
|
||||
|| $blockId === BlockLegacyIds::PODZOL
|
||||
|| $blockId === BlockLegacyIds::MYCELIUM
|
||||
|| $blockId === BlockLegacyIds::DIRT
|
||||
|| $blockId === BlockLegacyIds::HARDENED_CLAY
|
||||
|| $blockId === BlockLegacyIds::STAINED_HARDENED_CLAY;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -63,8 +63,9 @@ class Dirt extends Opaque{
|
||||
$item->applyDamage(1);
|
||||
|
||||
$newBlock = $this->coarse ? VanillaBlocks::DIRT() : VanillaBlocks::FARMLAND();
|
||||
$this->position->getWorld()->addSound($this->position->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock));
|
||||
$this->position->getWorld()->setBlock($this->position, $newBlock);
|
||||
$world = $this->position->getWorld();
|
||||
$world->addSound($this->position->add(0.5, 0.5, 0.5), new ItemUseOnBlockSound($newBlock));
|
||||
$world->setBlock($this->position, $newBlock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -163,13 +163,14 @@ class Door extends Transparent{
|
||||
$this->open = !$this->open;
|
||||
|
||||
$other = $this->getSide($this->top ? Facing::DOWN : Facing::UP);
|
||||
$world = $this->position->getWorld();
|
||||
if($other instanceof Door && $other->isSameType($this)){
|
||||
$other->open = $this->open;
|
||||
$this->position->getWorld()->setBlock($other->position, $other);
|
||||
$world->setBlock($other->position, $other);
|
||||
}
|
||||
|
||||
$this->position->getWorld()->setBlock($this->position, $this);
|
||||
$this->position->getWorld()->addSound($this->position, new DoorSound());
|
||||
$world->setBlock($this->position, $this);
|
||||
$world->addSound($this->position, new DoorSound());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
@ -62,8 +62,9 @@ class DragonEgg extends Transparent implements Fallable{
|
||||
}
|
||||
|
||||
public function teleport() : void{
|
||||
$world = $this->position->getWorld();
|
||||
for($tries = 0; $tries < 16; ++$tries){
|
||||
$block = $this->position->getWorld()->getBlockAt(
|
||||
$block = $world->getBlockAt(
|
||||
$this->position->x + mt_rand(-16, 16),
|
||||
max(World::Y_MIN, min(World::Y_MAX - 1, $this->position->y + mt_rand(-8, 8))),
|
||||
$this->position->z + mt_rand(-16, 16)
|
||||
@ -76,9 +77,9 @@ class DragonEgg extends Transparent implements Fallable{
|
||||
}
|
||||
|
||||
$blockPos = $ev->getTo();
|
||||
$this->position->getWorld()->addParticle($this->position, new DragonEggTeleportParticle($this->position->x - $blockPos->x, $this->position->y - $blockPos->y, $this->position->z - $blockPos->z));
|
||||
$this->position->getWorld()->setBlock($this->position, VanillaBlocks::AIR());
|
||||
$this->position->getWorld()->setBlock($blockPos, $this);
|
||||
$world->addParticle($this->position, new DragonEggTeleportParticle($this->position->x - $blockPos->x, $this->position->y - $blockPos->y, $this->position->z - $blockPos->z));
|
||||
$world->setBlock($this->position, VanillaBlocks::AIR());
|
||||
$world->setBlock($blockPos, $this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user