mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-11 03:58:06 +00:00
Compare commits
237 Commits
Author | SHA1 | Date | |
---|---|---|---|
e852a43821 | |||
05f40b1315 | |||
7aaef8cb89 | |||
9d4c37fc3a | |||
cfa2df82eb | |||
7f78ec0a32 | |||
8572311bf4 | |||
18ca3a37d9 | |||
4b41fca991 | |||
9f09acc079 | |||
b65b7a7f74 | |||
4c25d38b44 | |||
983aa79a0b | |||
af9ae445fc | |||
91d5a3ddfe | |||
f03e708f64 | |||
b86b389fc5 | |||
e27121a437 | |||
2d5c9e64ce | |||
78f5fbddf3 | |||
aa3f4f2545 | |||
f7279b6672 | |||
2711ab4f00 | |||
b4c5f5d58d | |||
735d9a5bf4 | |||
f4a06605b1 | |||
662f2495e9 | |||
b8a4ca45e4 | |||
ebcd6a0bb2 | |||
b45b4b5edf | |||
dd79d4c463 | |||
9c1ab943bc | |||
2c74124e2e | |||
514fc1ebb5 | |||
c1638ffaab | |||
710177ceb5 | |||
2559d1719f | |||
2e58387a43 | |||
35a28300f6 | |||
81941ae9e5 | |||
1a2c10e844 | |||
d88c3d8ced | |||
bb0e648276 | |||
53de55dcde | |||
01664d2e81 | |||
0a90a5928a | |||
46f24b165a | |||
6f09286fed | |||
774eb3e72b | |||
cd8219d9fd | |||
52ce3444d8 | |||
e9e5923639 | |||
49a9da147b | |||
4c0df5ee4e | |||
4c737b2ee3 | |||
eb53b795d5 | |||
befd3637f6 | |||
9b2a7b43c2 | |||
5ec3f4655f | |||
c972e65741 | |||
a45763328b | |||
82a5ea9ed3 | |||
bbdcab7277 | |||
6086ef667c | |||
486d4099df | |||
a1f34a460b | |||
5ff03c81f8 | |||
1c611a03e6 | |||
948875b025 | |||
fb43f59458 | |||
16dfd27935 | |||
2a4909d328 | |||
b078e01b65 | |||
4eb9dacd3c | |||
43770313ba | |||
3afe3b7f44 | |||
fd23281183 | |||
70dd8732e2 | |||
cdf72563f4 | |||
2779f92828 | |||
5899f2fc1d | |||
9ef835c82d | |||
d65d8c3356 | |||
9b43ddecbd | |||
4bdd6410db | |||
6ea7fd7d6b | |||
5e7f18cbcf | |||
4517948297 | |||
777a901932 | |||
24d979bd08 | |||
86810c5e1c | |||
b33a9690e9 | |||
1b9c282194 | |||
82b75e0ccb | |||
6c59912ed5 | |||
3c34841dfc | |||
914dd90b3d | |||
537721fe7d | |||
fba51e3bf9 | |||
763241b11f | |||
8414c78969 | |||
4637aae621 | |||
6fbc133e5d | |||
f38aee1fc5 | |||
69abd5eb53 | |||
f6ee7ddc9e | |||
cff4a8d2bc | |||
20b7e8d702 | |||
c6110be051 | |||
c053742f5d | |||
0051b34797 | |||
a74ab756bd | |||
90520c8962 | |||
2e9a4f2be2 | |||
e23806d417 | |||
30db658d70 | |||
83d11c7429 | |||
4c6b82f30a | |||
fb6a7d279f | |||
0c1bfb058a | |||
45d1ce9bb8 | |||
8c8794ec71 | |||
b399eda21e | |||
f7c08dedee | |||
250d18e41b | |||
86bd6777a3 | |||
935df62006 | |||
489a7ba365 | |||
2709dd359c | |||
4e646d19a4 | |||
2a11762e61 | |||
dca752c72f | |||
259cc305df | |||
7132ac0ad3 | |||
0d8a06732a | |||
d2f4ba74c6 | |||
d4716ef457 | |||
d630b3af7b | |||
c2bb51cb37 | |||
7e0b5cf73d | |||
e903da8998 | |||
b7210755a7 | |||
f2193d1ba7 | |||
4daacb2ab7 | |||
f7977c9668 | |||
93d3f439bf | |||
200e5f940c | |||
9365ffa7fa | |||
cfd9950b02 | |||
8ebcdb452d | |||
ef85fbffe1 | |||
aacc00a911 | |||
0c250a2ef0 | |||
c01d2dc718 | |||
8f217ca6e0 | |||
f0d5647aa2 | |||
e6de9a70a2 | |||
a34514c6a1 | |||
6a80b210d4 | |||
02ffb04b92 | |||
6cbb03bf9b | |||
3abd592b1f | |||
644b417d2c | |||
588a754f1c | |||
70dd9c7371 | |||
f8e6f036af | |||
5d51ffdfe3 | |||
a2a7006878 | |||
b78c18ad2d | |||
41281db6a5 | |||
2278275505 | |||
53a6d8451b | |||
bbabccfc89 | |||
1698eac6dc | |||
83378d9403 | |||
321972b87b | |||
24b74a96eb | |||
e61796b146 | |||
c86c9b3ead | |||
249ef9c534 | |||
17842703a1 | |||
f4dab17a1b | |||
eed423505e | |||
c165670e0a | |||
882d50b14e | |||
0b0b72f596 | |||
2654fb294b | |||
2b40c1a5be | |||
74d219dcb6 | |||
470a3e1a3a | |||
ad67fb7291 | |||
3eed0a4620 | |||
b8788c55c5 | |||
c06763c59b | |||
881451c40c | |||
36f52f1ade | |||
0240d35c05 | |||
8dedbb7471 | |||
6f82942c64 | |||
9d0d60afd1 | |||
391732f00c | |||
ad3f854701 | |||
64e09525f3 | |||
774f92435a | |||
be8cca1d55 | |||
eb9f804781 | |||
bccda4fe44 | |||
8f48f8a596 | |||
288ebfa08a | |||
a3046eb6fa | |||
ff0199cdf8 | |||
39a6a9ee70 | |||
0939301938 | |||
202be92c06 | |||
df4a8d4788 | |||
1d25e15ec8 | |||
1b35c352cc | |||
ab75838c89 | |||
1533dc4e56 | |||
3800c0480f | |||
0f8e61eda4 | |||
0eb5f9b684 | |||
0f9283fda1 | |||
ab8386ed5a | |||
64c1776910 | |||
e85605af7f | |||
92bd88c77c | |||
7cd317bf39 | |||
35fc9abacf | |||
dfd70615ad | |||
ee903cad1f | |||
9a04481bec | |||
833f9401f9 | |||
a46dfaf677 | |||
57cbc25080 | |||
b9bdfe580b | |||
6d7f44d8fe |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
.github/readme/pocketmine-dark-rgb.gif
vendored
Normal file
BIN
.github/readme/pocketmine-dark-rgb.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 173 KiB |
BIN
.github/readme/pocketmine-rgb.gif
vendored
Normal file
BIN
.github/readme/pocketmine-rgb.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 173 KiB |
8
.github/workflows/build-docker-image.yml
vendored
8
.github/workflows/build-docker-image.yml
vendored
@ -53,7 +53,7 @@ jobs:
|
||||
run: echo NAME=$(echo "${GITHUB_REPOSITORY,,}") >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build image for tag
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
uses: docker/build-push-action@v4.1.1
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -66,7 +66,7 @@ jobs:
|
||||
|
||||
- name: Build image for major tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
uses: docker/build-push-action@v4.1.1
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
|
||||
- name: Build image for minor tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
uses: docker/build-push-action@v4.1.1
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
@ -92,7 +92,7 @@ jobs:
|
||||
|
||||
- name: Build image for latest tag
|
||||
if: steps.channel.outputs.CHANNEL == 'stable'
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
uses: docker/build-push-action@v4.1.1
|
||||
with:
|
||||
push: true
|
||||
context: ./pocketmine-mp
|
||||
|
22
.github/workflows/discord-release-embed.php
vendored
22
.github/workflows/discord-release-embed.php
vendored
@ -18,7 +18,12 @@ 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, int $newsPingRoleId) : array{
|
||||
function generateDiscordEmbed(string $version, string $channel, string $description, string $detailsUrl, string $sourceUrl, string $pharDownloadUrl, string $buildLogUrl, int $newsPingRoleId, ?string $phpDownloadUrl) : array{
|
||||
if($phpDownloadUrl !== null){
|
||||
$phpEmbedLink = " | [PHP Binaries]($phpDownloadUrl)";
|
||||
}else{
|
||||
$phpEmbedLink = "";
|
||||
}
|
||||
return [
|
||||
"content" => "<@&$newsPingRoleId> New PocketMine-MP release: $version ($channel)",
|
||||
"embeds" => [
|
||||
@ -27,7 +32,7 @@ function generateDiscordEmbed(string $version, string $channel, string $descript
|
||||
"description" => <<<DESCRIPTION
|
||||
$description
|
||||
|
||||
[Details]($detailsUrl) | [Source Code]($sourceUrl) | [Build Log]($buildLogUrl) | [Download]($pharDownloadUrl)
|
||||
[Details]($detailsUrl) | [Source Code]($sourceUrl) | [Build Log]($buildLogUrl) | [Download]($pharDownloadUrl)$phpEmbedLink
|
||||
DESCRIPTION,
|
||||
"url" => $detailsUrl,
|
||||
"color" => $channel === "stable" ? 0x57ab5a : 0xc69026
|
||||
@ -84,10 +89,21 @@ $detailsUrl = $buildInfoJson["details_url"];
|
||||
$sourceUrl = $buildInfoJson["source_url"];
|
||||
$pharDownloadUrl = $buildInfoJson["download_url"];
|
||||
$buildLogUrl = $buildInfoJson["build_log_url"];
|
||||
$phpBinaryUrl = $buildInfoJson["php_download_url"] ?? null;
|
||||
|
||||
$description = $releaseInfoJson["body"];
|
||||
|
||||
$discordPayload = generateDiscordEmbed($buildInfoJson["base_version"], $buildInfoJson["channel"], $description, $detailsUrl, $sourceUrl, $pharDownloadUrl, $buildLogUrl, (int) $newsPingRoleId);
|
||||
$discordPayload = generateDiscordEmbed(
|
||||
$buildInfoJson["base_version"],
|
||||
$buildInfoJson["channel"],
|
||||
$description,
|
||||
$detailsUrl,
|
||||
$sourceUrl,
|
||||
$pharDownloadUrl,
|
||||
$buildLogUrl,
|
||||
(int) $newsPingRoleId,
|
||||
$phpBinaryUrl
|
||||
);
|
||||
|
||||
$response = Internet::postURL(
|
||||
$hookURL,
|
||||
|
2
.github/workflows/discord-release-notify.yml
vendored
2
.github/workflows/discord-release-notify.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP and tools
|
||||
uses: shivammathur/setup-php@2.25.2
|
||||
uses: shivammathur/setup-php@2.25.5
|
||||
with:
|
||||
php-version: 8.1
|
||||
|
||||
|
23
.github/workflows/draft-release.yml
vendored
23
.github/workflows/draft-release.yml
vendored
@ -11,6 +11,8 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-version: [8.1]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@ -18,9 +20,9 @@ jobs:
|
||||
submodules: true
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@2.25.2
|
||||
uses: shivammathur/setup-php@2.25.5
|
||||
with:
|
||||
php-version: 8.1
|
||||
php-version: ${{ matrix.php-version }}
|
||||
|
||||
- name: Restore Composer package cache
|
||||
uses: actions/cache@v3
|
||||
@ -58,8 +60,21 @@ jobs:
|
||||
echo CHANGELOG_SUFFIX=$(php -r 'require "vendor/autoload.php"; echo \pocketmine\VersionInfo::BUILD_CHANNEL === "stable" ? "" : "-" . \pocketmine\VersionInfo::BUILD_CHANNEL;') >> $GITHUB_OUTPUT
|
||||
echo PRERELEASE=$(php -r 'require "vendor/autoload.php"; echo \pocketmine\VersionInfo::BUILD_CHANNEL === "stable" ? "false" : "true";') >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate PHP binary download URL
|
||||
id: php-binary-url
|
||||
run: |
|
||||
echo PHP_BINARY_URL="${{ github.server_url }}/${{ github.repository_owner }}/PHP-Binaries/releases/tag/php-${{ matrix.php-version }}-latest" >> $GITHUB_OUTPUT
|
||||
|
||||
- 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 }} ${{ github.run_id }} > 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 }} \
|
||||
${{ steps.php-binary-url.outputs.PHP_BINARY_URL }} \
|
||||
> build_info.json
|
||||
|
||||
- name: Upload release artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
@ -84,3 +99,5 @@ jobs:
|
||||
**For Minecraft: Bedrock Edition ${{ steps.get-pm-version.outputs.MCPE_VERSION }}**
|
||||
|
||||
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 }}${{ steps.get-pm-version.outputs.CHANGELOG_SUFFIX }}.md#${{ steps.get-pm-version.outputs.PM_VERSION_MD }}) for details.
|
||||
|
||||
:information_source: Download the recommended PHP binary [here](${{ steps.php-binary-url.outputs.PHP_BINARY_URL }}).
|
||||
|
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@ -173,7 +173,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP and tools
|
||||
uses: shivammathur/setup-php@2.25.2
|
||||
uses: shivammathur/setup-php@2.25.5
|
||||
with:
|
||||
php-version: 8.1
|
||||
tools: php-cs-fixer:3.17
|
||||
|
1
.github/workflows/update-updater-api.yml
vendored
1
.github/workflows/update-updater-api.yml
vendored
@ -8,6 +8,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
concurrency: update-updater-api # only one job can run at a time, to avoid git conflicts when updating the repository
|
||||
|
||||
steps:
|
||||
- name: Install jq
|
||||
|
@ -4,8 +4,8 @@
|
||||
<img src="https://github.com/pmmp/PocketMine-MP/blob/stable/.github/readme/pocketmine.png" alt="The PocketMine-MP logo" title="PocketMine" loading="eager" />
|
||||
<![endif]-->
|
||||
<picture>
|
||||
<source srcset="https://github.com/pmmp/PocketMine-MP/raw/stable/.github/readme/pocketmine-dark.png" media="(prefers-color-scheme: dark)">
|
||||
<img src="https://github.com/pmmp/PocketMine-MP/raw/stable/.github/readme/pocketmine.png" loading="eager" />
|
||||
<source srcset="https://raw.githubusercontent.com/pmmp/PocketMine-MP/stable/.github/readme/pocketmine-dark-rgb.gif" media="(prefers-color-scheme: dark)">
|
||||
<img src="https://raw.githubusercontent.com/pmmp/PocketMine-MP/stable/.github/readme/pocketmine-rgb.gif" loading="eager" />
|
||||
</picture>
|
||||
</a><br>
|
||||
<b>A highly customisable, open source server software for Minecraft: Bedrock Edition written in PHP</b>
|
||||
@ -26,7 +26,7 @@
|
||||
- [Docker image](https://github.com/pmmp/PocketMine-MP/pkgs/container/pocketmine-mp)
|
||||
- [Plugin repository](https://poggit.pmmp.io/plugins)
|
||||
|
||||
## Discussion/Help
|
||||
## Community & Support
|
||||
- [Forums](https://forums.pmmp.io/)
|
||||
- [Discord](https://discord.gg/bmSAZBG)
|
||||
- [StackOverflow](https://stackoverflow.com/tags/pocketmine)
|
||||
|
@ -139,7 +139,7 @@ function generateBlockStateNames(BlockPaletteReport $data) : void{
|
||||
|
||||
fwrite($output, generateClassHeader(BlockStateNames::class));
|
||||
foreach(Utils::stringifyKeys($data->seenStateValues) as $state => $values){
|
||||
$constName = mb_strtoupper(preg_replace("/^minecraft:/", "", $state) ?? throw new AssumptionFailedError("This regex is not invalid"), 'US-ASCII');
|
||||
$constName = mb_strtoupper(preg_replace("/^minecraft:/", "mc_", $state) ?? throw new AssumptionFailedError("This regex is not invalid"), 'US-ASCII');
|
||||
fwrite($output, "\tpublic const $constName = \"$state\";\n");
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ function generateBlockStringValues(BlockPaletteReport $data) : void{
|
||||
continue;
|
||||
}
|
||||
$anyWritten = true;
|
||||
$constName = mb_strtoupper(preg_replace("/^minecraft:/", "", $stateName) . "_" . $value, 'US-ASCII');
|
||||
$constName = mb_strtoupper(preg_replace("/^minecraft:/", "mc_", $stateName) . "_" . $value, 'US-ASCII');
|
||||
fwrite($output, "\tpublic const $constName = \"$value\";\n");
|
||||
}
|
||||
if($anyWritten){
|
||||
|
@ -23,13 +23,13 @@ declare(strict_types=1);
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
if(count($argv) !== 6){
|
||||
fwrite(STDERR, "required args: <git hash> <tag name> <github repo (owner/name)> <build number> <github actions run ID>\n");
|
||||
if(count($argv) !== 7){
|
||||
fwrite(STDERR, "required args: <git hash> <tag name> <github repo (owner/name)> <build number> <github actions run ID> <PHP binary download URL>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"php_version" => sprintf("%d.%d", PHP_MAJOR_VERSION, PHP_MINOR_VERSION),
|
||||
"php_version" => sprintf("%d.%d", PHP_MAJOR_VERSION, PHP_MINOR_VERSION), //deprecated
|
||||
"base_version" => \pocketmine\VersionInfo::BASE_VERSION,
|
||||
"build" => (int) $argv[4],
|
||||
"is_dev" => \pocketmine\VersionInfo::IS_DEVELOPMENT_BUILD,
|
||||
@ -41,4 +41,5 @@ echo json_encode([
|
||||
"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]",
|
||||
"php_download_url" => $argv[6],
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR) . "\n";
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\build\generate_item_serializer_ids;
|
||||
|
||||
use pocketmine\data\bedrock\item\BlockItemIdMap;
|
||||
use pocketmine\errorhandler\ErrorToExceptionHandler;
|
||||
use pocketmine\network\mcpe\convert\ItemTypeDictionaryFromDataHelper;
|
||||
use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary;
|
||||
@ -45,10 +46,10 @@ function constifyMcId(string $id) : string{
|
||||
return strtoupper(explode(":", $id, 2)[1]);
|
||||
}
|
||||
|
||||
function generateItemIds(ItemTypeDictionary $dictionary) : void{
|
||||
function generateItemIds(ItemTypeDictionary $dictionary, BlockItemIdMap $blockItemIdMap) : void{
|
||||
$ids = [];
|
||||
foreach($dictionary->getEntries() as $entry){
|
||||
if($entry->getNumericId() < 256){ //blockitems are serialized via BlockStateSerializer
|
||||
if($entry->getStringId() === "minecraft:air" || $blockItemIdMap->lookupBlockId($entry->getStringId()) !== null){ //blockitems are serialized via BlockStateSerializer
|
||||
continue;
|
||||
}
|
||||
$ids[$entry->getStringId()] = $entry->getStringId();
|
||||
@ -92,6 +93,7 @@ if($raw === false){
|
||||
}
|
||||
|
||||
$dictionary = ItemTypeDictionaryFromDataHelper::loadFromString($raw);
|
||||
generateItemIds($dictionary);
|
||||
$blockItemIdMap = BlockItemIdMap::getInstance();
|
||||
generateItemIds($dictionary, $blockItemIdMap);
|
||||
|
||||
echo "Done. Don't forget to run CS fixup after generating code.\n";
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\CopperOxidation;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\DirtType;
|
||||
use pocketmine\block\utils\DripleafState;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\FroglightType;
|
||||
use pocketmine\block\utils\LeverFacing;
|
||||
@ -145,6 +146,7 @@ $enumsUsed = [
|
||||
CopperOxidation::getAll(),
|
||||
CoralType::getAll(),
|
||||
DirtType::getAll(),
|
||||
DripleafState::getAll(),
|
||||
DyeColor::getAll(),
|
||||
FroglightType::getAll(),
|
||||
LeverFacing::getAll(),
|
||||
|
Submodule build/php updated: fcbc15f23e...a053f65e18
@ -22,3 +22,37 @@ If you're upgrading from 4.20.x directly to 4.22.x, please also read the followi
|
||||
## Fixes
|
||||
- Removed deprecated `ReflectionProperty::setAccessible()` calls.
|
||||
- Fixed jukebox music not stopping when destroyed by an explosion.
|
||||
|
||||
# 4.22.1
|
||||
Released 9th June 2023.
|
||||
|
||||
## Fixes
|
||||
- Replaced workaround for an old teleporting client bug:
|
||||
- This workaround broke due to an additional client bug introduced by 1.20, causing players to become frozen to observers when teleported.
|
||||
- The original client bug has still not been fixed, meaning a new workaround was needed, but no perfect solution could be found.
|
||||
- The new workaround involves broadcasting teleport movements as regular movements, which causes unwanted interpolation between the old and new positions, but otherwise works correctly. This solution is not ideal, but it is the best we can do for now.
|
||||
- See issues [#4394](https://github.com/pmmp/PocketMine-MP/issues/4394) and [#5810](https://github.com/pmmp/PocketMine-MP/issues/5810) for more details.
|
||||
|
||||
# 4.22.2
|
||||
Released 1st July 2023.
|
||||
|
||||
## Changes
|
||||
- Added obsoletion warnings to the server log at the end of the startup sequence.
|
||||
|
||||
## Fixes
|
||||
- Fixed players being disconnected en masse with "Not authenticated" messages.
|
||||
- This occurred due to a check intended to disable the old authentication key after July 1st.
|
||||
- We expected that the new key would have been deployed by Mojang by now, but it seems like that has not yet happened.
|
||||
- Due to the lack of a hard date for the key changeover, we guessed that July 1st would be a safe bet, but this appears to have backfired.
|
||||
- This version will accept both old and new keys indefinitely.
|
||||
- A security release will be published to remove the old key after the transition occurs.
|
||||
|
||||
# 4.22.3
|
||||
Released 11th July 2023.
|
||||
|
||||
## Fixes
|
||||
- Fixed mishandling of NBT leading to a server crash when editing signs.
|
||||
- Fixed an edge case crash that could occur in `AsyncTask->__destruct()` when thread-local storage referenced other `AsyncTask` objects.
|
||||
|
||||
## Internals
|
||||
- Added a concurrency lock to prevent the `update-updater-api` GitHub Action from running for multiple releases at the same time (which would have caused one of them to fail due to git conflicts).
|
||||
|
68
changelogs/4.23.md
Normal file
68
changelogs/4.23.md
Normal file
@ -0,0 +1,68 @@
|
||||
# 4.23.0
|
||||
Released 12th July 2023.
|
||||
|
||||
**For Minecraft: Bedrock Edition 1.20.10**
|
||||
|
||||
This is a support release for Minecraft: Bedrock Edition 1.20.10.
|
||||
|
||||
**Plugin compatibility:** Plugins for previous 4.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` namespace.
|
||||
Do not update plugin minimum API versions unless you need new features added in this release.
|
||||
|
||||
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
|
||||
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
|
||||
|
||||
## General
|
||||
- Added support for Minecraft: Bedrock Edition 1.20.10.
|
||||
- Removed support for older versions.
|
||||
|
||||
## Fixes
|
||||
- Fixed Docker image build failure due to outdated `build/php` submodule.
|
||||
|
||||
# 4.23.1
|
||||
Released 14th July 2023.
|
||||
|
||||
## Fixes
|
||||
- Hardened validation of JWT signing keys in `LoginPacket`.
|
||||
- Fixed server crash due to a bug in upstream dependency [`netresearch/jsonmapper`](https://github.com/cweiske/JsonMapper).
|
||||
|
||||
# 4.23.2
|
||||
Released 18th July 2023.
|
||||
|
||||
## Fixes
|
||||
- Fixed login errors due to a new `sandboxId` field appearing in the Xbox Live authentication data in `LoginPacket`. All clients, regardless of version, are affected by this change.
|
||||
|
||||
# 4.23.3
|
||||
Released 24th July 2023.
|
||||
|
||||
## Documentation
|
||||
- Fixed typo in `ChunkSelector::selectChunks()` documentation.
|
||||
|
||||
## Fixes
|
||||
- Fixed the server not stopping properly during crash conditions on *nix platforms.
|
||||
- Fixed `HORSE_EQUIP` and `SMITHING_TABLE_TEMPLATE` container UI types not being handled by `ItemStackContainerIdTranslator`. This bug prevented plugins from implementing missing inventory types.
|
||||
- Player emotes no longer broadcast messages to other players. This was unintended behaviour caused by a client-side behavioural change.
|
||||
- Shulker boxes no longer support the placement of torches or other similar blocks.
|
||||
- Fire can now be placed on upper slabs and the top of upside-down stairs.
|
||||
|
||||
# 4.23.4
|
||||
Released 1st August 2023.
|
||||
|
||||
## Fixes
|
||||
- Fixed exponentially increasing lag when many hundreds of non-mergeable dropped items occupied the same space. This disproportionately affected SkyBlock servers due to large cactus farms using water to collect items together.
|
||||
|
||||
# 4.23.5
|
||||
Released 9th August 2023.
|
||||
|
||||
## General
|
||||
- Updated translation data to [pmmp/Language 2.19.6](https://github.com/pmmp/Language/releases/tag/2.19.6).
|
||||
|
||||
## Fixes
|
||||
- Fixed `PluginBase->saveResource()` leaking file resources when the data file already exists in the plugin's data folder. This bug existed since 2014 and was only discovered recently.
|
||||
- Fixed coral blocks becoming dead after calling `getDropsForCompatibleTool()` on them.
|
||||
- Fixed `BlockDeathEvent->getOldState()` returning a block which is already dead.
|
||||
|
||||
# 4.23.6
|
||||
Released 21st August 2023.
|
||||
|
||||
## Fixes
|
||||
- Added a workaround for armor and other inventories not working correctly after inventory sync. This is caused by a client bug.
|
@ -20,3 +20,33 @@ Released 7th June 2023.
|
||||
|
||||
## Fixes
|
||||
- Fixed blockstates being saved with the wrong version ID for 1.20.0.
|
||||
|
||||
# 5.1.2
|
||||
Released 9th June 2023.
|
||||
|
||||
**This release includes changes from the following releases:**
|
||||
- [4.22.1](https://github.com/pmmp/PocketMine-MP/blob/4.22.1/changelogs/4.22.md#4221) - Teleportation client bug workarounds
|
||||
|
||||
This release contains no other changes.
|
||||
|
||||
# 5.1.3
|
||||
Released 1st July 2023.
|
||||
|
||||
**This release includes changes from the following releases:**
|
||||
- [4.22.2](https://github.com/pmmp/PocketMine-MP/blob/4.22.2/changelogs/4.22.md#4222) - Authentication time bomb fix
|
||||
|
||||
## General
|
||||
- Updated logos to new RGB-style logo. Thanks to @MrCakeSlayer and @HBIDamian for their efforts.
|
||||
- Improved error messages generated by the world system when some version tags are missing from `level.dat` in Bedrock worlds.
|
||||
- Outsourced Composer dependencies now only receive patch updates automatically (pinned using the `~` constraint).
|
||||
- Minor and major updates now require manually updating `composer.json`, to ensure that the plugin API is not broken by libraries getting randomly updated from one patch release to the next.
|
||||
|
||||
## Documentation
|
||||
- Updated doc comment for `Player->setGamemode()` to remove outdated information.
|
||||
- Added documentation for the `$clickVector` parameter of `Block->onInteract()` to specify that it is relative to the block's position.
|
||||
- Added missing `@required` tag for `BlockStateUpgradeSchemaModelBlockRemap->newState`.
|
||||
|
||||
## Fixes
|
||||
- Fixed blue candles not appearing in the creative inventory.
|
||||
- Fixed server crash when block-picking candle cakes.
|
||||
- `World->useItemOn()` now ensures that the `$clickVector` components are always in the range of 0-1. Previously, any invalid values were accepted, potentially leading to a crash.
|
||||
|
79
changelogs/5.2.md
Normal file
79
changelogs/5.2.md
Normal file
@ -0,0 +1,79 @@
|
||||
# 5.2.0
|
||||
Released 4th July 2023.
|
||||
|
||||
**For Minecraft: Bedrock Edition 1.20.0**
|
||||
|
||||
This is a minor technical update, including changes to AsyncTask error handling and support for BedrockBlockUpgradeSchema version 3.0.0.
|
||||
|
||||
**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace.
|
||||
Do not update plugin minimum API versions unless you need new features added in this release.
|
||||
|
||||
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
|
||||
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
|
||||
|
||||
## Core
|
||||
- [BedrockBlockUpgradeSchema version 3.0.0](https://github.com/pmmp/BedrockBlockUpgradeSchema/releases/tag/3.0.0) is now supported.
|
||||
- [`ext-pmmpthread` version 6.0.4](https://github.com/pmmp/ext-pmmpthread/releases/tag/6.0.4) is now required (bug fixes required to support technical changes in this release).
|
||||
|
||||
## Performance
|
||||
- Improved performance of `AsyncPool->submitTask()` and `AsyncPool->submitTaskToWorker()`.
|
||||
- Added new timings for `AsyncTask->onProgressUpdate()` and `AsyncTask->onCompletion()`.
|
||||
|
||||
## Gameplay
|
||||
### Blocks
|
||||
- Added the following new blocks:
|
||||
- Cherry Button
|
||||
- Cherry Door
|
||||
- Cherry Fence
|
||||
- Cherry Fence Gate
|
||||
- Cherry Leaves
|
||||
- Cherry Log
|
||||
- Cherry Planks
|
||||
- Cherry Pressure Plate
|
||||
- Cherry Sign
|
||||
- Cherry Slab
|
||||
- Cherry Stairs
|
||||
- Cherry Trapdoor
|
||||
- Cherry Wood
|
||||
- Glow Lichen
|
||||
- Piglin Head
|
||||
|
||||
## Tools
|
||||
- `generate-block-upgrade-schema.php` now supports generating schemas a la BedrockBlockUpgradeSchema version 3.0.0, using `newFlattenedName` to reduce schema size.
|
||||
- Improved property remapping detection in `generate-block-upgrade-schema.php`. It now detects related properties with more confidence (even when multiple properties were change), and no longer considers unrelated properties as mapped (e.g. `mapped_type` and `deprecated` in 1.9->1.10).
|
||||
|
||||
## API
|
||||
### `pocketmine\data\bedrock\block`
|
||||
- The following new API methods have been added:
|
||||
- `public BlockStateData->toVanillaNbt() : CompoundTag` - returns the NBT for the blockstate without any PMMP extra metadata (`toNbt()` will normally include a `PMMPDataVersion` tag).
|
||||
|
||||
### `pocketmine\data\runtime`
|
||||
- The following new API methods have been added:
|
||||
- `public RuntimeDataDescriber->facingFlags(list<int> $faces) : void`
|
||||
|
||||
### `pocketmine\scheduler`
|
||||
- `AsyncTask->onRun()` no longer tolerates uncaught exceptions.
|
||||
- This means that any uncaught exceptions thrown from `AsyncTask->onRun()` will now crash the worker thread, and by extension, the server.
|
||||
- This change makes it easier to debug errors by detecting them earlier.
|
||||
- The following API methods have been deprecated:
|
||||
- `AsyncTask->onError()`
|
||||
|
||||
## Internals
|
||||
- `AsyncTask->progressUpdates` is now lazily initialized when a task publishes a progress update.
|
||||
- This was previously not possible due to technical limitations of the `ext-pmmpthread` extension.
|
||||
- This change improves performance of `AsyncPool->submitTask()` and `AsyncPool->submitTaskToWorker()`, as well as reducing the amount of work needed to check for progress updates on tick.
|
||||
- Errors in `AsyncWorker` now cascade and crash the whole server.
|
||||
- This makes it easier to debug errors by detecting them earlier.
|
||||
- This includes all types of unexpected errors, such as OOM, uncaught exceptions, etc.
|
||||
- This change is not expected to affect normal server operation, as worker threads are not expected to crash under normal circumstances.
|
||||
- `AsyncTask::$threadLocalStorage` now uses a plain `array` instead of `ArrayObject`. The `ArrayObject` was a workaround for `ext-pthreads` to prevent thread-locals getting copied to the worker thread, and is no longer necessary.
|
||||
- Regenerated `pocketmine\data\bedrock\item\ItemTypeNames` for Bedrock 1.20 (BC breaking, some item names have changed).
|
||||
- Fixed `build/generate-item-type-names.php` not including some newer blockitems, such as doors and hanging signs.
|
||||
|
||||
# 5.2.1
|
||||
Released 11th July 2023.
|
||||
|
||||
**This release includes changes from the following releases:**
|
||||
- [4.22.3](https://github.com/pmmp/PocketMine-MP/blob/4.22.3/changelogs/4.22.md#4223) - Fixes for some crash issues
|
||||
|
||||
This release contains no other changes.
|
81
changelogs/5.3.md
Normal file
81
changelogs/5.3.md
Normal file
@ -0,0 +1,81 @@
|
||||
# 5.3.0
|
||||
Released 12th July 2023.
|
||||
|
||||
**For Minecraft: Bedrock Edition 1.20.10**
|
||||
|
||||
This is a support release for Minecraft: Bedrock Edition 1.20.10.
|
||||
|
||||
**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace.
|
||||
Do not update plugin minimum API versions unless you need new features added in this release.
|
||||
|
||||
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
|
||||
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
|
||||
|
||||
## Interim releases
|
||||
If you're upgrading directly from 5.1.x to 5.3.x, please also read the following changelogs, as the interim releases contain important changes:
|
||||
- [5.2.0](https://github.com/pmmp/PocketMine-MP/blob/5.2.0/changelogs/5.2.md#520)
|
||||
|
||||
## Included releases
|
||||
**This release includes changes from the following releases:**
|
||||
- [4.23.0](https://github.com/pmmp/PocketMine-MP/blob/4.23.0/changelogs/4.23.md#4230) - Support for Minecraft: Bedrock Edition 1.20.10
|
||||
|
||||
## Internals
|
||||
- `BlockTypeNames`, `BlockStateNames`, `BlockStateStringValues` and `ItemTypeNames` in the `pocketmine\data\bedrock` package have BC-breaking changes to accommodate Bedrock 1.20.10.
|
||||
|
||||
# 5.3.1
|
||||
Released 14th July 2023.
|
||||
|
||||
## Included releases
|
||||
**This release includes changes from the following releases:**
|
||||
- [4.23.1](https://github.com/pmmp/PocketMine-MP/blob/4.23.1/changelogs/4.23.md#4231) - Security fixes
|
||||
|
||||
## General
|
||||
- Updated `build/php` submodule to pmmp/PHP-Binaries@e0c918d1379465964acefd562d9e48f87cfc2c9e.
|
||||
|
||||
# 5.3.2
|
||||
Released 18th July 2023.
|
||||
|
||||
## Included releases
|
||||
**This release includes changes from the following releases:**
|
||||
- [4.23.2](https://github.com/pmmp/PocketMine-MP/blob/4.23.2/changelogs/4.23.md#4232) - Fix for `sandboxId`-related login errors
|
||||
|
||||
## Documentation
|
||||
- Fixed documentation error in `StringToTParser`.
|
||||
|
||||
## Fixes
|
||||
- Fixed turtle helmet not being able to be unequipped.
|
||||
|
||||
## Internals
|
||||
- Armor pieces are no longer set back into the armor inventory if no change was made. This reduces the number of slot updates sent to clients, as well as avoiding unnecessary updates for armor pieces which have Unbreaking enchantments.
|
||||
|
||||
# 5.3.3
|
||||
Released 24th July 2023.
|
||||
|
||||
## Included releases
|
||||
**This release includes changes from the following releases:**
|
||||
- [4.23.3](https://github.com/pmmp/PocketMine-MP/blob/4.23.3/changelogs/4.23.md#4233) - Various bug fixes
|
||||
|
||||
## Fixes
|
||||
- Added a workaround for PM4 worlds with chunks corrupted by [Refaltor77/CustomItemAPI](https://github.com/Refaltor77/CustomItemAPI).
|
||||
- While this was not the fault of PocketMine-MP itself, a significant number of users were affected by this problem.
|
||||
- This error was not detected by PM4 due to missing validation of certain data which should not have existed in 1.12.
|
||||
- An error will now be logged when this corruption is detected, but the affected chunks should otherwise load normally.
|
||||
- Relaxed validation of expected 3D biome array counts per chunk in LevelDB worlds.
|
||||
- Vanilla Bedrock currently saves 24 palettes (and only 24 are required), but it saved 25, 32, or 64 biome palettes per chunk in older versions.
|
||||
- Core validation for these padding biomes was very strict, enforcing exact compliance with vanilla.
|
||||
- Since only 24 palettes are actually required, the remaining palettes may now be omitted irrespective of the chunk version.
|
||||
- An error will still be logged when this mistake is detected, but the affected chunks will otherwise load normally.
|
||||
- Fixed `/kill` not working on players who had (re)spawned in the 3 seconds immediately after (re)spawning (due to `noDamageTicks`).
|
||||
- Fixed `/kill` not working correctly for players with high levels of Health Boost or other health-altering effects.
|
||||
- Fixed netherite items being destroyed by lava.
|
||||
- Fireproof entities no longer display the burning animation when in fire or lava. This does not apply to creative players, who are immortal rather than being fireproof.
|
||||
- Fixed frosted ice melting in certain conditions which didn't match vanilla Bedrock.
|
||||
|
||||
# 5.3.4
|
||||
Released 1st August 2023.
|
||||
|
||||
## Included releases
|
||||
This release includes changes from the following releases:
|
||||
- [4.23.4](https://github.com/pmmp/PocketMine-MP/blob/4.23.4/changelogs/4.23.md#4234) - Item entity lag fix
|
||||
|
||||
This release contains no other significant changes.
|
121
changelogs/5.4.md
Normal file
121
changelogs/5.4.md
Normal file
@ -0,0 +1,121 @@
|
||||
# 5.4.0
|
||||
Released 1st August 2023.
|
||||
|
||||
**For Minecraft: Bedrock Edition 1.20.10**
|
||||
|
||||
This is a minor feature update, including a handful of new gameplay features, new plugin APIs and improvements to error reporting.
|
||||
|
||||
**Plugin compatibility:** Plugins for previous 5.x versions will run unchanged on this release, unless they use internal APIs, reflection, or packages like the `pocketmine\network\mcpe` or `pocketmine\data` namespace.
|
||||
Do not update plugin minimum API versions unless you need new features added in this release.
|
||||
|
||||
**WARNING: If your plugin uses the `pocketmine\network\mcpe` namespace, you're not shielded by API change constraints.**
|
||||
Consider using the `mcpe-protocol` directive in `plugin.yml` as a constraint if you're using packets directly.
|
||||
|
||||
## General
|
||||
- Improved error reporting for async task and thread crashes.
|
||||
- Players may now have different creative inventories.
|
||||
|
||||
## Gameplay
|
||||
### General
|
||||
- Added support for 1.5-block height sneaking.
|
||||
- Fixed missing player arm swing and sounds when punching the air.
|
||||
|
||||
### Blocks
|
||||
- Implemented the following new blocks:
|
||||
- Big Dripleaf Head
|
||||
- Big Dripleaf Stem
|
||||
- Small Dripleaf
|
||||
- Acacia saplings now grow into acacia trees.
|
||||
- Fixed melon and pumpkin stems not attaching to the correct block when growing.
|
||||
- Various blocks now drop more items when mined with a compatible tool enchanted with Fortune.
|
||||
|
||||
### Items
|
||||
- Implemented Strong Slowness potion.
|
||||
- Implemented Fortune enchantment.
|
||||
|
||||
## API
|
||||
### `pocketmine\block`
|
||||
- The following new classes have been added:
|
||||
- `utils\FortuneDropHelper` - utility methods for calculating the drop counts for Fortune-affected blocks
|
||||
- The following new API methods have been added:
|
||||
- `protected Block->getAdjacentSupportType(int $facing) : utils\SupportType` - returns the type of support provided by the block in the given direction on the adjacent face
|
||||
|
||||
### `pocketmine\entity`
|
||||
- The following new API constants have been added:
|
||||
- `Living::DEFAULT_KNOCKBACK_FORCE`
|
||||
- `Living::DEFAULT_KNOCKBACK_VERTICAL_LIMIT`
|
||||
|
||||
### `pocketmine\entity\animation`
|
||||
- `ConsumingItemAnimation` now accepts `Living` instances instead of just `Human`.
|
||||
|
||||
### `pocketmine\event`
|
||||
- The following new classes have been added:
|
||||
- `PlayerMissSwingEvent` - called when the player attempts the attack action (left click on desktop) without any target
|
||||
- This is possible thanks to the introduction of new flags in `PlayerAuthInputPacket` in Bedrock 1.20.10
|
||||
- The following new API methods have been added:
|
||||
- `public EntityDamageByEntityEvent->getVerticalKnockBackLimit() : float`
|
||||
- `public EntityDamageByEntityEvent->setVerticalKnockBackLimit(float $verticalKnockBackLimit) : void` - sets the max vertical velocity that can result from the victim being knocked back
|
||||
|
||||
### `pocketmine\player`
|
||||
- The following new API methods have been added:
|
||||
- `public Player->getCreativeInventory() : pocketmine\inventory\CreativeInventory`
|
||||
- `public Player->setCreativeInventory(pocketmine\inventory\CreativeInventory $inventory) : void`
|
||||
- `public Player->missSwing() : void` - performs actions associated with the attack action when there is no target (see `PlayerMissSwingEvent`)
|
||||
|
||||
### `pocketmine\scheduler`
|
||||
- Cancellation functionality has been removed from `AsyncTask`, as it didn't make any sense and wasn't used by anything for what it was intended for.
|
||||
- It broke sequential task execution - later tasks might depend on state from earlier tasks
|
||||
- It didn't actually cancel the task anyway - at best, it prevented it from running, but couldn't interrupt it (though interrupting a task does not make sense either)
|
||||
- The following API methods have been deprecated, and their functionality has been removed:
|
||||
- `AsyncTask->hasCancelledRun()`
|
||||
- `AsyncTask->cancelRun()`
|
||||
|
||||
## Internals
|
||||
- Uncaught exceptions and fatal errors in `AsyncTask`, threads extending `pocketmine\thread\Thread`, and `pocketmine\thread\Worker` are now recorded in crashdumps, making it significantly easier to debug errors in these areas.
|
||||
- JWT signature DER <-> raw conversions are now handled in-house using code in `JwtUtils`
|
||||
- Due to the simplicity of the conversion and only requiring a tiny subset of the ASN.1 spec, it didn't make much sense to introduce another dependency.
|
||||
- `fgrosse/phpasn1` is no longer required. This package was abandoned by its author and only used by PocketMine-MP for this one purpose.
|
||||
- Various usages of `Closure::fromCallable()` have been replaced by PHP 8.1 first-class callable syntax.
|
||||
- Blocks requiring support shifted to a "can be supported at" model, rather than "can be supported by".
|
||||
- This model reduces repeated logic when placing and performing nearby block updates (no need to hardcode facing everywhere).
|
||||
- In addition, this change facilitates the use of the newly introduced `Block->getAdjacentSupportType()` API method, reducing boilerplate support-type checking code.
|
||||
- Bell block code has been simplified and cleaned up.
|
||||
- `TallGrass` and `DoubleTallGrass` now use a shared `TallGrassTrait` to reduce code duplication.
|
||||
|
||||
# 5.4.1
|
||||
Released 8th August 2023.
|
||||
|
||||
## General
|
||||
- Updated translation data to [pmmp/Language 2.19.6](https://github.com/pmmp/Language/releases/tag/2.19.6).
|
||||
- [`ext-pmmpthread` 6.0.7](https://github.com/pmmp/ext-pmmpthread/releases/tag/6.0.7) is now required (needed for bug fixes).
|
||||
|
||||
## Fixes
|
||||
- Fixed Podzol not dropping itself when mined with Silk Touch.
|
||||
- Fixed `World->getSafeSpawn()` not accepting positions below `y=0` (world height limit change).
|
||||
- Fixed `pocketmine\thread\Thread` and `pocketmine\thread\Worker` instances not logging any information when they crash.
|
||||
- Fixed `CraftItemEvent` not cloning returned items.
|
||||
|
||||
## Internals
|
||||
- Foreach by-reference is now disallowed via a custom PHPStan rule.
|
||||
|
||||
# 5.4.2
|
||||
Released 9th August 2023.
|
||||
|
||||
## Included releases
|
||||
- [4.23.5](https://github.com/pmmp/PocketMine-MP/blob/4.23.5/changelogs/4.23.md#4235) - Minor bug fixes
|
||||
|
||||
## Fixes
|
||||
- Fixed cake accepting candle placement when slices have already been eaten.
|
||||
- Fixed fire charges not lighting candles.
|
||||
|
||||
# 5.4.3
|
||||
Released 21st August 2023.
|
||||
|
||||
## Included releases
|
||||
- [4.23.6](https://github.com/pmmp/PocketMine-MP/blob/4.23.6/changelogs/4.23.md#4236) - Armor inventory client bug workaround
|
||||
|
||||
## Fixes
|
||||
- Fixed crashdumps not generating correctly on fatal errors.
|
||||
- Fixed `PotionCauldron::setPotionItem()` not validating the item type.
|
||||
- Fixed chorus fruit not considering teleport destinations below y=0.
|
||||
- Fixed cake dropping itself when mined.
|
@ -22,7 +22,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pmmpthread": "^6.0.1",
|
||||
"ext-pmmpthread": "^6.0.7",
|
||||
"ext-reflection": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-sockets": "*",
|
||||
@ -31,13 +31,12 @@
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": ">=1.2.11",
|
||||
"composer-runtime-api": "^2.0",
|
||||
"adhocore/json-comment": "^1.1",
|
||||
"fgrosse/phpasn1": "^2.3",
|
||||
"pocketmine/netresearch-jsonmapper": "~v4.2.999",
|
||||
"pocketmine/bedrock-block-upgrade-schema": "~2.2.0+bedrock-1.20.0",
|
||||
"pocketmine/bedrock-data": "~2.3.0+bedrock-1.20.0",
|
||||
"pocketmine/bedrock-item-upgrade-schema": "~1.3.0+bedrock-1.20.0",
|
||||
"pocketmine/bedrock-protocol": "~22.0.0+bedrock-1.20.0",
|
||||
"adhocore/json-comment": "~1.2.0",
|
||||
"pocketmine/netresearch-jsonmapper": "~v4.2.1000",
|
||||
"pocketmine/bedrock-block-upgrade-schema": "~3.1.0+bedrock-1.20.10",
|
||||
"pocketmine/bedrock-data": "~2.4.0+bedrock-1.20.10",
|
||||
"pocketmine/bedrock-item-upgrade-schema": "~1.4.0+bedrock-1.20.10",
|
||||
"pocketmine/bedrock-protocol": "~23.0.2+bedrock-1.20.10",
|
||||
"pocketmine/binaryutils": "^0.2.1",
|
||||
"pocketmine/callback-validator": "^1.0.2",
|
||||
"pocketmine/color": "^0.3.0",
|
||||
@ -49,8 +48,8 @@
|
||||
"pocketmine/raklib": "^0.15.0",
|
||||
"pocketmine/raklib-ipc": "^0.2.0",
|
||||
"pocketmine/snooze": "^0.5.0",
|
||||
"ramsey/uuid": "^4.1",
|
||||
"symfony/filesystem": "^6.2"
|
||||
"ramsey/uuid": "~4.7.0",
|
||||
"symfony/filesystem": "~6.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "1.10.16",
|
||||
|
236
composer.lock
generated
236
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "5483e35c09044ab9d989cec8fdf4a399",
|
||||
"content-hash": "27b30e0ed071ba0e6733545a695c3586",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/json-comment",
|
||||
@ -120,94 +120,18 @@
|
||||
],
|
||||
"time": "2023-01-15T23:15:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fgrosse/phpasn1",
|
||||
"version": "v2.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fgrosse/PHPASN1.git",
|
||||
"reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fgrosse/PHPASN1/zipball/42060ed45344789fb9f21f9f1864fc47b9e3507b",
|
||||
"reference": "42060ed45344789fb9f21f9f1864fc47b9e3507b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "~2.0",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "BCmath is the fallback extension for big integer calculations",
|
||||
"ext-curl": "For loading OID information from the web if they have not bee defined statically",
|
||||
"ext-gmp": "GMP is the preferred extension for big integer calculations",
|
||||
"phpseclib/bcmath_compat": "BCmath polyfill for servers where neither GMP nor BCmath is available"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FG\\": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Friedrich Große",
|
||||
"email": "friedrich.grosse@gmail.com",
|
||||
"homepage": "https://github.com/FGrosse",
|
||||
"role": "Author"
|
||||
},
|
||||
{
|
||||
"name": "All contributors",
|
||||
"homepage": "https://github.com/FGrosse/PHPASN1/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A PHP Framework that allows you to encode and decode arbitrary ASN.1 structures using the ITU-T X.690 Encoding Rules.",
|
||||
"homepage": "https://github.com/FGrosse/PHPASN1",
|
||||
"keywords": [
|
||||
"DER",
|
||||
"asn.1",
|
||||
"asn1",
|
||||
"ber",
|
||||
"binary",
|
||||
"decoding",
|
||||
"encoding",
|
||||
"x.509",
|
||||
"x.690",
|
||||
"x509",
|
||||
"x690"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/fgrosse/PHPASN1/issues",
|
||||
"source": "https://github.com/fgrosse/PHPASN1/tree/v2.5.0"
|
||||
},
|
||||
"abandoned": true,
|
||||
"time": "2022-12-19T11:08:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-block-upgrade-schema",
|
||||
"version": "2.2.0",
|
||||
"version": "3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockBlockUpgradeSchema.git",
|
||||
"reference": "79bb3ad542ef19e828fdf1fa6adc54f1fa4b3bb5"
|
||||
"reference": "6d4ae416043337946a22fc31e8065ca2c21f472d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/79bb3ad542ef19e828fdf1fa6adc54f1fa4b3bb5",
|
||||
"reference": "79bb3ad542ef19e828fdf1fa6adc54f1fa4b3bb5",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockBlockUpgradeSchema/zipball/6d4ae416043337946a22fc31e8065ca2c21f472d",
|
||||
"reference": "6d4ae416043337946a22fc31e8065ca2c21f472d",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -218,22 +142,22 @@
|
||||
"description": "Schemas describing how to upgrade saved block data in older Minecraft: Bedrock Edition world saves",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockBlockUpgradeSchema/issues",
|
||||
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/2.2.0"
|
||||
"source": "https://github.com/pmmp/BedrockBlockUpgradeSchema/tree/3.1.0"
|
||||
},
|
||||
"time": "2023-05-04T21:49:36+00:00"
|
||||
"time": "2023-07-12T12:05:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-data",
|
||||
"version": "2.3.0+bedrock-1.20.0",
|
||||
"version": "2.4.0+bedrock-1.20.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockData.git",
|
||||
"reference": "b3dd3f4b8e3b6759c5d84de6ec85bb20b668c3a9"
|
||||
"reference": "f98bd1cae46d2920058acf3b23c0bedeac79f4ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/b3dd3f4b8e3b6759c5d84de6ec85bb20b668c3a9",
|
||||
"reference": "b3dd3f4b8e3b6759c5d84de6ec85bb20b668c3a9",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockData/zipball/f98bd1cae46d2920058acf3b23c0bedeac79f4ab",
|
||||
"reference": "f98bd1cae46d2920058acf3b23c0bedeac79f4ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -244,22 +168,22 @@
|
||||
"description": "Blobs of data generated from Minecraft: Bedrock Edition, used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockData/issues",
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.20.0"
|
||||
"source": "https://github.com/pmmp/BedrockData/tree/bedrock-1.20.10"
|
||||
},
|
||||
"time": "2023-06-07T19:06:47+00:00"
|
||||
"time": "2023-07-12T11:51:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-item-upgrade-schema",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockItemUpgradeSchema.git",
|
||||
"reference": "b16c59cfae08833f180dd82f88de7c1f43bc67c9"
|
||||
"reference": "60d199afe5e371fd189b21d685ec1fed6ba54230"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/b16c59cfae08833f180dd82f88de7c1f43bc67c9",
|
||||
"reference": "b16c59cfae08833f180dd82f88de7c1f43bc67c9",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockItemUpgradeSchema/zipball/60d199afe5e371fd189b21d685ec1fed6ba54230",
|
||||
"reference": "60d199afe5e371fd189b21d685ec1fed6ba54230",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -270,22 +194,22 @@
|
||||
"description": "JSON schemas for upgrading items found in older Minecraft: Bedrock world saves",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockItemUpgradeSchema/issues",
|
||||
"source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.3.0"
|
||||
"source": "https://github.com/pmmp/BedrockItemUpgradeSchema/tree/1.4.0"
|
||||
},
|
||||
"time": "2023-05-18T15:34:32+00:00"
|
||||
"time": "2023-07-12T12:08:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/bedrock-protocol",
|
||||
"version": "22.0.0+bedrock-1.20.0",
|
||||
"version": "23.0.3+bedrock-1.20.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/BedrockProtocol.git",
|
||||
"reference": "ceff28a0bd5d248f37fb97be3e836d536e37526e"
|
||||
"reference": "e4157c7af3f91e1b08fe21be171eb73dad7029e9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/ceff28a0bd5d248f37fb97be3e836d536e37526e",
|
||||
"reference": "ceff28a0bd5d248f37fb97be3e836d536e37526e",
|
||||
"url": "https://api.github.com/repos/pmmp/BedrockProtocol/zipball/e4157c7af3f91e1b08fe21be171eb73dad7029e9",
|
||||
"reference": "e4157c7af3f91e1b08fe21be171eb73dad7029e9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -294,8 +218,8 @@
|
||||
"php": "^8.0",
|
||||
"pocketmine/binaryutils": "^0.2.0",
|
||||
"pocketmine/color": "^0.2.0 || ^0.3.0",
|
||||
"pocketmine/math": "^0.3.0 || ^0.4.0",
|
||||
"pocketmine/nbt": "^0.3.0",
|
||||
"pocketmine/math": "^0.3.0 || ^0.4.0 || ^1.0.0",
|
||||
"pocketmine/nbt": "^0.3.0 || ^1.0.0",
|
||||
"ramsey/uuid": "^4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
@ -317,9 +241,9 @@
|
||||
"description": "An implementation of the Minecraft: Bedrock Edition protocol in PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/BedrockProtocol/issues",
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/22.0.0+bedrock-1.20.0"
|
||||
"source": "https://github.com/pmmp/BedrockProtocol/tree/23.0.3+bedrock-1.20.10"
|
||||
},
|
||||
"time": "2023-06-07T19:22:05+00:00"
|
||||
"time": "2023-08-03T15:30:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/binaryutils",
|
||||
@ -492,16 +416,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/locale-data",
|
||||
"version": "2.19.5",
|
||||
"version": "2.19.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/Language.git",
|
||||
"reference": "71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d"
|
||||
"reference": "93e473e20e7f4515ecf45c5ef0f9155b9247a86e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d",
|
||||
"reference": "71af5f9bd23b4e4bad8920dac7f4fe08e5205f7d",
|
||||
"url": "https://api.github.com/repos/pmmp/Language/zipball/93e473e20e7f4515ecf45c5ef0f9155b9247a86e",
|
||||
"reference": "93e473e20e7f4515ecf45c5ef0f9155b9247a86e",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
@ -509,9 +433,9 @@
|
||||
"description": "Language resources used by PocketMine-MP",
|
||||
"support": {
|
||||
"issues": "https://github.com/pmmp/Language/issues",
|
||||
"source": "https://github.com/pmmp/Language/tree/2.19.5"
|
||||
"source": "https://github.com/pmmp/Language/tree/2.19.6"
|
||||
},
|
||||
"time": "2023-03-19T16:45:15+00:00"
|
||||
"time": "2023-08-08T16:53:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/log",
|
||||
@ -639,16 +563,16 @@
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/netresearch-jsonmapper",
|
||||
"version": "v4.2.999",
|
||||
"version": "v4.2.1000",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pmmp/netresearch-jsonmapper.git",
|
||||
"reference": "f700806dec756ed825a8200dc2950ead98265956"
|
||||
"reference": "078764e869e9b732f97206ec9363480a77c35532"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pmmp/netresearch-jsonmapper/zipball/f700806dec756ed825a8200dc2950ead98265956",
|
||||
"reference": "f700806dec756ed825a8200dc2950ead98265956",
|
||||
"url": "https://api.github.com/repos/pmmp/netresearch-jsonmapper/zipball/078764e869e9b732f97206ec9363480a77c35532",
|
||||
"reference": "078764e869e9b732f97206ec9363480a77c35532",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -687,9 +611,9 @@
|
||||
"support": {
|
||||
"email": "cweiske@cweiske.de",
|
||||
"issues": "https://github.com/cweiske/jsonmapper/issues",
|
||||
"source": "https://github.com/pmmp/netresearch-jsonmapper/tree/v4.2.999"
|
||||
"source": "https://github.com/pmmp/netresearch-jsonmapper/tree/v4.2.1000"
|
||||
},
|
||||
"time": "2023-06-01T13:43:01+00:00"
|
||||
"time": "2023-07-14T10:44:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pocketmine/raklib",
|
||||
@ -998,16 +922,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v6.2.10",
|
||||
"version": "v6.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894"
|
||||
"reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/fd588debf7d1bc16a2c84b4b3b71145d9946b894",
|
||||
"reference": "fd588debf7d1bc16a2c84b4b3b71145d9946b894",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
|
||||
"reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1041,7 +965,7 @@
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v6.2.10"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v6.3.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1057,7 +981,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-04-18T13:46:08+00:00"
|
||||
"time": "2023-06-01T08:30:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@ -1287,16 +1211,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.15.5",
|
||||
"version": "v4.17.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e"
|
||||
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/11e2663a5bc9db5d714eedb4277ee300403b4a9e",
|
||||
"reference": "11e2663a5bc9db5d714eedb4277ee300403b4a9e",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
|
||||
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1337,9 +1261,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.15.5"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
|
||||
},
|
||||
"time": "2023-05-19T20:20:00+00:00"
|
||||
"time": "2023-08-13T19:53:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@ -1617,16 +1541,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "10.1.2",
|
||||
"version": "10.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "db1497ec8dd382e82c962f7abbe0320e4882ee4e"
|
||||
"reference": "be1fe461fdc917de2a29a452ccf2657d325b443d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/db1497ec8dd382e82c962f7abbe0320e4882ee4e",
|
||||
"reference": "db1497ec8dd382e82c962f7abbe0320e4882ee4e",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/be1fe461fdc917de2a29a452ccf2657d325b443d",
|
||||
"reference": "be1fe461fdc917de2a29a452ccf2657d325b443d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1683,7 +1607,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
|
||||
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.2"
|
||||
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1691,7 +1615,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-05-22T09:04:27+00:00"
|
||||
"time": "2023-07-26T13:45:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
@ -1937,16 +1861,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "10.2.1",
|
||||
"version": "10.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "599b33294350e8f51163119d5670512f98b0490d"
|
||||
"reference": "0dafb1175c366dd274eaa9a625e914451506bcd1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/599b33294350e8f51163119d5670512f98b0490d",
|
||||
"reference": "599b33294350e8f51163119d5670512f98b0490d",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0dafb1175c366dd274eaa9a625e914451506bcd1",
|
||||
"reference": "0dafb1175c366dd274eaa9a625e914451506bcd1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1971,7 +1895,7 @@
|
||||
"sebastian/diff": "^5.0",
|
||||
"sebastian/environment": "^6.0",
|
||||
"sebastian/exporter": "^5.0",
|
||||
"sebastian/global-state": "^6.0",
|
||||
"sebastian/global-state": "^6.0.1",
|
||||
"sebastian/object-enumerator": "^5.0",
|
||||
"sebastian/recursion-context": "^5.0",
|
||||
"sebastian/type": "^4.0",
|
||||
@ -1986,7 +1910,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "10.2-dev"
|
||||
"dev-main": "10.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@ -2018,7 +1942,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.2.1"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2034,7 +1958,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-06-05T05:15:51+00:00"
|
||||
"time": "2023-08-15T05:34:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
@ -2205,16 +2129,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/comparator",
|
||||
"version": "5.0.0",
|
||||
"version": "5.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/comparator.git",
|
||||
"reference": "72f01e6586e0caf6af81297897bd112eb7e9627c"
|
||||
"reference": "2db5010a484d53ebf536087a70b4a5423c102372"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/72f01e6586e0caf6af81297897bd112eb7e9627c",
|
||||
"reference": "72f01e6586e0caf6af81297897bd112eb7e9627c",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372",
|
||||
"reference": "2db5010a484d53ebf536087a70b4a5423c102372",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2225,7 +2149,7 @@
|
||||
"sebastian/exporter": "^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0"
|
||||
"phpunit/phpunit": "^10.3"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@ -2269,7 +2193,8 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/comparator/issues",
|
||||
"source": "https://github.com/sebastianbergmann/comparator/tree/5.0.0"
|
||||
"security": "https://github.com/sebastianbergmann/comparator/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2277,7 +2202,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-03T07:07:16+00:00"
|
||||
"time": "2023-08-14T13:18:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/complexity",
|
||||
@ -2546,16 +2471,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
"version": "6.0.0",
|
||||
"version": "6.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/global-state.git",
|
||||
"reference": "aab257c712de87b90194febd52e4d184551c2d44"
|
||||
"reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/aab257c712de87b90194febd52e4d184551c2d44",
|
||||
"reference": "aab257c712de87b90194febd52e4d184551c2d44",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4",
|
||||
"reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2595,7 +2520,8 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/global-state/issues",
|
||||
"source": "https://github.com/sebastianbergmann/global-state/tree/6.0.0"
|
||||
"security": "https://github.com/sebastianbergmann/global-state/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2603,7 +2529,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-03T07:07:38+00:00"
|
||||
"time": "2023-07-19T07:19:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/lines-of-code",
|
||||
@ -3020,7 +2946,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-phar": "*",
|
||||
"ext-pmmpthread": "^6.0.1",
|
||||
"ext-pmmpthread": "^6.0.7",
|
||||
"ext-reflection": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-sockets": "*",
|
||||
|
@ -11,6 +11,7 @@ includes:
|
||||
|
||||
rules:
|
||||
- pocketmine\phpstan\rules\DisallowEnumComparisonRule
|
||||
- pocketmine\phpstan\rules\DisallowForeachByReferenceRule
|
||||
- pocketmine\phpstan\rules\UnsafeForeachArrayOfStringRule
|
||||
# - pocketmine\phpstan\rules\ThreadedSupportedTypesRule
|
||||
|
||||
@ -43,7 +44,6 @@ parameters:
|
||||
stubFiles:
|
||||
- tests/phpstan/stubs/JsonMapper.stub
|
||||
- tests/phpstan/stubs/leveldb.stub
|
||||
- tests/phpstan/stubs/phpasn1.stub
|
||||
- tests/phpstan/stubs/pmmpthread.stub
|
||||
reportUnmatchedIgnoredErrors: false #no other way to silence platform-specific non-warnings
|
||||
staticReflectionClassNamePatterns:
|
||||
|
@ -120,8 +120,8 @@ namespace pocketmine {
|
||||
}
|
||||
|
||||
if(($pmmpthread_version = phpversion("pmmpthread")) !== false){
|
||||
if(version_compare($pmmpthread_version, "6.0.1") < 0 || version_compare($pmmpthread_version, "7.0.0") >= 0){
|
||||
$messages[] = "pmmpthread ^6.0.1 is required, while you have $pmmpthread_version.";
|
||||
if(version_compare($pmmpthread_version, "6.0.7") < 0 || version_compare($pmmpthread_version, "7.0.0") >= 0){
|
||||
$messages[] = "pmmpthread ^6.0.7 is required, while you have $pmmpthread_version.";
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,7 +341,7 @@ JIT_WARNING
|
||||
|
||||
if(ThreadManager::getInstance()->stopAll() > 0){
|
||||
$logger->debug("Some threads could not be stopped, performing a force-kill");
|
||||
Process::kill(Process::pid(), true);
|
||||
Process::kill(Process::pid());
|
||||
}
|
||||
}while(false);
|
||||
|
||||
|
@ -93,6 +93,7 @@ use pocketmine\scheduler\AsyncPool;
|
||||
use pocketmine\snooze\SleeperHandler;
|
||||
use pocketmine\stats\SendUsageTask;
|
||||
use pocketmine\thread\log\AttachableThreadSafeLogger;
|
||||
use pocketmine\thread\ThreadCrashException;
|
||||
use pocketmine\thread\ThreadSafeClassLoader;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\timings\TimingsHandler;
|
||||
@ -1009,7 +1010,7 @@ class Server{
|
||||
|
||||
$this->playerDataProvider = new DatFilePlayerDataProvider(Path::join($this->dataPath, "players"));
|
||||
|
||||
register_shutdown_function([$this, "crashDump"]);
|
||||
register_shutdown_function($this->crashDump(...));
|
||||
|
||||
$loadErrorCount = 0;
|
||||
$this->pluginManager->loadPlugins($this->pluginPath, $loadErrorCount);
|
||||
@ -1427,7 +1428,7 @@ class Server{
|
||||
|
||||
private function forceShutdownExit() : void{
|
||||
$this->forceShutdown();
|
||||
Process::kill(Process::pid(), true);
|
||||
Process::kill(Process::pid());
|
||||
}
|
||||
|
||||
public function forceShutdown() : void{
|
||||
@ -1495,7 +1496,7 @@ class Server{
|
||||
}catch(\Throwable $e){
|
||||
$this->logger->logException($e);
|
||||
$this->logger->emergency("Crashed while crashing, killing process");
|
||||
@Process::kill(Process::pid(), true);
|
||||
@Process::kill(Process::pid());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1516,23 +1517,38 @@ class Server{
|
||||
$trace = $e->getTrace();
|
||||
}
|
||||
|
||||
$errstr = $e->getMessage();
|
||||
$errfile = $e->getFile();
|
||||
$errline = $e->getLine();
|
||||
//If this is a thread crash, this logs where the exception came from on the main thread, as opposed to the
|
||||
//crashed thread. This is intentional, and might be useful for debugging
|
||||
//Assume that the thread already logged the original exception with the correct stack trace
|
||||
$this->logger->logException($e, $trace);
|
||||
|
||||
if($e instanceof ThreadCrashException){
|
||||
$info = $e->getCrashInfo();
|
||||
$type = $info->getType();
|
||||
$errstr = $info->getMessage();
|
||||
$errfile = $info->getFile();
|
||||
$errline = $info->getLine();
|
||||
$printableTrace = $info->getTrace();
|
||||
$thread = $info->getThreadName();
|
||||
}else{
|
||||
$type = get_class($e);
|
||||
$errstr = $e->getMessage();
|
||||
$errfile = $e->getFile();
|
||||
$errline = $e->getLine();
|
||||
$printableTrace = Utils::printableTraceWithMetadata($trace);
|
||||
$thread = "Main";
|
||||
}
|
||||
|
||||
$errstr = preg_replace('/\s+/', ' ', trim($errstr));
|
||||
|
||||
$errfile = Filesystem::cleanPath($errfile);
|
||||
|
||||
$this->logger->logException($e, $trace);
|
||||
|
||||
$lastError = [
|
||||
"type" => get_class($e),
|
||||
"type" => $type,
|
||||
"message" => $errstr,
|
||||
"fullFile" => $e->getFile(),
|
||||
"file" => $errfile,
|
||||
"fullFile" => $errfile,
|
||||
"file" => Filesystem::cleanPath($errfile),
|
||||
"line" => $errline,
|
||||
"trace" => $trace
|
||||
"trace" => $printableTrace,
|
||||
"thread" => $thread
|
||||
];
|
||||
|
||||
global $lastExceptionError, $lastError;
|
||||
@ -1649,7 +1665,7 @@ class Server{
|
||||
echo "--- Waiting $spacing seconds to throttle automatic restart (you can kill the process safely now) ---" . PHP_EOL;
|
||||
sleep($spacing);
|
||||
}
|
||||
@Process::kill(Process::pid(), true);
|
||||
@Process::kill(Process::pid());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ use function str_repeat;
|
||||
|
||||
final class VersionInfo{
|
||||
public const NAME = "PocketMine-MP";
|
||||
public const BASE_VERSION = "5.1.1";
|
||||
public const BASE_VERSION = "5.4.3";
|
||||
public const IS_DEVELOPMENT_BUILD = false;
|
||||
public const BUILD_CHANNEL = "stable";
|
||||
|
||||
|
136
src/block/BaseBigDripleaf.php
Normal file
136
src/block/BaseBigDripleaf.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
|
||||
abstract class BaseBigDripleaf extends Transparent{
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
abstract protected function isHead() : bool;
|
||||
|
||||
private function canBeSupportedBy(Block $block, bool $head) : bool{
|
||||
//TODO: Moss block
|
||||
return
|
||||
($block instanceof BaseBigDripleaf && $block->isHead() === $head) ||
|
||||
$block->getTypeId() === BlockTypeIds::CLAY ||
|
||||
$block->hasTypeTag(BlockTypeTags::DIRT) ||
|
||||
$block->hasTypeTag(BlockTypeTags::MUD);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(
|
||||
(!$this->isHead() && !$this->getSide(Facing::UP) instanceof BaseBigDripleaf) ||
|
||||
!$this->canBeSupportedBy($this->getSide(Facing::DOWN), false)
|
||||
){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$block = $blockReplace->getSide(Facing::DOWN);
|
||||
if(!$this->canBeSupportedBy($block, true)){
|
||||
return false;
|
||||
}
|
||||
if($player !== null){
|
||||
$this->facing = Facing::opposite($player->getHorizontalFacing());
|
||||
}
|
||||
if($block instanceof BaseBigDripleaf){
|
||||
$this->facing = $block->getFacing();
|
||||
$tx->addBlock($block->getPosition(), VanillaBlocks::BIG_DRIPLEAF_STEM()->setFacing($this->facing));
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof Fertilizer && $this->grow($player)){
|
||||
$item->pop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function seekToHead() : ?BaseBigDripleaf{
|
||||
if($this->isHead()){
|
||||
return $this;
|
||||
}
|
||||
$step = 1;
|
||||
while(($next = $this->getSide(Facing::UP, $step)) instanceof BaseBigDripleaf){
|
||||
if($next->isHead()){
|
||||
return $next;
|
||||
}
|
||||
$step++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private function grow(?Player $player) : bool{
|
||||
$head = $this->seekToHead();
|
||||
if($head === null){
|
||||
return false;
|
||||
}
|
||||
$pos = $head->getPosition();
|
||||
$up = $pos->up();
|
||||
$world = $pos->getWorld();
|
||||
if(
|
||||
!$world->isInWorld($up->getFloorX(), $up->getFloorY(), $up->getFloorZ()) ||
|
||||
$world->getBlock($up)->getTypeId() !== BlockTypeIds::AIR
|
||||
){
|
||||
return false;
|
||||
}
|
||||
|
||||
$tx = new BlockTransaction($world);
|
||||
|
||||
$tx->addBlock($pos, VanillaBlocks::BIG_DRIPLEAF_STEM()->setFacing($head->getFacing()));
|
||||
$tx->addBlock($up, VanillaBlocks::BIG_DRIPLEAF_HEAD()->setFacing($head->getFacing()));
|
||||
|
||||
$ev = new StructureGrowEvent($head, $tx, $player);
|
||||
$ev->call();
|
||||
|
||||
if(!$ev->isCancelled()){
|
||||
return $tx->apply();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
}
|
@ -46,7 +46,7 @@ abstract class BaseCoral extends Transparent{
|
||||
|
||||
public function onScheduledUpdate() : void{
|
||||
if(!$this->dead && !$this->isCoveredWithWater()){
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev = new BlockDeathEvent($this, (clone $this)->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$this->position->getWorld()->setBlock($this->position, $ev->getNewState());
|
||||
|
@ -38,7 +38,7 @@ use function in_array;
|
||||
abstract class BaseRail extends Flowable{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($blockReplace->getSide(Facing::DOWN)->getSupportType(Facing::UP)->hasEdgeSupport()){
|
||||
if($blockReplace->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport()){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ abstract class BaseRail extends Flowable{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if(!$this->getSide(Facing::DOWN)->getSupportType(Facing::UP)->hasEdgeSupport()){
|
||||
if(!$this->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport()){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
foreach($this->getCurrentShapeConnections() as $connection){
|
||||
|
@ -177,11 +177,11 @@ class Bed extends Transparent{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if($this->canBeSupportedAt($blockReplace)){
|
||||
$this->facing = $player !== null ? $player->getHorizontalFacing() : Facing::NORTH;
|
||||
|
||||
$next = $this->getSide($this->getOtherHalfSide());
|
||||
if($next->canBeReplaced() && $this->canBeSupportedBy($next->getSide(Facing::DOWN))){
|
||||
if($next->canBeReplaced() && $this->canBeSupportedAt($next)){
|
||||
$nextState = clone $this;
|
||||
$nextState->head = true;
|
||||
$tx->addBlock($blockReplace->position, $this)->addBlock($next->position, $nextState);
|
||||
@ -208,8 +208,8 @@ class Bed extends Transparent{
|
||||
return parent::getAffectedBlocks();
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE());
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE());
|
||||
}
|
||||
|
||||
public function getMaxStackSize() : int{ return 1; }
|
||||
|
@ -23,9 +23,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
|
||||
class Beetroot extends Crops{
|
||||
|
||||
@ -33,7 +33,7 @@ class Beetroot extends Crops{
|
||||
if($this->age >= self::MAX_AGE){
|
||||
return [
|
||||
VanillaItems::BEETROOT(),
|
||||
VanillaItems::BEETROOT_SEEDS()->setCount(mt_rand(0, 3))
|
||||
VanillaItems::BEETROOT_SEEDS()->setCount(FortuneDropHelper::binomial($item, 0))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ use pocketmine\math\Facing;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\sound\BellRingSound;
|
||||
|
||||
@ -87,46 +88,44 @@ final class Bell extends Transparent{
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block, int $face) : bool{
|
||||
return !$block->getSupportType($face)->equals(SupportType::NONE());
|
||||
private function canBeSupportedAt(Block $block, int $face) : bool{
|
||||
return !$block->getAdjacentSupportType($face)->equals(SupportType::NONE());
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){
|
||||
return false;
|
||||
}
|
||||
if($face === Facing::UP){
|
||||
if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->down()), Facing::UP)){
|
||||
return false;
|
||||
}
|
||||
if($player !== null){
|
||||
$this->setFacing(Facing::opposite($player->getHorizontalFacing()));
|
||||
}
|
||||
$this->setAttachmentType(BellAttachmentType::FLOOR());
|
||||
}elseif($face === Facing::DOWN){
|
||||
if(!$this->canBeSupportedBy($tx->fetchBlock($this->position->up()), Facing::DOWN)){
|
||||
return false;
|
||||
}
|
||||
$this->setAttachmentType(BellAttachmentType::CEILING());
|
||||
}else{
|
||||
$this->setFacing($face);
|
||||
if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide(Facing::opposite($face))), $face)){
|
||||
$this->setAttachmentType(BellAttachmentType::ONE_WALL());
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
if($this->canBeSupportedBy($tx->fetchBlock($this->position->getSide($face)), Facing::opposite($face))){
|
||||
$this->setAttachmentType(BellAttachmentType::TWO_WALLS());
|
||||
}
|
||||
$this->setAttachmentType(
|
||||
$this->canBeSupportedAt($blockReplace, $face) ?
|
||||
BellAttachmentType::TWO_WALLS() :
|
||||
BellAttachmentType::ONE_WALL()
|
||||
);
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(
|
||||
($this->attachmentType->equals(BellAttachmentType::CEILING()) && !$this->canBeSupportedBy($this->getSide(Facing::UP), Facing::DOWN)) ||
|
||||
($this->attachmentType->equals(BellAttachmentType::FLOOR()) && !$this->canBeSupportedBy($this->getSide(Facing::DOWN), Facing::UP)) ||
|
||||
($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) && !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)) ||
|
||||
($this->attachmentType->equals(BellAttachmentType::TWO_WALLS()) && (!$this->canBeSupportedBy($this->getSide($this->facing), Facing::opposite($this->facing)) || !$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)))
|
||||
){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
foreach(match($this->attachmentType){
|
||||
BellAttachmentType::CEILING() => [Facing::UP],
|
||||
BellAttachmentType::FLOOR() => [Facing::DOWN],
|
||||
BellAttachmentType::ONE_WALL() => [Facing::opposite($this->facing)],
|
||||
BellAttachmentType::TWO_WALLS() => [$this->facing, Facing::opposite($this->facing)],
|
||||
default => throw new AssumptionFailedError("All cases of BellAttachmentType must be handled")
|
||||
} as $supportBlockDirection){
|
||||
if(!$this->canBeSupportedAt($this, $supportBlockDirection)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,13 +158,11 @@ final class Bell extends Transparent{
|
||||
}
|
||||
|
||||
private function isValidFaceToRing(int $faceHit) : bool{
|
||||
return (
|
||||
$this->attachmentType->equals(BellAttachmentType::CEILING()) ||
|
||||
($this->attachmentType->equals(BellAttachmentType::FLOOR()) && Facing::axis($faceHit) === Facing::axis($this->facing)) ||
|
||||
(
|
||||
($this->attachmentType->equals(BellAttachmentType::ONE_WALL()) || $this->attachmentType->equals(BellAttachmentType::TWO_WALLS())) &&
|
||||
($faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true))
|
||||
)
|
||||
);
|
||||
return match($this->attachmentType){
|
||||
BellAttachmentType::CEILING() => true,
|
||||
BellAttachmentType::FLOOR() => Facing::axis($faceHit) === Facing::axis($this->facing),
|
||||
BellAttachmentType::ONE_WALL(), BellAttachmentType::TWO_WALLS() => $faceHit === Facing::rotateY($this->facing, false) || $faceHit === Facing::rotateY($this->facing, true),
|
||||
default => throw new AssumptionFailedError("All cases of BellAttachmentType must be handled")
|
||||
};
|
||||
}
|
||||
}
|
||||
|
132
src/block/BigDripleafHead.php
Normal file
132
src/block/BigDripleafHead.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\DripleafState;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\projectile\Projectile;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\world\sound\DripleafTiltDownSound;
|
||||
use pocketmine\world\sound\DripleafTiltUpSound;
|
||||
|
||||
class BigDripleafHead extends BaseBigDripleaf{
|
||||
|
||||
protected DripleafState $leafState;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->leafState = DripleafState::STABLE();
|
||||
parent::__construct($idInfo, $name, $typeInfo);
|
||||
}
|
||||
|
||||
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
parent::describeBlockOnlyState($w);
|
||||
$w->dripleafState($this->leafState);
|
||||
}
|
||||
|
||||
protected function isHead() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLeafState() : DripleafState{
|
||||
return $this->leafState;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function setLeafState(DripleafState $leafState) : self{
|
||||
$this->leafState = $leafState;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasEntityCollision() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function setTiltAndScheduleTick(DripleafState $tilt) : void{
|
||||
$this->position->getWorld()->setBlock($this->position, $this->setLeafState($tilt));
|
||||
$delay = $tilt->getScheduledUpdateDelayTicks();
|
||||
if($delay !== null){
|
||||
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, $delay);
|
||||
}
|
||||
}
|
||||
|
||||
private function getLeafTopOffset() : float{
|
||||
return match($this->leafState){
|
||||
DripleafState::STABLE(), DripleafState::UNSTABLE() => 1 / 16,
|
||||
DripleafState::PARTIAL_TILT() => 3 / 16,
|
||||
default => 0
|
||||
};
|
||||
}
|
||||
|
||||
public function onEntityInside(Entity $entity) : bool{
|
||||
if(!$entity instanceof Projectile && $this->leafState->equals(DripleafState::STABLE())){
|
||||
//the entity must be standing on top of the leaf - do not collapse if the entity is standing underneath
|
||||
$intersection = AxisAlignedBB::one()
|
||||
->offset($this->position->x, $this->position->y, $this->position->z)
|
||||
->trim(Facing::DOWN, 1 - $this->getLeafTopOffset());
|
||||
if($entity->getBoundingBox()->intersectsWith($intersection)){
|
||||
$this->setTiltAndScheduleTick(DripleafState::UNSTABLE());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onProjectileHit(Projectile $projectile, RayTraceResult $hitResult) : void{
|
||||
if(!$this->leafState->equals(DripleafState::FULL_TILT())){
|
||||
$this->setTiltAndScheduleTick(DripleafState::FULL_TILT());
|
||||
$this->position->getWorld()->addSound($this->position, new DripleafTiltDownSound());
|
||||
}
|
||||
}
|
||||
|
||||
public function onScheduledUpdate() : void{
|
||||
if(!$this->leafState->equals(DripleafState::STABLE())){
|
||||
if($this->leafState->equals(DripleafState::FULL_TILT())){
|
||||
$this->position->getWorld()->setBlock($this->position, $this->setLeafState(DripleafState::STABLE()));
|
||||
$this->position->getWorld()->addSound($this->position, new DripleafTiltUpSound());
|
||||
}else{
|
||||
$this->setTiltAndScheduleTick(match($this->leafState->id()){
|
||||
DripleafState::UNSTABLE()->id() => DripleafState::PARTIAL_TILT(),
|
||||
DripleafState::PARTIAL_TILT()->id() => DripleafState::FULL_TILT(),
|
||||
default => throw new AssumptionFailedError("All types should be covered")
|
||||
});
|
||||
$this->position->getWorld()->addSound($this->position, new DripleafTiltDownSound());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
if(!$this->leafState->equals(DripleafState::FULL_TILT())){
|
||||
return [
|
||||
AxisAlignedBB::one()
|
||||
->trim(Facing::DOWN, 11 / 16)
|
||||
->trim(Facing::UP, $this->getLeafTopOffset())
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
41
src/block/BigDripleafStem.php
Normal file
41
src/block/BigDripleafStem.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class BigDripleafStem extends BaseBigDripleaf{
|
||||
|
||||
protected function isHead() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
return VanillaBlocks::BIG_DRIPLEAF_HEAD()->asItem();
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemBlock;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\RayTraceResult;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
@ -467,7 +468,8 @@ class Block{
|
||||
/**
|
||||
* Do actions when interacted by Item. Returns if it has done anything
|
||||
*
|
||||
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
|
||||
* @param Vector3 $clickVector Exact position where the click occurred, relative to the block's integer position
|
||||
* @param Item[] &$returnedItems Items to be added to the target's inventory (or dropped, if the inventory is full)
|
||||
*/
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
return false;
|
||||
@ -862,6 +864,10 @@ class Block{
|
||||
return SupportType::FULL();
|
||||
}
|
||||
|
||||
protected function getAdjacentSupportType(int $facing) : SupportType{
|
||||
return $this->getSide($facing)->getSupportType(Facing::opposite($facing));
|
||||
}
|
||||
|
||||
public function isFullCube() : bool{
|
||||
$bb = $this->getCollisionBoxes();
|
||||
|
||||
|
@ -717,8 +717,27 @@ final class BlockTypeIds{
|
||||
public const FLOWERING_AZALEA_LEAVES = 10687;
|
||||
public const REINFORCED_DEEPSLATE = 10688;
|
||||
public const CAVE_VINES = 10689;
|
||||
public const GLOW_LICHEN = 10690;
|
||||
public const CHERRY_BUTTON = 10691;
|
||||
public const CHERRY_DOOR = 10692;
|
||||
public const CHERRY_FENCE = 10693;
|
||||
public const CHERRY_FENCE_GATE = 10694;
|
||||
public const CHERRY_LEAVES = 10695;
|
||||
public const CHERRY_LOG = 10696;
|
||||
public const CHERRY_PLANKS = 10697;
|
||||
public const CHERRY_PRESSURE_PLATE = 10698;
|
||||
public const CHERRY_SAPLING = 10699;
|
||||
public const CHERRY_SIGN = 10700;
|
||||
public const CHERRY_SLAB = 10701;
|
||||
public const CHERRY_STAIRS = 10702;
|
||||
public const CHERRY_TRAPDOOR = 10703;
|
||||
public const CHERRY_WALL_SIGN = 10704;
|
||||
public const CHERRY_WOOD = 10705;
|
||||
public const SMALL_DRIPLEAF = 10706;
|
||||
public const BIG_DRIPLEAF_HEAD = 10707;
|
||||
public const BIG_DRIPLEAF_STEM = 10708;
|
||||
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10690;
|
||||
public const FIRST_UNUSED_BLOCK_ID = 10709;
|
||||
|
||||
private static int $nextDynamicId = self::FIRST_UNUSED_BLOCK_ID;
|
||||
|
||||
|
@ -52,7 +52,7 @@ abstract class Button extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){
|
||||
if($this->canBeSupportedAt($blockReplace, $face)){
|
||||
$this->facing = $face;
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
@ -83,12 +83,12 @@ abstract class Button extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){
|
||||
if(!$this->canBeSupportedAt($this, $this->facing)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $support, int $face) : bool{
|
||||
return $support->getSupportType($face)->hasCenterSupport();
|
||||
private function canBeSupportedAt(Block $block, int $face) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::opposite($face))->hasCenterSupport();
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class Cake extends BaseCake{
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof ItemBlock){
|
||||
if($this->bites === 0 && $item instanceof ItemBlock){
|
||||
$block = $item->getBlock();
|
||||
$resultBlock = null;
|
||||
if($block->getTypeId() === BlockTypeIds::CANDLE){
|
||||
@ -83,6 +83,10 @@ class Cake extends BaseCake{
|
||||
return parent::onInteract($item, $face, $clickVector, $player, $returnedItems);
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getResidue() : Block{
|
||||
$clone = clone $this;
|
||||
$clone->bites++;
|
||||
|
@ -64,7 +64,7 @@ class CakeWithCandle extends BaseCake{
|
||||
}
|
||||
|
||||
public function getPickedItem(bool $addUserData = false) : Item{
|
||||
return VanillaBlocks::CAKE()->getPickedItem($addUserData);
|
||||
return VanillaBlocks::CAKE()->asItem();
|
||||
}
|
||||
|
||||
public function getResidue() : Block{
|
||||
|
@ -104,8 +104,7 @@ class Candle extends Transparent{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$down = $blockReplace->getSide(Facing::DOWN);
|
||||
if(!$down->getSupportType(Facing::UP)->hasCenterSupport()){
|
||||
if(!$blockReplace->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport()){
|
||||
return false;
|
||||
}
|
||||
$existing = $this->getCandleIfCompatibleType($blockReplace);
|
||||
|
@ -23,15 +23,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
|
||||
class Carrot extends Crops{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::CARROT()->setCount($this->age >= self::MAX_AGE ? mt_rand(1, 4) : 1)
|
||||
VanillaItems::CARROT()->setCount($this->age >= self::MAX_AGE ? FortuneDropHelper::binomial($item, 1) : 1)
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,7 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
|
||||
class CarvedPumpkin extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
}
|
||||
|
@ -87,18 +87,18 @@ class CaveVines extends Flowable{
|
||||
return $this->berries ? 14 : 0;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::DOWN)->equals(SupportType::FULL()) || $block->hasSameTypeId($this);
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::UP)->equals(SupportType::FULL()) || $block->hasSameTypeId($this);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::UP))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP))){
|
||||
if(!$this->canBeSupportedAt($blockReplace)){
|
||||
return false;
|
||||
}
|
||||
$this->age = mt_rand(0, self::MAX_AGE);
|
||||
|
@ -24,14 +24,12 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
final class ChemistryTable extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
//TODO
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Chest as TileChest;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\event\block\ChestPairEvent;
|
||||
use pocketmine\item\Item;
|
||||
@ -36,7 +35,6 @@ use pocketmine\player\Player;
|
||||
|
||||
class Chest extends Transparent{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
@ -31,7 +32,7 @@ class CoalOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::COAL()
|
||||
VanillaItems::COAL()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -23,13 +23,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
|
||||
final class CopperOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [VanillaItems::RAW_COPPER()];
|
||||
return [
|
||||
VanillaItems::RAW_COPPER()->setCount(FortuneDropHelper::weighted($item, min: 2, maxBase: 5)),
|
||||
];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{ return true; }
|
||||
|
@ -32,7 +32,7 @@ use pocketmine\world\BlockTransaction;
|
||||
final class Coral extends BaseCoral{
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($tx->fetchBlock($blockReplace->getPosition()->down()))){
|
||||
if(!$this->canBeSupportedAt($blockReplace)){
|
||||
return false;
|
||||
}
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
@ -40,14 +40,14 @@ final class Coral extends BaseCoral{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if(!$this->canBeSupportedBy($world->getBlock($this->position->down()))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
parent::onNearbyBlockChange();
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::UP)->hasCenterSupport();
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport();
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ final class CoralBlock extends Opaque{
|
||||
}
|
||||
}
|
||||
if(!$hasWater){
|
||||
$ev = new BlockDeathEvent($this, $this->setDead(true));
|
||||
$ev = new BlockDeathEvent($this, (clone $this)->setDead(true));
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$world->setBlock($this->position, $ev->getNewState());
|
||||
@ -65,7 +65,7 @@ final class CoralBlock extends Opaque{
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [$this->setDead(true)->asItem()];
|
||||
return [(clone $this)->setDead(true)->asItem()];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
@ -31,7 +32,7 @@ class DiamondOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::DIAMOND()
|
||||
VanillaItems::DIAMOND()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Door extends Transparent{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN)) && !$this->getSide(Facing::DOWN) instanceof Door){ //Replace with common break method
|
||||
if(!$this->canBeSupportedAt($this) && !$this->getSide(Facing::DOWN) instanceof Door){ //Replace with common break method
|
||||
$this->position->getWorld()->useBreakOn($this->position); //this will delete both halves if they exist
|
||||
}
|
||||
}
|
||||
@ -114,8 +114,7 @@ class Door extends Transparent{
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($face === Facing::UP){
|
||||
$blockUp = $this->getSide(Facing::UP);
|
||||
$blockDown = $this->getSide(Facing::DOWN);
|
||||
if(!$blockUp->canBeReplaced() || !$this->canBeSupportedBy($blockDown)){
|
||||
if(!$blockUp->canBeReplaced() || !$this->canBeSupportedAt($blockReplace)){
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -172,7 +171,7 @@ class Door extends Transparent{
|
||||
return parent::getAffectedBlocks();
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::UP)->hasEdgeSupport();
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::DOWN)->hasEdgeSupport();
|
||||
}
|
||||
}
|
||||
|
@ -23,19 +23,21 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\TallGrassTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
|
||||
class DoubleTallGrass extends DoublePlant{
|
||||
use TallGrassTrait {
|
||||
getDropsForIncompatibleTool as traitGetDropsForIncompatibleTool;
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDropsForIncompatibleTool(Item $item) : array{
|
||||
if($this->top && mt_rand(0, 7) === 0){
|
||||
return [VanillaItems::WHEAT_SEEDS()];
|
||||
if($this->top){
|
||||
return $this->traitGetDropsForIncompatibleTool($item);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
@ -31,7 +32,7 @@ class EmeraldOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::EMERALD()
|
||||
VanillaItems::EMERALD()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -24,14 +24,12 @@ declare(strict_types=1);
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
|
||||
class EndPortalFrame extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected bool $eye = false;
|
||||
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\inventory\EnderChestInventory;
|
||||
use pocketmine\block\tile\EnderChest as TileEnderChest;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -36,7 +35,6 @@ use pocketmine\player\Player;
|
||||
|
||||
class EnderChest extends Transparent{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 7;
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockBurnEvent;
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
@ -58,12 +59,16 @@ class Fire extends BaseFire{
|
||||
return 1;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::UP)->equals(SupportType::FULL());
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
$down = $this->getSide(Facing::DOWN);
|
||||
if(SoulFire::canBeSupportedBy($down)){
|
||||
$world->setBlock($this->position, VanillaBlocks::SOUL_FIRE());
|
||||
}elseif($down->isTransparent() && !$this->hasAdjacentFlammableBlocks()){
|
||||
}elseif(!$this->canBeSupportedBy($this->getSide(Facing::DOWN)) && !$this->hasAdjacentFlammableBlocks()){
|
||||
$world->setBlock($this->position, VanillaBlocks::AIR());
|
||||
}else{
|
||||
$world->scheduleDelayedBlockUpdate($this->position, mt_rand(30, 40));
|
||||
|
@ -53,7 +53,7 @@ final class FloorCoralFan extends BaseCoral{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($tx->fetchBlock($blockReplace->getPosition()->down()))){
|
||||
if(!$this->canBeSupportedAt($blockReplace)){
|
||||
return false;
|
||||
}
|
||||
if($player !== null){
|
||||
@ -75,15 +75,15 @@ final class FloorCoralFan extends BaseCoral{
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if(!$this->canBeSupportedBy($world->getBlock($this->position->down()))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
parent::onNearbyBlockChange();
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::UP)->hasCenterSupport();
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport();
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
|
@ -90,7 +90,7 @@ class FlowerPot extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if(!$this->canBeSupportedAt($blockReplace)){
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -98,13 +98,13 @@ class FlowerPot extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::UP)->hasCenterSupport();
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport();
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
|
@ -48,12 +48,7 @@ class FrostedIce extends Ice{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$world = $this->position->getWorld();
|
||||
if(!$this->checkAdjacentBlocks(2)){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
$world->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40));
|
||||
}
|
||||
$this->position->getWorld()->scheduleDelayedBlockUpdate($this->position, mt_rand(20, 40));
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Furnace as TileFurnace;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\crafting\FurnaceType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
@ -35,7 +34,6 @@ use function mt_rand;
|
||||
|
||||
class Furnace extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected FurnaceType $furnaceType;
|
||||
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
@ -30,7 +31,7 @@ use function mt_rand;
|
||||
final class GildedBlackstone extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(mt_rand(1, 10) === 1){
|
||||
if(FortuneDropHelper::bonusChanceDivisor($item, 10, 3)){
|
||||
return [VanillaItems::GOLD_NUGGET()->setCount(mt_rand(2, 5))];
|
||||
}
|
||||
|
||||
|
@ -26,12 +26,10 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\utils\ColoredTrait;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
|
||||
class GlazedTerracotta extends Opaque{
|
||||
use ColoredTrait;
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function __construct(BlockIdentifier $idInfo, string $name, BlockTypeInfo $typeInfo){
|
||||
$this->color = DyeColor::BLACK();
|
||||
|
284
src/block/GlowLichen.php
Normal file
284
src/block/GlowLichen.php
Normal file
@ -0,0 +1,284 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockSpreadEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\World;
|
||||
use function array_key_first;
|
||||
use function count;
|
||||
use function shuffle;
|
||||
|
||||
class GlowLichen extends Transparent{
|
||||
|
||||
/** @var int[] */
|
||||
protected array $faces = [];
|
||||
|
||||
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
$w->facingFlags($this->faces);
|
||||
}
|
||||
|
||||
/** @return int[] */
|
||||
public function getFaces() : array{ return $this->faces; }
|
||||
|
||||
public function hasFace(int $face) : bool{
|
||||
return isset($this->faces[$face]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $faces
|
||||
* @return $this
|
||||
*/
|
||||
public function setFaces(array $faces) : self{
|
||||
$uniqueFaces = [];
|
||||
foreach($faces as $face){
|
||||
Facing::validate($face);
|
||||
$uniqueFaces[$face] = $face;
|
||||
}
|
||||
$this->faces = $uniqueFaces;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function setFace(int $face, bool $value) : self{
|
||||
Facing::validate($face);
|
||||
if($value){
|
||||
$this->faces[$face] = $face;
|
||||
}else{
|
||||
unset($this->faces[$face]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLightLevel() : int{
|
||||
return 7;
|
||||
}
|
||||
|
||||
public function isSolid() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return AxisAlignedBB[]
|
||||
*/
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$this->faces = $blockReplace instanceof GlowLichen ? $blockReplace->faces : [];
|
||||
$availableFaces = $this->getAvailableFaces();
|
||||
|
||||
if(count($availableFaces) === 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
$opposite = Facing::opposite($face);
|
||||
$placedFace = isset($availableFaces[$opposite]) ? $opposite : array_key_first($availableFaces);
|
||||
$this->faces[$placedFace] = $placedFace;
|
||||
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$changed = false;
|
||||
|
||||
foreach($this->faces as $face){
|
||||
if(!$this->getAdjacentSupportType($face)->equals(SupportType::FULL())){
|
||||
unset($this->faces[$face]);
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($changed){
|
||||
$world = $this->position->getWorld();
|
||||
if(count($this->faces) === 0){
|
||||
$world->useBreakOn($this->position);
|
||||
}else{
|
||||
$world->setBlock($this->position, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getSpreadBlock(Block $replace, int $spreadFace) : ?Block{
|
||||
if($replace instanceof self && $replace->hasSameTypeId($this)){
|
||||
if($replace->hasFace($spreadFace)){
|
||||
return null;
|
||||
}
|
||||
$result = $replace;
|
||||
}elseif($replace->getTypeId() === BlockTypeIds::AIR){
|
||||
$result = VanillaBlocks::GLOW_LICHEN();
|
||||
}else{
|
||||
//TODO: if this is a water block, generate a waterlogged block
|
||||
return null;
|
||||
}
|
||||
return $result->setFace($spreadFace, true);
|
||||
}
|
||||
|
||||
private function spread(World $world, Vector3 $replacePos, int $spreadFace) : bool{
|
||||
$supportBlock = $world->getBlock($replacePos->getSide($spreadFace));
|
||||
$supportFace = Facing::opposite($spreadFace);
|
||||
|
||||
if(!$supportBlock->getSupportType($supportFace)->equals(SupportType::FULL())){
|
||||
return false;
|
||||
}
|
||||
|
||||
$replacedBlock = $supportBlock->getSide($supportFace);
|
||||
$replacementBlock = $this->getSpreadBlock($replacedBlock, Facing::opposite($supportFace));
|
||||
if($replacementBlock === null){
|
||||
return false;
|
||||
}
|
||||
|
||||
$ev = new BlockSpreadEvent($replacedBlock, $this, $replacementBlock);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$world->setBlock($replacedBlock->getPosition(), $ev->getNewState());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return \Generator<int, int, void, void>
|
||||
*/
|
||||
private static function getShuffledSpreadFaces(int $sourceFace) : \Generator{
|
||||
$skipAxis = Facing::axis($sourceFace);
|
||||
|
||||
$faces = Facing::ALL;
|
||||
shuffle($faces);
|
||||
foreach($faces as $spreadFace){
|
||||
if(Facing::axis($spreadFace) !== $skipAxis){
|
||||
yield $spreadFace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function spreadAroundSupport(int $sourceFace) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
$supportPos = $this->position->getSide($sourceFace);
|
||||
foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){
|
||||
$replacePos = $supportPos->getSide($spreadFace);
|
||||
if($this->spread($world, $replacePos, Facing::opposite($spreadFace))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function spreadAdjacentToSupport(int $sourceFace) : bool{
|
||||
$world = $this->position->getWorld();
|
||||
|
||||
foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){
|
||||
$replacePos = $this->position->getSide($spreadFace);
|
||||
if($this->spread($world, $replacePos, $sourceFace)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function spreadWithinSelf(int $sourceFace) : bool{
|
||||
foreach(self::getShuffledSpreadFaces($sourceFace) as $spreadFace){
|
||||
if(!$this->hasFace($spreadFace) && $this->spread($this->position->getWorld(), $this->position, $spreadFace)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof Fertilizer && count($this->faces) > 0){
|
||||
$shuffledFaces = $this->faces;
|
||||
shuffle($shuffledFaces);
|
||||
|
||||
$spreadMethods = [
|
||||
$this->spreadAroundSupport(...),
|
||||
$this->spreadAdjacentToSupport(...),
|
||||
$this->spreadWithinSelf(...),
|
||||
];
|
||||
shuffle($spreadMethods);
|
||||
|
||||
foreach($shuffledFaces as $sourceFace){
|
||||
foreach($spreadMethods as $spreadMethod){
|
||||
if($spreadMethod($sourceFace)){
|
||||
$item->pop();
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item) : array{
|
||||
if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0){
|
||||
return $this->getDropsForCompatibleTool($item);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, int> $faces
|
||||
*/
|
||||
private function getAvailableFaces() : array{
|
||||
$faces = [];
|
||||
foreach(Facing::ALL as $face){
|
||||
if(!$this->hasFace($face) && $this->getAdjacentSupportType($face)->equals(SupportType::FULL())){
|
||||
$faces[$face] = $face;
|
||||
}
|
||||
}
|
||||
return $faces;
|
||||
}
|
||||
}
|
@ -23,9 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
use function min;
|
||||
|
||||
class Glowstone extends Transparent{
|
||||
|
||||
@ -35,7 +36,7 @@ class Glowstone extends Transparent{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::GLOWSTONE_DUST()->setCount(mt_rand(2, 4))
|
||||
VanillaItems::GLOWSTONE_DUST()->setCount(min(4, FortuneDropHelper::discrete($item, 2, 4)))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -25,15 +25,15 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\Fallable;
|
||||
use pocketmine\block\utils\FallableTrait;
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
|
||||
class Gravel extends Opaque implements Fallable{
|
||||
use FallableTrait;
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(mt_rand(1, 10) === 1){
|
||||
if(FortuneDropHelper::bonusChanceDivisor($item, 10, 3)){
|
||||
return [
|
||||
VanillaItems::FLINT()
|
||||
];
|
||||
|
@ -163,18 +163,18 @@ class ItemFrame extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block, int $face) : bool{
|
||||
return !$block->getSupportType($face)->equals(SupportType::NONE());
|
||||
private function canBeSupportedAt(Block $block, int $face) : bool{
|
||||
return !$block->getAdjacentSupportType($face)->equals(SupportType::NONE());
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){
|
||||
if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){
|
||||
if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ class Ladder extends Transparent{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face) && Facing::axis($face) !== Axis::Y){
|
||||
if($this->canBeSupportedAt($blockReplace, Facing::opposite($face)) && Facing::axis($face) !== Axis::Y){
|
||||
$this->facing = $face;
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
@ -79,12 +79,12 @@ class Ladder extends Transparent{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($this->facing)), $this->facing)){ //Replace with common break method
|
||||
if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){ //Replace with common break method
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block, int $face) : bool{
|
||||
return $block->getSupportType($face)->equals(SupportType::FULL());
|
||||
private function canBeSupportedAt(Block $block, int $face) : bool{
|
||||
return $block->getAdjacentSupportType($face)->equals(SupportType::FULL());
|
||||
}
|
||||
}
|
||||
|
@ -77,22 +77,23 @@ class Lantern extends Transparent{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP), Facing::DOWN) && !$this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN), Facing::UP)){
|
||||
$downSupport = $this->canBeSupportedAt($blockReplace, Facing::DOWN);
|
||||
if(!$downSupport && !$this->canBeSupportedAt($blockReplace, Facing::UP)){
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->hanging = ($face === Facing::DOWN || !$this->canBeSupportedBy($this->position->getWorld()->getBlock($blockReplace->getPosition()->down()), Facing::UP));
|
||||
$this->hanging = $face === Facing::DOWN || !$downSupport;
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$face = $this->hanging ? Facing::UP : Facing::DOWN;
|
||||
if(!$this->canBeSupportedBy($this->getSide($face), Facing::opposite($face))){
|
||||
if(!$this->canBeSupportedAt($this, $face)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block, int $face) : bool{
|
||||
return $block->getSupportType($face)->hasCenterSupport();
|
||||
private function canBeSupportedAt(Block $block, int $face) : bool{
|
||||
return $block->getAdjacentSupportType($face)->hasCenterSupport();
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
@ -31,7 +32,7 @@ class LapisOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::LAPIS_LAZULI()->setCount(mt_rand(4, 8))
|
||||
VanillaItems::LAPIS_LAZULI()->setCount(FortuneDropHelper::weighted($item, min: 4, maxBase: 9))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\block\utils\LeavesType;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
@ -138,7 +139,8 @@ class Leaves extends Transparent{
|
||||
}
|
||||
|
||||
$drops = [];
|
||||
if(mt_rand(1, 20) === 1){ //Saplings
|
||||
if(FortuneDropHelper::bonusChanceDivisor($item, 20, 4)){ //Saplings
|
||||
// TODO: according to the wiki, the jungle saplings have a different drop rate
|
||||
$sapling = (match($this->leavesType){
|
||||
LeavesType::ACACIA() => VanillaBlocks::ACACIA_SAPLING(),
|
||||
LeavesType::BIRCH() => VanillaBlocks::BIRCH_SAPLING(),
|
||||
@ -148,16 +150,20 @@ class Leaves extends Transparent{
|
||||
LeavesType::SPRUCE() => VanillaBlocks::SPRUCE_SAPLING(),
|
||||
LeavesType::MANGROVE(), //TODO: mangrove propagule
|
||||
LeavesType::AZALEA(), LeavesType::FLOWERING_AZALEA() => null, //TODO: azalea
|
||||
LeavesType::CHERRY() => null, //TODO: cherry
|
||||
default => throw new AssumptionFailedError("Unreachable")
|
||||
})?->asItem();
|
||||
if($sapling !== null){
|
||||
$drops[] = $sapling;
|
||||
}
|
||||
}
|
||||
if(($this->leavesType->equals(LeavesType::OAK()) || $this->leavesType->equals(LeavesType::DARK_OAK())) && mt_rand(1, 200) === 1){ //Apples
|
||||
if(
|
||||
($this->leavesType->equals(LeavesType::OAK()) || $this->leavesType->equals(LeavesType::DARK_OAK())) &&
|
||||
FortuneDropHelper::bonusChanceDivisor($item, 200, 20)
|
||||
){ //Apples
|
||||
$drops[] = VanillaItems::APPLE();
|
||||
}
|
||||
if(mt_rand(1, 50) === 1){
|
||||
if(FortuneDropHelper::bonusChanceDivisor($item, 50, 5)){
|
||||
$drops[] = VanillaItems::STICK()->setCount(mt_rand(1, 2));
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\Lectern as TileLectern;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
@ -39,7 +38,6 @@ use function count;
|
||||
|
||||
class Lectern extends Transparent{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected int $viewedPage = 0;
|
||||
protected ?WritableBookBase $book = null;
|
||||
|
@ -66,7 +66,7 @@ class Lever extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){
|
||||
if(!$this->canBeSupportedAt($blockReplace, Facing::opposite($face))){
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -90,8 +90,7 @@ class Lever extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$facing = $this->facing->getFacing();
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::opposite($facing)), $facing)){
|
||||
if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing->getFacing()))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
@ -107,8 +106,8 @@ class Lever extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block, int $face) : bool{
|
||||
return $block->getSupportType($face)->hasCenterSupport();
|
||||
private function canBeSupportedAt(Block $block, int $face) : bool{
|
||||
return $block->getAdjacentSupportType($face)->hasCenterSupport();
|
||||
}
|
||||
|
||||
//TODO
|
||||
|
@ -312,7 +312,7 @@ abstract class Liquid extends Transparent{
|
||||
}
|
||||
|
||||
if($adjacentDecay <= self::MAX_DECAY){
|
||||
$calculator = new MinimumCostFlowCalculator($world, $this->getFlowDecayPerBlock(), \Closure::fromCallable([$this, 'canFlowInto']));
|
||||
$calculator = new MinimumCostFlowCalculator($world, $this->getFlowDecayPerBlock(), $this->canFlowInto(...));
|
||||
foreach($calculator->getOptimalFlowDirections($this->position->getFloorX(), $this->position->getFloorY(), $this->position->getFloorZ()) as $facing){
|
||||
$this->flowIntoBlock($world->getBlock($this->position->getSide($facing)), $adjacentDecay, false);
|
||||
}
|
||||
|
@ -25,14 +25,12 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\inventory\LoomInventory;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
|
||||
final class Loom extends Opaque{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player !== null){
|
||||
|
@ -23,15 +23,16 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
use function min;
|
||||
|
||||
class Melon extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::MELON()->setCount(mt_rand(3, 7))
|
||||
VanillaItems::MELON()->setCount(min(9, FortuneDropHelper::discrete($item, 3, 7)))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -23,14 +23,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
|
||||
final class NetherGoldOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [VanillaItems::GOLD_NUGGET()->setCount(mt_rand(2, 6))];
|
||||
return [VanillaItems::GOLD_NUGGET()->setCount(FortuneDropHelper::weighted($item, min: 2, maxBase: 6))];
|
||||
}
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{ return true; }
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
@ -31,7 +32,7 @@ class NetherQuartzOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::NETHER_QUARTZ()
|
||||
VanillaItems::NETHER_QUARTZ()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\Entity;
|
||||
@ -82,16 +83,13 @@ class NetherVines extends Flowable{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getSupportFace() : int{
|
||||
return Facing::opposite($this->growthFace);
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType($this->getSupportFace())->hasCenterSupport() || $block->hasSameTypeId($this);
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
$supportBlock = $block->getSide(Facing::opposite($this->growthFace));
|
||||
return $supportBlock->getSupportType($this->growthFace)->hasCenterSupport() || $supportBlock->hasSameTypeId($this);
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide($this->getSupportFace()))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
@ -108,7 +106,7 @@ class NetherVines extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($blockReplace->getSide($this->getSupportFace()))){
|
||||
if(!$this->canBeSupportedAt($blockReplace)){
|
||||
return false;
|
||||
}
|
||||
$this->age = mt_rand(0, self::MAX_AGE - 1);
|
||||
@ -179,7 +177,7 @@ class NetherVines extends Flowable{
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0 || mt_rand(1, 3) === 1){
|
||||
if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0 || FortuneDropHelper::bonusChanceFixed($item, 1 / 3, 2 / 9)){
|
||||
return [$this->asItem()];
|
||||
}
|
||||
return [];
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
@ -85,7 +86,7 @@ class NetherWartPlant extends Flowable{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
$this->asItem()->setCount($this->age === self::MAX_AGE ? mt_rand(2, 4) : 1)
|
||||
$this->asItem()->setCount($this->age === self::MAX_AGE ? FortuneDropHelper::discrete($item, 2, 4) : 1)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ use pocketmine\item\Item;
|
||||
|
||||
class Podzol extends Opaque{
|
||||
|
||||
public function isAffectedBySilkTouch() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaBlocks::DIRT()->asItem()
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function mt_rand;
|
||||
@ -31,7 +32,8 @@ class Potato extends Crops{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
$result = [
|
||||
VanillaItems::POTATO()->setCount($this->age >= self::MAX_AGE ? mt_rand(1, 5) : 1)
|
||||
//min/max would be 2-5 in Java
|
||||
VanillaItems::POTATO()->setCount($this->age >= self::MAX_AGE ? FortuneDropHelper::binomial($item, 1) : 1)
|
||||
];
|
||||
if($this->age >= self::MAX_AGE && mt_rand(0, 49) === 0){
|
||||
$result[] = VanillaItems::POISONOUS_POTATO();
|
||||
|
@ -63,6 +63,14 @@ final class PotionCauldron extends FillableCauldron{
|
||||
|
||||
/** @return $this */
|
||||
public function setPotionItem(?Item $potionItem) : self{
|
||||
if($potionItem !== null && !match($potionItem->getTypeId()){
|
||||
ItemTypeIds::POTION,
|
||||
ItemTypeIds::SPLASH_POTION,
|
||||
ItemTypeIds::LINGERING_POTION => true,
|
||||
default => false,
|
||||
}){
|
||||
throw new \InvalidArgumentException("Item must be a POTION, SPLASH_POTION or LINGERING_POTION");
|
||||
}
|
||||
$this->potionItem = $potionItem !== null ? (clone $potionItem)->setCount(1) : null;
|
||||
return $this;
|
||||
}
|
||||
|
@ -45,18 +45,18 @@ abstract class PressurePlate extends Transparent{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){
|
||||
if($this->canBeSupportedAt($blockReplace)){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE());
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE());
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ class RedstoneComparator extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){
|
||||
if($this->canBeSupportedAt($blockReplace)){
|
||||
if($player !== null){
|
||||
$this->facing = Facing::opposite($player->getHorizontalFacing());
|
||||
}
|
||||
@ -102,13 +102,13 @@ class RedstoneComparator extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE());
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE());
|
||||
}
|
||||
|
||||
//TODO: redstone functionality
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
@ -81,7 +82,7 @@ class RedstoneOre extends Opaque{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::REDSTONE_DUST()->setCount(mt_rand(4, 5))
|
||||
VanillaItems::REDSTONE_DUST()->setCount(FortuneDropHelper::discrete($item, 4, 5))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ class RedstoneRepeater extends Flowable{
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){
|
||||
if($this->canBeSupportedAt($blockReplace)){
|
||||
if($player !== null){
|
||||
$this->facing = Facing::opposite($player->getHorizontalFacing());
|
||||
}
|
||||
@ -88,13 +88,13 @@ class RedstoneRepeater extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return !$block->getSupportType(Facing::UP)->equals(SupportType::NONE());
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return !$block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::NONE());
|
||||
}
|
||||
|
||||
//TODO: redstone functionality
|
||||
|
@ -35,7 +35,7 @@ class RedstoneWire extends Flowable{
|
||||
use AnalogRedstoneSignalEmitterTrait;
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if($this->canBeSupportedAt($blockReplace)){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
return false;
|
||||
@ -49,13 +49,13 @@ class RedstoneWire extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::UP)->hasCenterSupport();
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::DOWN)->hasCenterSupport();
|
||||
}
|
||||
|
||||
public function asItem() : Item{
|
||||
|
@ -23,8 +23,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use function min;
|
||||
|
||||
class SeaLantern extends Transparent{
|
||||
|
||||
@ -34,7 +36,7 @@ class SeaLantern extends Transparent{
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
return [
|
||||
VanillaItems::PRISMARINE_CRYSTALS()->setCount(3)
|
||||
VanillaItems::PRISMARINE_CRYSTALS()->setCount(min(5, FortuneDropHelper::discrete($item, 2, 3)))
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\tile\ShulkerBox as TileShulkerBox;
|
||||
use pocketmine\block\utils\AnyFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Vector3;
|
||||
@ -110,4 +111,8 @@ class ShulkerBox extends Opaque{
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
}
|
||||
|
170
src/block/SmallDripleaf.php
Normal file
170
src/block/SmallDripleaf.php
Normal file
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
*
|
||||
* ____ _ _ __ __ _ __ __ ____
|
||||
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* @author PocketMine Team
|
||||
* @link http://www.pocketmine.net/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\StructureGrowEvent;
|
||||
use pocketmine\item\Fertilizer;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use pocketmine\world\Position;
|
||||
use function mt_rand;
|
||||
|
||||
class SmallDripleaf extends Transparent{
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
protected bool $top = false;
|
||||
|
||||
public function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
$w->horizontalFacing($this->facing);
|
||||
$w->bool($this->top);
|
||||
}
|
||||
|
||||
public function isTop() : bool{
|
||||
return $this->top;
|
||||
}
|
||||
|
||||
/** @return $this */
|
||||
public function setTop(bool $top) : self{
|
||||
$this->top = $top;
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
//TODO: Moss
|
||||
//TODO: Small Dripleaf also can be placed on dirt, coarse dirt, farmland, grass blocks,
|
||||
// podzol, rooted dirt, mycelium, and mud if these blocks are underwater (needs waterlogging)
|
||||
return $block->getTypeId() === BlockTypeIds::CLAY;
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->top && !$this->canBeSupportedBy($this->getSide(Facing::DOWN))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
return;
|
||||
}
|
||||
$face = $this->top ? Facing::DOWN : Facing::UP;
|
||||
if(!$this->getSide($face)->hasSameTypeId($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
$block = $blockReplace->getSide(Facing::UP);
|
||||
if($block->getTypeId() !== BlockTypeIds::AIR || !$this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){
|
||||
return false;
|
||||
}
|
||||
if($player !== null){
|
||||
$this->facing = Facing::opposite($player->getHorizontalFacing());
|
||||
}
|
||||
|
||||
$tx->addBlock($block->getPosition(), VanillaBlocks::SMALL_DRIPLEAF()
|
||||
->setFacing($this->facing)
|
||||
->setTop(true)
|
||||
);
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($item instanceof Fertilizer && $this->grow($player)){
|
||||
$item->pop();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function canGrowTo(Position $pos) : bool{
|
||||
$world = $pos->getWorld();
|
||||
if(!$world->isInWorld($pos->getFloorX(), $pos->getFloorY(), $pos->getFloorZ())){
|
||||
return false;
|
||||
}
|
||||
$block = $world->getBlock($pos);
|
||||
return $block->hasSameTypeId($this) || $block->getTypeId() === BlockTypeIds::AIR;
|
||||
}
|
||||
|
||||
private function grow(?Player $player) : bool{
|
||||
$bottomBlock = $this->top ? $this->getSide(Facing::DOWN) : $this;
|
||||
if(!$this->hasSameTypeId($bottomBlock)){
|
||||
return false;
|
||||
}
|
||||
$world = $this->position->getWorld();
|
||||
$tx = new BlockTransaction($world);
|
||||
$height = mt_rand(2, 5);
|
||||
$grown = 0;
|
||||
for($i = 0; $i < $height; $i++){
|
||||
$pos = $bottomBlock->getSide(Facing::UP, $i)->getPosition();
|
||||
if(!$this->canGrowTo($pos)){
|
||||
break;
|
||||
}
|
||||
$block = ++$grown < $height && $this->canGrowTo($pos->getSide(Facing::UP)) ?
|
||||
VanillaBlocks::BIG_DRIPLEAF_STEM() :
|
||||
VanillaBlocks::BIG_DRIPLEAF_HEAD();
|
||||
$tx->addBlock($pos, $block->setFacing($this->facing));
|
||||
}
|
||||
if($grown > 1){
|
||||
$ev = new StructureGrowEvent($bottomBlock, $tx, $player);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
return $tx->apply();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getAffectedBlocks() : array{
|
||||
$other = $this->getSide($this->top ? Facing::DOWN : Facing::UP);
|
||||
if($other->hasSameTypeId($this)){
|
||||
return [$this, $other];
|
||||
}
|
||||
return parent::getAffectedBlocks();
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(!$this->top){
|
||||
return [$this->asItem()];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
|
||||
public function getSupportType(int $facing) : SupportType{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
protected function recalculateCollisionBoxes() : array{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -80,8 +80,8 @@ class SnowLayer extends Flowable implements Fallable{
|
||||
return SupportType::NONE();
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $b) : bool{
|
||||
return $b->getSupportType(Facing::UP)->equals(SupportType::FULL());
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::DOWN)->equals(SupportType::FULL());
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
@ -91,7 +91,7 @@ class SnowLayer extends Flowable implements Fallable{
|
||||
}
|
||||
$this->layers = $blockReplace->layers + 1;
|
||||
}
|
||||
if($this->canBeSupportedBy($blockReplace->getSide(Facing::DOWN))){
|
||||
if($this->canBeSupportedAt($blockReplace)){
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
|
||||
|
@ -32,12 +32,12 @@ use pocketmine\world\BlockTransaction;
|
||||
|
||||
final class SporeBlossom extends Flowable{
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->getSupportType(Facing::DOWN)->equals(SupportType::FULL());
|
||||
private function canBeSupportedAt(Block $block) : bool{
|
||||
return $block->getAdjacentSupportType(Facing::UP)->equals(SupportType::FULL());
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if(!$this->canBeSupportedBy($blockReplace->getSide(Facing::UP))){
|
||||
if(!$this->canBeSupportedAt($blockReplace)){
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ final class SporeBlossom extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if(!$this->canBeSupportedBy($this->getSide(Facing::UP))){
|
||||
if(!$this->canBeSupportedAt($this)){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\event\block\BlockGrowEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Facing;
|
||||
@ -30,11 +31,35 @@ use function array_rand;
|
||||
use function mt_rand;
|
||||
|
||||
abstract class Stem extends Crops{
|
||||
protected int $facing = Facing::UP;
|
||||
|
||||
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
parent::describeBlockOnlyState($w);
|
||||
$w->facingExcept($this->facing, Facing::DOWN);
|
||||
}
|
||||
|
||||
public function getFacing() : int{ return $this->facing; }
|
||||
|
||||
/** @return $this */
|
||||
public function setFacing(int $facing) : self{
|
||||
if($facing === Facing::DOWN){
|
||||
throw new \InvalidArgumentException("DOWN is not a valid facing for this block");
|
||||
}
|
||||
$this->facing = $facing;
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract protected function getPlant() : Block;
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
if($this->facing !== Facing::UP && !$this->getSide($this->facing)->hasSameTypeId($this->getPlant())){
|
||||
$this->position->getWorld()->setBlock($this->position, $this->setFacing(Facing::UP));
|
||||
}
|
||||
parent::onNearbyBlockChange();
|
||||
}
|
||||
|
||||
public function onRandomTick() : void{
|
||||
if(mt_rand(0, 2) === 1){
|
||||
if($this->facing === Facing::UP && mt_rand(0, 2) === 1){
|
||||
$world = $this->position->getWorld();
|
||||
if($this->age < self::MAX_AGE){
|
||||
$block = clone $this;
|
||||
@ -52,11 +77,13 @@ abstract class Stem extends Crops{
|
||||
}
|
||||
}
|
||||
|
||||
$side = $this->getSide(Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)]);
|
||||
$facing = Facing::HORIZONTAL[array_rand(Facing::HORIZONTAL)];
|
||||
$side = $this->getSide($facing);
|
||||
if($side->getTypeId() === BlockTypeIds::AIR && $side->getSide(Facing::DOWN)->hasTypeTag(BlockTypeTags::DIRT)){
|
||||
$ev = new BlockGrowEvent($side, $grow);
|
||||
$ev->call();
|
||||
if(!$ev->isCancelled()){
|
||||
$world->setBlock($this->position, $this->setFacing($facing));
|
||||
$world->setBlock($side->position, $ev->getNewState());
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\inventory\StonecutterInventory;
|
||||
use pocketmine\block\utils\FacesOppositePlacingPlayerTrait;
|
||||
use pocketmine\block\utils\HorizontalFacingTrait;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
@ -35,7 +34,6 @@ use pocketmine\player\Player;
|
||||
|
||||
class Stonecutter extends Transparent{
|
||||
use FacesOppositePlacingPlayerTrait;
|
||||
use HorizontalFacingTrait;
|
||||
|
||||
public function onInteract(Item $item, int $face, Vector3 $clickVector, ?Player $player = null, array &$returnedItems = []) : bool{
|
||||
if($player !== null){
|
||||
|
@ -23,6 +23,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\FortuneDropHelper;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Living;
|
||||
@ -108,13 +109,14 @@ class SweetBerryBush extends Flowable{
|
||||
}
|
||||
|
||||
public function getDropsForCompatibleTool(Item $item) : array{
|
||||
if(($dropAmount = $this->getBerryDropAmount()) > 0){
|
||||
return [
|
||||
$this->asItem()->setCount($dropAmount)
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
$count = match($this->age){
|
||||
self::STAGE_MATURE => FortuneDropHelper::discrete($item, 2, 3),
|
||||
self::STAGE_BUSH_SOME_BERRIES => FortuneDropHelper::discrete($item, 1, 2),
|
||||
default => 0
|
||||
};
|
||||
return [
|
||||
$this->asItem()->setCount($count)
|
||||
];
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
|
@ -23,19 +23,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\block\utils\TallGrassTrait;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
use pocketmine\world\BlockTransaction;
|
||||
use function mt_rand;
|
||||
|
||||
class TallGrass extends Flowable{
|
||||
|
||||
public function canBeReplaced() : bool{
|
||||
return true;
|
||||
}
|
||||
use TallGrassTrait;
|
||||
|
||||
private function canBeSupportedBy(Block $block) : bool{
|
||||
return $block->hasTypeTag(BlockTypeTags::DIRT) || $block->hasTypeTag(BlockTypeTags::MUD);
|
||||
@ -54,22 +50,4 @@ class TallGrass extends Flowable{
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function getDropsForIncompatibleTool(Item $item) : array{
|
||||
if(mt_rand(0, 15) === 0){
|
||||
return [
|
||||
VanillaItems::WHEAT_SEEDS()
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getFlameEncouragement() : int{
|
||||
return 60;
|
||||
}
|
||||
|
||||
public function getFlammability() : int{
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ namespace pocketmine\block;
|
||||
use pocketmine\block\utils\SupportType;
|
||||
use pocketmine\data\runtime\RuntimeDataDescriber;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\player\Player;
|
||||
@ -56,15 +55,13 @@ class Torch extends Flowable{
|
||||
}
|
||||
|
||||
public function onNearbyBlockChange() : void{
|
||||
$face = Facing::opposite($this->facing);
|
||||
|
||||
if(!$this->canBeSupportedBy($this->getSide($face), $this->facing)){
|
||||
if(!$this->canBeSupportedAt($this, Facing::opposite($this->facing))){
|
||||
$this->position->getWorld()->useBreakOn($this->position);
|
||||
}
|
||||
}
|
||||
|
||||
public function place(BlockTransaction $tx, Item $item, Block $blockReplace, Block $blockClicked, int $face, Vector3 $clickVector, ?Player $player = null) : bool{
|
||||
if($face !== Facing::DOWN && $this->canBeSupportedBy($blockReplace->getSide(Facing::opposite($face)), $face)){
|
||||
if($face !== Facing::DOWN && $this->canBeSupportedAt($blockReplace, Facing::opposite($face))){
|
||||
$this->facing = $face;
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}else{
|
||||
@ -75,8 +72,7 @@ class Torch extends Flowable{
|
||||
Facing::EAST,
|
||||
Facing::DOWN
|
||||
] as $side){
|
||||
$block = $this->getSide($side);
|
||||
if($this->canBeSupportedBy($block, Facing::opposite($side))){
|
||||
if($this->canBeSupportedAt($blockReplace, $side)){
|
||||
$this->facing = Facing::opposite($side);
|
||||
return parent::place($tx, $item, $blockReplace, $blockClicked, $face, $clickVector, $player);
|
||||
}
|
||||
@ -85,8 +81,9 @@ class Torch extends Flowable{
|
||||
return false;
|
||||
}
|
||||
|
||||
private function canBeSupportedBy(Block $support, int $face) : bool{
|
||||
return ($face === Facing::UP && $support->getSupportType($face)->hasCenterSupport()) ||
|
||||
(Facing::axis($face) !== Axis::Y && $support->getSupportType($face)->equals(SupportType::FULL()));
|
||||
private function canBeSupportedAt(Block $block, int $face) : bool{
|
||||
return $face === Facing::DOWN ?
|
||||
$block->getAdjacentSupportType($face)->hasCenterSupport() :
|
||||
$block->getAdjacentSupportType($face)->equals(SupportType::FULL());
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,8 @@ use function mb_strtolower;
|
||||
* @method static Bedrock BEDROCK()
|
||||
* @method static Beetroot BEETROOTS()
|
||||
* @method static Bell BELL()
|
||||
* @method static BigDripleafHead BIG_DRIPLEAF_HEAD()
|
||||
* @method static BigDripleafStem BIG_DRIPLEAF_STEM()
|
||||
* @method static WoodenButton BIRCH_BUTTON()
|
||||
* @method static WoodenDoor BIRCH_DOOR()
|
||||
* @method static WoodenFence BIRCH_FENCE()
|
||||
@ -159,6 +161,20 @@ use function mb_strtolower;
|
||||
* @method static CaveVines CAVE_VINES()
|
||||
* @method static Chain CHAIN()
|
||||
* @method static ChemicalHeat CHEMICAL_HEAT()
|
||||
* @method static WoodenButton CHERRY_BUTTON()
|
||||
* @method static WoodenDoor CHERRY_DOOR()
|
||||
* @method static WoodenFence CHERRY_FENCE()
|
||||
* @method static FenceGate CHERRY_FENCE_GATE()
|
||||
* @method static Leaves CHERRY_LEAVES()
|
||||
* @method static Wood CHERRY_LOG()
|
||||
* @method static Planks CHERRY_PLANKS()
|
||||
* @method static WoodenPressurePlate CHERRY_PRESSURE_PLATE()
|
||||
* @method static FloorSign CHERRY_SIGN()
|
||||
* @method static WoodenSlab CHERRY_SLAB()
|
||||
* @method static WoodenStairs CHERRY_STAIRS()
|
||||
* @method static WoodenTrapdoor CHERRY_TRAPDOOR()
|
||||
* @method static WallSign CHERRY_WALL_SIGN()
|
||||
* @method static Wood CHERRY_WOOD()
|
||||
* @method static Chest CHEST()
|
||||
* @method static Opaque CHISELED_DEEPSLATE()
|
||||
* @method static Opaque CHISELED_NETHER_BRICKS()
|
||||
@ -417,6 +433,7 @@ use function mb_strtolower;
|
||||
* @method static ItemFrame GLOWING_ITEM_FRAME()
|
||||
* @method static GlowingObsidian GLOWING_OBSIDIAN()
|
||||
* @method static Glowstone GLOWSTONE()
|
||||
* @method static GlowLichen GLOW_LICHEN()
|
||||
* @method static Opaque GOLD()
|
||||
* @method static GoldOre GOLD_ORE()
|
||||
* @method static Opaque GRANITE()
|
||||
@ -643,6 +660,7 @@ use function mb_strtolower;
|
||||
* @method static Opaque SHROOMLIGHT()
|
||||
* @method static ShulkerBox SHULKER_BOX()
|
||||
* @method static Slime SLIME()
|
||||
* @method static SmallDripleaf SMALL_DRIPLEAF()
|
||||
* @method static SmithingTable SMITHING_TABLE()
|
||||
* @method static Furnace SMOKER()
|
||||
* @method static Opaque SMOOTH_BASALT()
|
||||
@ -864,6 +882,7 @@ final class VanillaBlocks{
|
||||
self::register("glass_pane", new GlassPane(new BID(Ids::GLASS_PANE), "Glass Pane", $glassBreakInfo));
|
||||
self::register("glowing_obsidian", new GlowingObsidian(new BID(Ids::GLOWING_OBSIDIAN), "Glowing Obsidian", new Info(BreakInfo::pickaxe(10.0, ToolTier::DIAMOND(), 50.0))));
|
||||
self::register("glowstone", new Glowstone(new BID(Ids::GLOWSTONE), "Glowstone", new Info(BreakInfo::pickaxe(0.3))));
|
||||
self::register("glow_lichen", new GlowLichen(new BID(Ids::GLOW_LICHEN), "Glow Lichen", new Info(BreakInfo::axe(0.2, null, 0.2))));
|
||||
self::register("gold", new Opaque(new BID(Ids::GOLD), "Gold Block", new Info(BreakInfo::pickaxe(3.0, ToolTier::IRON(), 30.0))));
|
||||
|
||||
$grassBreakInfo = BreakInfo::shovel(0.6);
|
||||
@ -1582,6 +1601,10 @@ final class VanillaBlocks{
|
||||
self::register("hanging_roots", new HangingRoots(new BID(Ids::HANGING_ROOTS), "Hanging Roots", new Info(BreakInfo::instant(ToolType::SHEARS, 1))));
|
||||
|
||||
self::register("cave_vines", new CaveVines(new BID(Ids::CAVE_VINES), "Cave Vines", new Info(BreakInfo::instant())));
|
||||
|
||||
self::register("small_dripleaf", new SmallDripleaf(new BID(Ids::SMALL_DRIPLEAF), "Small Dripleaf", new Info(BreakInfo::instant(BlockToolType::SHEARS, toolHarvestLevel: 1))));
|
||||
self::register("big_dripleaf_head", new BigDripleafHead(new BID(Ids::BIG_DRIPLEAF_HEAD), "Big Dripleaf", new Info(BreakInfo::instant())));
|
||||
self::register("big_dripleaf_stem", new BigDripleafStem(new BID(Ids::BIG_DRIPLEAF_STEM), "Big Dripleaf Stem", new Info(BreakInfo::instant())));
|
||||
}
|
||||
|
||||
private static function registerBlocksR18() : void{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user